File indexing completed on 2024-05-11 03:34:24
0001
0002
0003
0004 #include "RootFile.h"
0005 #include "DuplicateChecker.h"
0006 #include "InputFile.h"
0007 #include "ProvenanceAdaptor.h"
0008 #include "RunHelper.h"
0009
0010 #include "DataFormats/Common/interface/setIsMergeable.h"
0011 #include "DataFormats/Common/interface/ThinnedAssociation.h"
0012 #include "DataFormats/Provenance/interface/BranchDescription.h"
0013 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
0014 #include "DataFormats/Provenance/interface/BranchType.h"
0015 #include "DataFormats/Provenance/interface/EventEntryInfo.h"
0016 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
0017 #include "DataFormats/Provenance/interface/ParentageRegistry.h"
0018 #include "DataFormats/Provenance/interface/ProcessHistoryID.h"
0019 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
0020 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0021 #include "DataFormats/Provenance/interface/StoredMergeableRunProductMetadata.h"
0022 #include "DataFormats/Provenance/interface/StoredProcessBlockHelper.h"
0023 #include "DataFormats/Provenance/interface/StoredProductProvenance.h"
0024 #include "DataFormats/Provenance/interface/ThinnedAssociationsHelper.h"
0025 #include "DataFormats/Provenance/interface/RunID.h"
0026 #include "FWCore/Common/interface/ProcessBlockHelper.h"
0027 #include "FWCore/Framework/interface/FileBlock.h"
0028 #include "FWCore/Framework/interface/EventPrincipal.h"
0029 #include "FWCore/Framework/interface/ProductSelector.h"
0030 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
0031 #include "FWCore/Framework/interface/MergeableRunProductMetadata.h"
0032 #include "FWCore/Framework/interface/ProcessBlockPrincipal.h"
0033 #include "FWCore/Framework/interface/RunPrincipal.h"
0034 #include "FWCore/Framework/interface/SharedResourcesAcquirer.h"
0035 #include "FWCore/Framework/interface/SharedResourcesRegistry.h"
0036 #include "FWCore/Framework/interface/DelayedReader.h"
0037 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0039 #include "FWCore/ParameterSet/interface/Registry.h"
0040 #include "FWCore/Sources/interface/EventSkipperByID.h"
0041 #include "FWCore/Sources/interface/DaqProvenanceHelper.h"
0042 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0043 #include "FWCore/Utilities/interface/Algorithms.h"
0044 #include "FWCore/Utilities/interface/do_nothing_deleter.h"
0045 #include "FWCore/Utilities/interface/EDMException.h"
0046 #include "FWCore/Utilities/interface/FriendlyName.h"
0047 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
0048 #include "FWCore/Utilities/interface/ReleaseVersion.h"
0049 #include "FWCore/Utilities/interface/stemFromPath.h"
0050 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0051 #include "FWCore/Version/interface/GetReleaseVersion.h"
0052 #include "IOPool/Common/interface/getWrapperBasePtr.h"
0053
0054 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0055 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0056
0057
0058 #include "DataFormats/Provenance/interface/EventAux.h"
0059 #include "DataFormats/Provenance/interface/LuminosityBlockAux.h"
0060 #include "DataFormats/Provenance/interface/RunAux.h"
0061 #include "FWCore/ParameterSet/interface/ParameterSetConverter.h"
0062
0063 #include "Rtypes.h"
0064 #include "TClass.h"
0065 #include "TString.h"
0066 #include "TTree.h"
0067 #include "TTreeCache.h"
0068
0069 #include <algorithm>
0070 #include <cassert>
0071 #include <list>
0072
0073 namespace edm {
0074
0075
0076 class MakeDummyProvenanceReader : public MakeProvenanceReader {
0077 public:
0078 std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
0079 DaqProvenanceHelper const* daqProvenanceHelper) const override;
0080 };
0081 class MakeOldProvenanceReader : public MakeProvenanceReader {
0082 public:
0083 MakeOldProvenanceReader(std::unique_ptr<EntryDescriptionMap>&& entryDescriptionMap)
0084 : MakeProvenanceReader(), entryDescriptionMap_(std::move(entryDescriptionMap)) {}
0085 std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
0086 DaqProvenanceHelper const* daqProvenanceHelper) const override;
0087
0088 private:
0089 edm::propagate_const<std::unique_ptr<EntryDescriptionMap>> entryDescriptionMap_;
0090 };
0091 class MakeFullProvenanceReader : public MakeProvenanceReader {
0092 public:
0093 std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
0094 DaqProvenanceHelper const* daqProvenanceHelper) const override;
0095 };
0096 class MakeReducedProvenanceReader : public MakeProvenanceReader {
0097 public:
0098 MakeReducedProvenanceReader(std::vector<ParentageID> const& parentageIDLookup)
0099 : parentageIDLookup_(parentageIDLookup) {}
0100 std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
0101 DaqProvenanceHelper const* daqProvenanceHelper) const override;
0102
0103 private:
0104 std::vector<ParentageID> const& parentageIDLookup_;
0105 };
0106
0107 namespace {
0108 void checkReleaseVersion(std::vector<ProcessHistory> processHistoryVector, std::string const& fileName) {
0109 std::string releaseVersion = getReleaseVersion();
0110 releaseversion::DecomposedReleaseVersion currentRelease(releaseVersion);
0111 for (auto const& ph : processHistoryVector) {
0112 for (auto const& pc : ph) {
0113 if (releaseversion::isEarlierRelease(currentRelease, pc.releaseVersion())) {
0114 throw Exception(errors::FormatIncompatibility)
0115 << "The release you are using, " << getReleaseVersion() << " , predates\n"
0116 << "a release (" << pc.releaseVersion() << ") used in writing the input file, " << fileName << ".\n"
0117 << "Forward compatibility cannot be supported.\n";
0118 }
0119 }
0120 }
0121 }
0122 }
0123
0124
0125 class RootFileEventFinder : public IndexIntoFile::EventFinder {
0126 public:
0127 explicit RootFileEventFinder(RootTree& eventTree) : eventTree_(eventTree) {}
0128 ~RootFileEventFinder() override {}
0129
0130 EventNumber_t getEventNumberOfEntry(roottree::EntryNumber entry) const override {
0131 roottree::EntryNumber saveEntry = eventTree_.entryNumber();
0132 eventTree_.setEntryNumber(entry);
0133 EventAuxiliary eventAux;
0134 EventAuxiliary* pEvAux = &eventAux;
0135 eventTree_.fillAux<EventAuxiliary>(pEvAux);
0136 eventTree_.setEntryNumber(saveEntry);
0137 return eventAux.event();
0138 }
0139
0140 private:
0141 RootTree& eventTree_;
0142 };
0143
0144
0145 RootFile::RootFile(std::string const& fileName,
0146 ProcessConfiguration const& processConfiguration,
0147 std::string const& logicalFileName,
0148 std::shared_ptr<InputFile> filePtr,
0149 std::shared_ptr<EventSkipperByID> eventSkipperByID,
0150 bool skipAnyEvents,
0151 int remainingEvents,
0152 int remainingLumis,
0153 unsigned int nStreams,
0154 unsigned int treeCacheSize,
0155 int treeMaxVirtualSize,
0156 InputSource::ProcessingMode processingMode,
0157 RunHelperBase* runHelper,
0158 bool noRunLumiSort,
0159 bool noEventSort,
0160 ProductSelectorRules const& productSelectorRules,
0161 InputType inputType,
0162 std::shared_ptr<BranchIDListHelper> branchIDListHelper,
0163 ProcessBlockHelper* processBlockHelper,
0164 std::shared_ptr<ThinnedAssociationsHelper> thinnedAssociationsHelper,
0165 std::vector<BranchID> const* associationsFromSecondary,
0166 std::shared_ptr<DuplicateChecker> duplicateChecker,
0167 bool dropDescendants,
0168 ProcessHistoryRegistry& processHistoryRegistry,
0169 std::vector<std::shared_ptr<IndexIntoFile>> const& indexesIntoFiles,
0170 std::vector<std::shared_ptr<IndexIntoFile>>::size_type currentIndexIntoFile,
0171 std::vector<ProcessHistoryID>& orderedProcessHistoryIDs,
0172 bool bypassVersionCheck,
0173 bool labelRawDataLikeMC,
0174 bool usingGoToEvent,
0175 bool enablePrefetching,
0176 bool enforceGUIDInFileName)
0177 : file_(fileName),
0178 logicalFile_(logicalFileName),
0179 processConfiguration_(processConfiguration),
0180 processHistoryRegistry_(&processHistoryRegistry),
0181 filePtr_(filePtr),
0182 eventSkipperByID_(eventSkipperByID),
0183 fileFormatVersion_(),
0184 fid_(),
0185 indexIntoFileSharedPtr_(new IndexIntoFile),
0186 indexIntoFile_(*indexIntoFileSharedPtr_),
0187 orderedProcessHistoryIDs_(orderedProcessHistoryIDs),
0188 indexIntoFileBegin_(indexIntoFile_.begin(
0189 noRunLumiSort ? IndexIntoFile::entryOrder
0190 : (noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder))),
0191 indexIntoFileEnd_(indexIntoFileBegin_),
0192 indexIntoFileIter_(indexIntoFileBegin_),
0193 storedMergeableRunProductMetadata_((inputType == InputType::Primary) ? new StoredMergeableRunProductMetadata
0194 : nullptr),
0195 eventProcessHistoryIDs_(),
0196 eventProcessHistoryIter_(eventProcessHistoryIDs_.begin()),
0197 savedRunAuxiliary_(),
0198 skipAnyEvents_(skipAnyEvents),
0199 noRunLumiSort_(noRunLumiSort),
0200 noEventSort_(noEventSort),
0201 enforceGUIDInFileName_(enforceGUIDInFileName),
0202 whyNotFastClonable_(0),
0203 hasNewlyDroppedBranch_(),
0204 branchListIndexesUnchanged_(false),
0205 eventAuxCache_(),
0206 eventTree_(filePtr,
0207 InEvent,
0208 nStreams,
0209 treeMaxVirtualSize,
0210 treeCacheSize,
0211 roottree::defaultLearningEntries,
0212 enablePrefetching,
0213 inputType),
0214 lumiTree_(filePtr,
0215 InLumi,
0216 1,
0217 treeMaxVirtualSize,
0218 roottree::defaultNonEventCacheSize,
0219 roottree::defaultNonEventLearningEntries,
0220 enablePrefetching,
0221 inputType),
0222 runTree_(filePtr,
0223 InRun,
0224 1,
0225 treeMaxVirtualSize,
0226 roottree::defaultNonEventCacheSize,
0227 roottree::defaultNonEventLearningEntries,
0228 enablePrefetching,
0229 inputType),
0230 treePointers_(),
0231 lastEventEntryNumberRead_(IndexIntoFile::invalidEntry),
0232 productRegistry_(),
0233 branchIDLists_(),
0234 branchIDListHelper_(branchIDListHelper),
0235 processBlockHelper_(processBlockHelper),
0236 fileThinnedAssociationsHelper_(),
0237 thinnedAssociationsHelper_(thinnedAssociationsHelper),
0238 processingMode_(processingMode),
0239 runHelper_(runHelper),
0240 newBranchToOldBranch_(),
0241 eventHistoryTree_(nullptr),
0242 eventToProcessBlockIndexesBranch_(
0243 inputType == InputType::Primary
0244 ? eventTree_.tree()->GetBranch(poolNames::eventToProcessBlockIndexesBranchName().c_str())
0245 : nullptr),
0246 history_(),
0247 branchChildren_(new BranchChildren),
0248 duplicateChecker_(duplicateChecker),
0249 provenanceAdaptor_(),
0250 provenanceReaderMaker_(),
0251 eventProductProvenanceRetrievers_(),
0252 parentageIDLookup_(),
0253 daqProvenanceHelper_(),
0254 edProductClass_(TypeWithDict::byName("edm::WrapperBase").getClass()),
0255 inputType_(inputType) {
0256 hasNewlyDroppedBranch_.fill(false);
0257
0258 treePointers_.resize(3);
0259 treePointers_[InEvent] = &eventTree_;
0260 treePointers_[InLumi] = &lumiTree_;
0261 treePointers_[InRun] = &runTree_;
0262
0263
0264
0265 std::unique_ptr<TTree> metaDataTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::metaDataTreeName().c_str())));
0266 if (nullptr == metaDataTree.get()) {
0267 throw Exception(errors::FileReadError)
0268 << "Could not find tree " << poolNames::metaDataTreeName() << " in the input file.\n";
0269 }
0270
0271
0272
0273
0274 FileFormatVersion* fftPtr = &fileFormatVersion_;
0275 if (metaDataTree->FindBranch(poolNames::fileFormatVersionBranchName().c_str()) != nullptr) {
0276 TBranch* fft = metaDataTree->GetBranch(poolNames::fileFormatVersionBranchName().c_str());
0277 fft->SetAddress(&fftPtr);
0278 roottree::getEntry(fft, 0);
0279 metaDataTree->SetBranchAddress(poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
0280 }
0281
0282 FileID* fidPtr = &fid_;
0283 if (metaDataTree->FindBranch(poolNames::fileIdentifierBranchName().c_str()) != nullptr) {
0284 metaDataTree->SetBranchAddress(poolNames::fileIdentifierBranchName().c_str(), &fidPtr);
0285 }
0286
0287 IndexIntoFile* iifPtr = &indexIntoFile_;
0288 if (metaDataTree->FindBranch(poolNames::indexIntoFileBranchName().c_str()) != nullptr) {
0289 metaDataTree->SetBranchAddress(poolNames::indexIntoFileBranchName().c_str(), &iifPtr);
0290 }
0291
0292 storedProcessBlockHelper_ = std::make_unique<StoredProcessBlockHelper>();
0293 StoredProcessBlockHelper& storedProcessBlockHelper = *storedProcessBlockHelper_;
0294 StoredProcessBlockHelper* pStoredProcessBlockHelper = storedProcessBlockHelper_.get();
0295 if (inputType == InputType::Primary) {
0296 if (metaDataTree->FindBranch(poolNames::processBlockHelperBranchName().c_str()) != nullptr) {
0297 metaDataTree->SetBranchAddress(poolNames::processBlockHelperBranchName().c_str(), &pStoredProcessBlockHelper);
0298 }
0299 }
0300
0301 StoredMergeableRunProductMetadata* smrc = nullptr;
0302 if (inputType == InputType::Primary) {
0303 smrc = &*storedMergeableRunProductMetadata_;
0304 if (metaDataTree->FindBranch(poolNames::mergeableRunProductMetadataBranchName().c_str()) != nullptr) {
0305 metaDataTree->SetBranchAddress(poolNames::mergeableRunProductMetadataBranchName().c_str(), &smrc);
0306 }
0307 }
0308
0309
0310
0311 ProductRegistry inputProdDescReg;
0312 ProductRegistry* ppReg = &inputProdDescReg;
0313 metaDataTree->SetBranchAddress(poolNames::productDescriptionBranchName().c_str(), (&ppReg));
0314
0315 using PsetMap = std::map<ParameterSetID, ParameterSetBlob>;
0316 PsetMap psetMap;
0317 PsetMap* psetMapPtr = &psetMap;
0318 if (metaDataTree->FindBranch(poolNames::parameterSetMapBranchName().c_str()) != nullptr) {
0319
0320 assert(!fileFormatVersion().parameterSetsTree());
0321 metaDataTree->SetBranchAddress(poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
0322 } else {
0323 assert(fileFormatVersion().parameterSetsTree());
0324
0325 std::unique_ptr<TTree> psetTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parameterSetsTreeName().c_str())));
0326 if (nullptr == psetTree.get()) {
0327 throw Exception(errors::FileReadError)
0328 << "Could not find tree " << poolNames::parameterSetsTreeName() << " in the input file.\n";
0329 }
0330
0331 using IdToBlobs = std::pair<ParameterSetID, ParameterSetBlob>;
0332 IdToBlobs idToBlob;
0333 IdToBlobs* pIdToBlob = &idToBlob;
0334 psetTree->SetBranchAddress(poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
0335
0336 std::unique_ptr<TTreeCache> psetTreeCache =
0337 roottree::trainCache(psetTree.get(), *filePtr_, roottree::defaultNonEventCacheSize, "*");
0338 psetTreeCache->SetEnablePrefetching(false);
0339 filePtr_->SetCacheRead(psetTreeCache.get());
0340 for (Long64_t i = 0; i != psetTree->GetEntries(); ++i) {
0341 psetTree->GetEntry(i);
0342 psetMap.insert(idToBlob);
0343 }
0344 filePtr_->SetCacheRead(nullptr);
0345 }
0346
0347
0348 ProcessHistoryRegistry::collection_type pHistMap;
0349 ProcessHistoryRegistry::collection_type* pHistMapPtr = &pHistMap;
0350 if (metaDataTree->FindBranch(poolNames::processHistoryMapBranchName().c_str()) != nullptr) {
0351 metaDataTree->SetBranchAddress(poolNames::processHistoryMapBranchName().c_str(), &pHistMapPtr);
0352 }
0353
0354 ProcessHistoryRegistry::vector_type pHistVector;
0355 ProcessHistoryRegistry::vector_type* pHistVectorPtr = &pHistVector;
0356 if (metaDataTree->FindBranch(poolNames::processHistoryBranchName().c_str()) != nullptr) {
0357 metaDataTree->SetBranchAddress(poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
0358 }
0359
0360
0361 ProcessConfigurationVector processConfigurations;
0362 ProcessConfigurationVector* procConfigVectorPtr = &processConfigurations;
0363 if (metaDataTree->FindBranch(poolNames::processConfigurationBranchName().c_str()) != nullptr) {
0364 metaDataTree->SetBranchAddress(poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
0365 }
0366
0367 auto branchIDListsAPtr = std::make_unique<BranchIDLists>();
0368 BranchIDLists* branchIDListsPtr = branchIDListsAPtr.get();
0369 if (metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) != nullptr) {
0370 metaDataTree->SetBranchAddress(poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
0371 }
0372
0373 ThinnedAssociationsHelper* thinnedAssociationsHelperPtr;
0374 if (inputType != InputType::SecondarySource) {
0375 fileThinnedAssociationsHelper_ =
0376 std::make_unique<ThinnedAssociationsHelper>();
0377 thinnedAssociationsHelperPtr = fileThinnedAssociationsHelper_.get();
0378 if (metaDataTree->FindBranch(poolNames::thinnedAssociationsHelperBranchName().c_str()) != nullptr) {
0379 metaDataTree->SetBranchAddress(poolNames::thinnedAssociationsHelperBranchName().c_str(),
0380 &thinnedAssociationsHelperPtr);
0381 }
0382 }
0383
0384 BranchChildren* branchChildrenBuffer = branchChildren_.get();
0385 if (metaDataTree->FindBranch(poolNames::productDependenciesBranchName().c_str()) != nullptr) {
0386 metaDataTree->SetBranchAddress(poolNames::productDependenciesBranchName().c_str(), &branchChildrenBuffer);
0387 }
0388
0389
0390 std::vector<EventProcessHistoryID>* eventHistoryIDsPtr = &eventProcessHistoryIDs_;
0391 if (metaDataTree->FindBranch(poolNames::eventHistoryBranchName().c_str()) != nullptr) {
0392 metaDataTree->SetBranchAddress(poolNames::eventHistoryBranchName().c_str(), &eventHistoryIDsPtr);
0393 }
0394
0395 if (metaDataTree->FindBranch(poolNames::moduleDescriptionMapBranchName().c_str()) != nullptr) {
0396 if (metaDataTree->GetBranch(poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
0397 metaDataTree->SetBranchStatus((poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), false);
0398 } else {
0399 metaDataTree->SetBranchStatus(poolNames::moduleDescriptionMapBranchName().c_str(), false);
0400 }
0401 }
0402
0403
0404 roottree::getEntry(metaDataTree.get(), 0);
0405
0406 eventProcessHistoryIter_ = eventProcessHistoryIDs_.begin();
0407
0408
0409 readEventHistoryTree();
0410
0411 ParameterSetConverter::ParameterSetIdConverter psetIdConverter;
0412 if (!fileFormatVersion().triggerPathsTracked()) {
0413 ParameterSetConverter converter(psetMap, psetIdConverter, fileFormatVersion().parameterSetsByReference());
0414 } else {
0415
0416 pset::Registry& psetRegistry = *pset::Registry::instance();
0417 try {
0418 for (auto const& psetEntry : psetMap) {
0419 ParameterSet pset(psetEntry.second.pset());
0420 pset.setID(psetEntry.first);
0421
0422 if (inputType != InputType::SecondarySource) {
0423 psetRegistry.insertMapped(pset);
0424 }
0425 }
0426 } catch (edm::Exception const& iExcept) {
0427 if (iExcept.categoryCode() == edm::errors::Configuration) {
0428 edm::Exception exception(edm::errors::FormatIncompatibility);
0429 exception << iExcept.message();
0430 exception.addContext("Creating ParameterSets from file");
0431 throw exception;
0432 } else {
0433 throw;
0434 }
0435 }
0436 }
0437 if (!fileFormatVersion().splitProductIDs()) {
0438
0439
0440 provenanceAdaptor_ = std::make_unique<ProvenanceAdaptor>(
0441 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter, true);
0442
0443 branchIDLists_ = provenanceAdaptor_->branchIDLists();
0444 } else {
0445 if (!fileFormatVersion().triggerPathsTracked()) {
0446
0447
0448 provenanceAdaptor_ = std::make_unique<ProvenanceAdaptor>(
0449 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter, false);
0450 }
0451
0452 if (metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) == nullptr) {
0453 throw Exception(errors::EventCorruption) << "Failed to find branchIDLists branch in metaData tree.\n";
0454 }
0455 branchIDLists_.reset(branchIDListsAPtr.release());
0456 }
0457
0458 if (fileFormatVersion().hasThinnedAssociations()) {
0459 if (metaDataTree->FindBranch(poolNames::thinnedAssociationsHelperBranchName().c_str()) == nullptr) {
0460 throw Exception(errors::EventCorruption)
0461 << "Failed to find thinnedAssociationsHelper branch in metaData tree.\n";
0462 }
0463 }
0464
0465 if (!bypassVersionCheck) {
0466 checkReleaseVersion(pHistVector, file());
0467 }
0468
0469 if (labelRawDataLikeMC) {
0470 std::string const rawData("FEDRawDataCollection");
0471 std::string const source("source");
0472 ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
0473 BranchKey finder(rawData, source, "", "");
0474 ProductRegistry::ProductList::iterator it = pList.lower_bound(finder);
0475 if (it != pList.end() && it->first.friendlyClassName() == rawData && it->first.moduleLabel() == source) {
0476
0477
0478
0479 it->second.init();
0480
0481 daqProvenanceHelper_ = std::make_unique<DaqProvenanceHelper>(it->second.unwrappedTypeID());
0482
0483 BranchDescription const& newBD = daqProvenanceHelper_->branchDescription();
0484
0485 daqProvenanceHelper_->saveInfo(it->second, newBD);
0486
0487 newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), it->second.branchName()));
0488
0489 pList.erase(it);
0490
0491 it = pList.lower_bound(finder);
0492 assert(!(it != pList.end() && it->first.friendlyClassName() == rawData && it->first.moduleLabel() == source));
0493
0494 inputProdDescReg.copyProduct(newBD);
0495
0496 daqProvenanceHelper_->fixMetaData(processConfigurations, pHistVector);
0497 daqProvenanceHelper_->fixMetaData(*branchIDLists_);
0498 daqProvenanceHelper_->fixMetaData(*branchChildren_);
0499 }
0500 }
0501
0502 for (auto const& history : pHistVector) {
0503 processHistoryRegistry.registerProcessHistory(history);
0504 }
0505
0506 eventTree_.trainCache(BranchTypeToAuxiliaryBranchName(InEvent).c_str());
0507
0508
0509
0510 if (inputType == InputType::Primary) {
0511 branchListIndexesUnchanged_ = branchIDListHelper_->updateFromInput(*branchIDLists_);
0512 }
0513
0514 validateFile(inputType, usingGoToEvent);
0515
0516
0517
0518
0519 provenanceReaderMaker_ = std::unique_ptr<MakeProvenanceReader>(makeProvenanceReaderMaker(inputType).release());
0520
0521
0522 if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
0523 whyNotFastClonable_ += FileBlock::EventsOrLumisSelectedByID;
0524 }
0525
0526 initializeDuplicateChecker(indexesIntoFiles, currentIndexIntoFile);
0527 indexIntoFileIter_ = indexIntoFileBegin_ = indexIntoFile_.begin(
0528 noRunLumiSort ? IndexIntoFile::entryOrder
0529 : (noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder));
0530 indexIntoFileEnd_ = indexIntoFile_.end(
0531 noRunLumiSort ? IndexIntoFile::entryOrder
0532 : (noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder));
0533 runHelper_->setForcedRunOffset(indexIntoFileBegin_ == indexIntoFileEnd_ ? 1 : indexIntoFileBegin_.run());
0534 eventProcessHistoryIter_ = eventProcessHistoryIDs_.begin();
0535
0536 makeProcessBlockRootTrees(filePtr, treeMaxVirtualSize, enablePrefetching, inputType, storedProcessBlockHelper);
0537
0538 setPresenceInProductRegistry(inputProdDescReg, storedProcessBlockHelper);
0539
0540 auto newReg = std::make_unique<ProductRegistry>();
0541
0542
0543 {
0544 ProductRegistry::ProductList const& prodList = inputProdDescReg.productList();
0545 for (auto const& product : prodList) {
0546 BranchDescription const& prod = product.second;
0547 std::string newFriendlyName = friendlyname::friendlyName(prod.className());
0548 if (newFriendlyName == prod.friendlyClassName()) {
0549 newReg->copyProduct(prod);
0550 } else {
0551 if (fileFormatVersion().splitProductIDs()) {
0552 throw Exception(errors::UnimplementedFeature)
0553 << "Cannot change friendly class name algorithm without more development work\n"
0554 << "to update BranchIDLists and ThinnedAssociationsHelper. Contact the framework group.\n";
0555 }
0556 BranchDescription newBD(prod);
0557 newBD.updateFriendlyClassName();
0558 newReg->copyProduct(newBD);
0559 newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), prod.branchName()));
0560 }
0561 }
0562
0563 dropOnInputAndReorder(
0564 *newReg, productSelectorRules, dropDescendants, inputType, storedProcessBlockHelper, processBlockHelper);
0565
0566 if (inputType == InputType::SecondaryFile) {
0567 thinnedAssociationsHelper->updateFromSecondaryInput(*fileThinnedAssociationsHelper_,
0568 *associationsFromSecondary);
0569 } else if (inputType == InputType::Primary) {
0570 processBlockHelper->initializeFromPrimaryInput(storedProcessBlockHelper);
0571 thinnedAssociationsHelper->updateFromPrimaryInput(*fileThinnedAssociationsHelper_);
0572 }
0573
0574 if (inputType == InputType::Primary) {
0575 for (auto& product : newReg->productListUpdator()) {
0576 setIsMergeable(product.second);
0577 }
0578 }
0579
0580 for (auto& product : newReg->productListUpdator()) {
0581 product.second.setOnDemand(true);
0582 }
0583
0584 for (auto& processBlockTree : processBlockTrees_) {
0585 treePointers_.push_back(processBlockTree.get());
0586 }
0587
0588
0589 newReg->setFrozen(inputType != InputType::Primary);
0590 productRegistry_.reset(newReg.release());
0591 }
0592
0593
0594 ProductRegistry::ProductList const& prodList = productRegistry()->productList();
0595
0596 {
0597 std::vector<size_t> nBranches(treePointers_.size(), 0);
0598 for (auto const& product : prodList) {
0599 if (product.second.branchType() == InProcess) {
0600 std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
0601 auto it = std::find(processes.begin(), processes.end(), product.second.processName());
0602 if (it != processes.end()) {
0603 auto index = std::distance(processes.begin(), it);
0604 ++nBranches[numberOfRunLumiEventProductTrees + index];
0605 }
0606 } else {
0607 ++nBranches[product.second.branchType()];
0608 }
0609 }
0610
0611 int i = 0;
0612 for (auto& t : treePointers_) {
0613 t->numberOfBranchesToAdd(nBranches[i]);
0614 ++i;
0615 }
0616 }
0617 for (auto const& product : prodList) {
0618 BranchDescription const& prod = product.second;
0619 if (prod.branchType() == InProcess) {
0620 std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
0621 auto it = std::find(processes.begin(), processes.end(), prod.processName());
0622 if (it != processes.end()) {
0623 auto index = std::distance(processes.begin(), it);
0624 treePointers_[numberOfRunLumiEventProductTrees + index]->addBranch(prod,
0625 newBranchToOldBranch(prod.branchName()));
0626 }
0627 } else {
0628 treePointers_[prod.branchType()]->addBranch(prod, newBranchToOldBranch(prod.branchName()));
0629 }
0630 }
0631
0632
0633 setIfFastClonable(remainingEvents, remainingLumis);
0634
0635
0636 indexIntoFile_.doneFileInitialization();
0637
0638
0639 eventTree_.resetTraining();
0640
0641
0642 runTree_.trainCache("*");
0643 lumiTree_.trainCache("*");
0644 for (auto& processBlockTree : processBlockTrees_) {
0645 processBlockTree->trainCache("*");
0646 }
0647 }
0648
0649 RootFile::~RootFile() {}
0650
0651 void RootFile::readEntryDescriptionTree(EntryDescriptionMap& entryDescriptionMap, InputType inputType) {
0652
0653
0654 std::unique_ptr<TTree> entryDescriptionTree(
0655 dynamic_cast<TTree*>(filePtr_->Get(poolNames::entryDescriptionTreeName().c_str())));
0656 if (nullptr == entryDescriptionTree.get()) {
0657 throw Exception(errors::FileReadError)
0658 << "Could not find tree " << poolNames::entryDescriptionTreeName() << " in the input file.\n";
0659 }
0660
0661 EntryDescriptionID idBuffer;
0662 EntryDescriptionID* pidBuffer = &idBuffer;
0663 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), &pidBuffer);
0664
0665 EventEntryDescription entryDescriptionBuffer;
0666 EventEntryDescription* pEntryDescriptionBuffer = &entryDescriptionBuffer;
0667 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), &pEntryDescriptionBuffer);
0668
0669
0670 ParentageRegistry& registry = *ParentageRegistry::instance();
0671
0672 for (Long64_t i = 0, numEntries = entryDescriptionTree->GetEntries(); i < numEntries; ++i) {
0673 roottree::getEntry(entryDescriptionTree.get(), i);
0674 if (idBuffer != entryDescriptionBuffer.id()) {
0675 throw Exception(errors::EventCorruption) << "Corruption of EntryDescription tree detected.\n";
0676 }
0677 entryDescriptionMap.insert(std::make_pair(entryDescriptionBuffer.id(), entryDescriptionBuffer));
0678 Parentage parents;
0679 parents.setParents(entryDescriptionBuffer.parents());
0680 if (daqProvenanceHelper_) {
0681 ParentageID const oldID = parents.id();
0682 daqProvenanceHelper_->fixMetaData(parents.parentsForUpdate());
0683 ParentageID newID = parents.id();
0684 if (newID != oldID) {
0685 daqProvenanceHelper_->setOldParentageIDToNew(oldID, newID);
0686 }
0687 }
0688
0689 if (inputType != InputType::SecondarySource) {
0690 registry.insertMapped(parents);
0691 }
0692 }
0693 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), nullptr);
0694 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), nullptr);
0695 }
0696
0697 void RootFile::readParentageTree(InputType inputType) {
0698
0699
0700 std::unique_ptr<TTree> parentageTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parentageTreeName().c_str())));
0701 if (nullptr == parentageTree.get()) {
0702 throw Exception(errors::FileReadError)
0703 << "Could not find tree " << poolNames::parentageTreeName() << " in the input file.\n";
0704 }
0705
0706 Parentage parents;
0707 Parentage* pParentageBuffer = &parents;
0708 parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), &pParentageBuffer);
0709
0710 ParentageRegistry& registry = *ParentageRegistry::instance();
0711
0712 parentageIDLookup_.reserve(parentageTree->GetEntries());
0713 for (Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
0714 roottree::getEntry(parentageTree.get(), i);
0715 if (daqProvenanceHelper_) {
0716 ParentageID const oldID = parents.id();
0717 daqProvenanceHelper_->fixMetaData(parents.parentsForUpdate());
0718 ParentageID newID = parents.id();
0719 if (newID != oldID) {
0720 daqProvenanceHelper_->setOldParentageIDToNew(oldID, newID);
0721 }
0722 }
0723
0724 if (inputType != InputType::SecondarySource) {
0725 registry.insertMapped(parents);
0726 }
0727 parentageIDLookup_.push_back(parents.id());
0728 }
0729 parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), nullptr);
0730 }
0731
0732 void RootFile::setIfFastClonable(int remainingEvents, int remainingLumis) {
0733 if (fileFormatVersion().noMetaDataTrees() and !fileFormatVersion().storedProductProvenanceUsed()) {
0734
0735 whyNotFastClonable_ += FileBlock::FileTooOld;
0736 return;
0737 }
0738 if (!fileFormatVersion().splitProductIDs()) {
0739 whyNotFastClonable_ += FileBlock::FileTooOld;
0740 return;
0741 }
0742 if (processingMode_ != InputSource::RunsLumisAndEvents) {
0743 whyNotFastClonable_ += FileBlock::NotProcessingEvents;
0744 return;
0745 }
0746
0747 IndexIntoFile::IndexIntoFileItr it = indexIntoFileBegin_;
0748 while (it != indexIntoFileEnd_ && it.getEntryType() != IndexIntoFile::kEvent) {
0749 ++it;
0750 }
0751 if (it == indexIntoFileEnd_) {
0752 whyNotFastClonable_ += FileBlock::NoEventsInFile;
0753 return;
0754 }
0755
0756
0757 IndexIntoFile::SortOrder sortOrder =
0758 (noRunLumiSort_ ? IndexIntoFile::entryOrder
0759 : (noEventSort_ ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder));
0760 if (!indexIntoFile_.iterationWillBeInEntryOrder(sortOrder)) {
0761 whyNotFastClonable_ += (noEventSort_ ? FileBlock::RunOrLumiNotContiguous : FileBlock::EventsToBeSorted);
0762 }
0763 if (skipAnyEvents_) {
0764 whyNotFastClonable_ += FileBlock::InitialEventsSkipped;
0765 }
0766 if (remainingEvents >= 0 && eventTree_.entries() > remainingEvents) {
0767 whyNotFastClonable_ += FileBlock::MaxEventsTooSmall;
0768 }
0769 if (remainingLumis >= 0 && lumiTree_.entries() > remainingLumis) {
0770 whyNotFastClonable_ += FileBlock::MaxLumisTooSmall;
0771 }
0772 if (duplicateChecker_ && !duplicateChecker_->checkDisabled() && !duplicateChecker_->noDuplicatesInFile()) {
0773 whyNotFastClonable_ += FileBlock::DuplicateEventsRemoved;
0774 }
0775 }
0776
0777 std::shared_ptr<FileBlock> RootFile::createFileBlock() {
0778 std::vector<TTree*> processBlockTrees;
0779 std::vector<std::string> processesWithProcessBlockTrees;
0780 processBlockTrees.reserve(processBlockTrees_.size());
0781 processesWithProcessBlockTrees.reserve(processBlockTrees_.size());
0782 for (auto& processBlockTree : processBlockTrees_) {
0783 processBlockTrees.push_back(processBlockTree->tree());
0784 processesWithProcessBlockTrees.push_back(processBlockTree->processName());
0785 }
0786 return std::make_shared<FileBlock>(fileFormatVersion(),
0787 eventTree_.tree(),
0788 eventTree_.metaTree(),
0789 lumiTree_.tree(),
0790 lumiTree_.metaTree(),
0791 runTree_.tree(),
0792 runTree_.metaTree(),
0793 std::move(processBlockTrees),
0794 std::move(processesWithProcessBlockTrees),
0795 whyNotFastClonable(),
0796 hasNewlyDroppedBranch(),
0797 file_,
0798 branchListIndexesUnchanged(),
0799 modifiedIDs(),
0800 branchChildren());
0801 }
0802
0803 void RootFile::updateFileBlock(FileBlock& fileBlock) {
0804 std::vector<TTree*> processBlockTrees;
0805 std::vector<std::string> processesWithProcessBlockTrees;
0806 processBlockTrees.reserve(processBlockTrees_.size());
0807 processesWithProcessBlockTrees.reserve(processBlockTrees_.size());
0808 for (auto& processBlockTree : processBlockTrees_) {
0809 processBlockTrees.push_back(processBlockTree->tree());
0810 processesWithProcessBlockTrees.push_back(processBlockTree->processName());
0811 }
0812 fileBlock.updateTTreePointers(eventTree_.tree(),
0813 eventTree_.metaTree(),
0814 lumiTree_.tree(),
0815 lumiTree_.metaTree(),
0816 runTree_.tree(),
0817 runTree_.metaTree(),
0818 std::move(processBlockTrees),
0819 std::move(processesWithProcessBlockTrees));
0820 }
0821
0822 std::string const& RootFile::newBranchToOldBranch(std::string const& newBranch) const {
0823 std::map<std::string, std::string>::const_iterator it = newBranchToOldBranch_.find(newBranch);
0824 if (it != newBranchToOldBranch_.end()) {
0825 return it->second;
0826 }
0827 return newBranch;
0828 }
0829
0830 IndexIntoFile::IndexIntoFileItr RootFile::indexIntoFileIter() const { return indexIntoFileIter_; }
0831
0832 void RootFile::setPosition(IndexIntoFile::IndexIntoFileItr const& position) {
0833 indexIntoFileIter_.copyPosition(position);
0834 }
0835
0836 void RootFile::initAssociationsFromSecondary(std::vector<BranchID> const& associationsFromSecondary) {
0837 thinnedAssociationsHelper_->initAssociationsFromSecondary(associationsFromSecondary,
0838 *fileThinnedAssociationsHelper_);
0839 }
0840
0841 bool RootFile::skipThisEntry() {
0842 if (indexIntoFileIter_ == indexIntoFileEnd_) {
0843 return false;
0844 }
0845
0846 if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
0847
0848 if (eventSkipperByID_->skipIt(indexIntoFileIter_.run(), indexIntoFileIter_.lumi(), 0U)) {
0849 return true;
0850 }
0851
0852
0853 if (indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent) {
0854 auto eventAux = fillEventAuxiliary(indexIntoFileIter_.entry());
0855 if (eventSkipperByID_->skipIt(indexIntoFileIter_.run(), indexIntoFileIter_.lumi(), eventAux.id().event())) {
0856 return true;
0857 }
0858 }
0859
0860
0861 if (indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun && eventSkipperByID_->skippingLumis()) {
0862
0863 if (indexIntoFileIter_.peekAheadAtLumi() == IndexIntoFile::invalidLumi) {
0864 return true;
0865 }
0866
0867 do {
0868 if (!eventSkipperByID_->skipIt(indexIntoFileIter_.run(), indexIntoFileIter_.peekAheadAtLumi(), 0U)) {
0869 return false;
0870 }
0871 } while (indexIntoFileIter_.skipLumiInRun());
0872 return true;
0873 }
0874 }
0875 return false;
0876 }
0877
0878 bool RootFile::isDuplicateEvent() {
0879 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent);
0880 if (duplicateChecker_.get() == nullptr) {
0881 return false;
0882 }
0883 auto const eventAux = fillEventAuxiliary(indexIntoFileIter_.entry());
0884 return duplicateChecker_->isDuplicateAndCheckActive(indexIntoFileIter_.processHistoryIDIndex(),
0885 indexIntoFileIter_.run(),
0886 indexIntoFileIter_.lumi(),
0887 eventAux.id().event(),
0888 file_);
0889 }
0890
0891 bool RootFile::containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
0892 return indexIntoFile_.containsItem(run, lumi, event);
0893 }
0894
0895 IndexIntoFile::EntryType RootFile::getNextItemType(RunNumber_t& run,
0896 LuminosityBlockNumber_t& lumi,
0897 EventNumber_t& event) {
0898
0899 while (skipThisEntry()) {
0900 if (indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun) {
0901 indexIntoFileIter_.advanceToNextRun();
0902 } else if (indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi) {
0903 indexIntoFileIter_.advanceToNextLumiOrRun();
0904 } else {
0905 ++indexIntoFileIter_;
0906 }
0907 }
0908
0909 IndexIntoFile::EntryType entryType = indexIntoFileIter_.getEntryType();
0910 if (entryType == IndexIntoFile::kEnd) {
0911 return IndexIntoFile::kEnd;
0912 }
0913 if (entryType == IndexIntoFile::kRun) {
0914 run = indexIntoFileIter_.run();
0915 runHelper_->checkForNewRun(run, indexIntoFileIter_.peekAheadAtLumi());
0916 return IndexIntoFile::kRun;
0917 } else if (processingMode_ == InputSource::Runs) {
0918 indexIntoFileIter_.advanceToNextRun();
0919 return getNextItemType(run, lumi, event);
0920 }
0921 if (entryType == IndexIntoFile::kLumi) {
0922 run = indexIntoFileIter_.run();
0923 lumi = indexIntoFileIter_.lumi();
0924 return IndexIntoFile::kLumi;
0925 } else if (processingMode_ == InputSource::RunsAndLumis) {
0926 indexIntoFileIter_.advanceToNextLumiOrRun();
0927 return getNextItemType(run, lumi, event);
0928 }
0929 if (isDuplicateEvent()) {
0930 ++indexIntoFileIter_;
0931 return getNextItemType(run, lumi, event);
0932 }
0933 run = indexIntoFileIter_.run();
0934 lumi = indexIntoFileIter_.lumi();
0935 auto eventAux = fillEventAuxiliary(indexIntoFileIter_.entry());
0936 event = eventAux.event();
0937 return IndexIntoFile::kEvent;
0938 }
0939
0940 bool RootFile::wasLastEventJustRead() const {
0941 IndexIntoFile::IndexIntoFileItr itr(indexIntoFileIter_);
0942 itr.advanceToEvent();
0943 return itr.getEntryType() == IndexIntoFile::kEnd;
0944 }
0945
0946 bool RootFile::wasFirstEventJustRead() const {
0947 IndexIntoFile::IndexIntoFileItr itr(indexIntoFileIter_);
0948 int phIndex;
0949 RunNumber_t run;
0950 LuminosityBlockNumber_t lumi;
0951 IndexIntoFile::EntryNumber_t eventEntry;
0952 itr.skipEventBackward(phIndex, run, lumi, eventEntry);
0953 itr.skipEventBackward(phIndex, run, lumi, eventEntry);
0954 return eventEntry == IndexIntoFile::invalidEntry;
0955 }
0956
0957 namespace {
0958 struct RunItem {
0959 RunItem(ProcessHistoryID const& phid, RunNumber_t const& run) : phid_(phid), run_(run) {}
0960 ProcessHistoryID phid_;
0961 RunNumber_t run_;
0962 };
0963 struct RunItemSortByRun {
0964 bool operator()(RunItem const& a, RunItem const& b) const { return a.run_ < b.run_; }
0965 };
0966 struct RunItemSortByRunPhid {
0967 bool operator()(RunItem const& a, RunItem const& b) const {
0968 return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.phid_ < b.phid_);
0969 }
0970 };
0971 struct LumiItem {
0972 LumiItem(ProcessHistoryID const& phid,
0973 RunNumber_t const& run,
0974 LuminosityBlockNumber_t const& lumi,
0975 IndexIntoFile::EntryNumber_t const& entry)
0976 : phid_(phid),
0977 run_(run),
0978 lumi_(lumi),
0979 firstEventEntry_(entry),
0980 lastEventEntry_(entry == IndexIntoFile::invalidEntry ? IndexIntoFile::invalidEntry : entry + 1) {}
0981 ProcessHistoryID phid_;
0982 RunNumber_t run_;
0983 LuminosityBlockNumber_t lumi_;
0984 IndexIntoFile::EntryNumber_t firstEventEntry_;
0985 IndexIntoFile::EntryNumber_t lastEventEntry_;
0986 };
0987 struct LumiItemSortByRunLumi {
0988 bool operator()(LumiItem const& a, LumiItem const& b) const {
0989 return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.lumi_ < b.lumi_);
0990 }
0991 };
0992 struct LumiItemSortByRunLumiPhid {
0993 bool operator()(LumiItem const& a, LumiItem const& b) const {
0994 if (a.run_ < b.run_)
0995 return true;
0996 if (b.run_ < a.run_)
0997 return false;
0998 if (a.lumi_ < b.lumi_)
0999 return true;
1000 if (b.lumi_ < a.lumi_)
1001 return false;
1002 return a.phid_ < b.phid_;
1003 }
1004 };
1005 }
1006
1007 void RootFile::fillIndexIntoFile() {
1008
1009
1010
1011
1012
1013
1014
1015 assert(!fileFormatVersion().hasIndexIntoFile());
1016
1017 typedef std::list<LumiItem> LumiList;
1018 LumiList lumis;
1019
1020 typedef std::set<LuminosityBlockID> RunLumiSet;
1021 RunLumiSet runLumiSet;
1022
1023 typedef std::list<RunItem> RunList;
1024 RunList runs;
1025
1026 typedef std::set<RunNumber_t> RunSet;
1027 RunSet runSet;
1028
1029 typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
1030 RunItemSet runItemSet;
1031
1032 typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
1033 PHIDMap phidMap;
1034
1035 RunNumber_t prevRun = 0;
1036 LuminosityBlockNumber_t prevLumi = 0;
1037 ProcessHistoryID prevPhid;
1038 bool iFirst = true;
1039
1040 indexIntoFile_.unsortedEventNumbers().clear();
1041 indexIntoFile_.unsortedEventNumbers().reserve(eventTree_.entries());
1042
1043
1044 EventSelectionIDVector eventSelectionIDs;
1045 BranchListIndexes branchListIndexes;
1046 while (eventTree_.next()) {
1047 bool newRun = false;
1048 bool newLumi = false;
1049 auto evtAux = fillThisEventAuxiliary();
1050 fillEventHistory(evtAux, eventSelectionIDs, branchListIndexes);
1051
1052
1053
1054
1055 indexIntoFile_.unsortedEventNumbers().push_back(evtAux.event());
1056
1057 ProcessHistoryID reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(evtAux.processHistoryID());
1058
1059 if (iFirst || prevPhid != reducedPHID || prevRun != evtAux.run()) {
1060 iFirst = false;
1061 newRun = newLumi = true;
1062 } else if (prevLumi != evtAux.luminosityBlock()) {
1063 newLumi = true;
1064 }
1065 prevPhid = reducedPHID;
1066 prevRun = evtAux.run();
1067 prevLumi = evtAux.luminosityBlock();
1068 if (newLumi) {
1069 lumis.emplace_back(
1070 reducedPHID, evtAux.run(), evtAux.luminosityBlock(), eventTree_.entryNumber());
1071 runLumiSet.insert(LuminosityBlockID(evtAux.run(), evtAux.luminosityBlock()));
1072 } else {
1073 LumiItem& currentLumi = lumis.back();
1074 assert(currentLumi.lastEventEntry_ == eventTree_.entryNumber());
1075 ++currentLumi.lastEventEntry_;
1076 }
1077 if (newRun) {
1078
1079 RunItem item(reducedPHID, evtAux.run());
1080 if (runItemSet.insert(item).second) {
1081 runs.push_back(std::move(item));
1082 runSet.insert(evtAux.run());
1083 phidMap.insert(std::make_pair(evtAux.run(), reducedPHID));
1084 }
1085 }
1086 }
1087
1088 eventTree_.setEntryNumber(IndexIntoFile::invalidEntry);
1089 lastEventEntryNumberRead_ = IndexIntoFile::invalidEntry;
1090
1091
1092
1093 typedef std::map<RunNumber_t, IndexIntoFile::EntryNumber_t> RunMap;
1094 RunMap runMap;
1095
1096 typedef std::vector<RunItem> RunVector;
1097 RunVector emptyRuns;
1098
1099 if (runTree_.isValid()) {
1100 while (runTree_.next()) {
1101
1102
1103 std::shared_ptr<RunAuxiliary> runAux = fillRunAuxiliary();
1104 ProcessHistoryID reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(runAux->processHistoryID());
1105
1106 if (runSet.insert(runAux->run()).second) {
1107
1108 emptyRuns.emplace_back(reducedPHID, runAux->run());
1109 }
1110 runMap.insert(std::make_pair(runAux->run(), runTree_.entryNumber()));
1111 phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
1112 }
1113
1114 runTree_.setEntryNumber(IndexIntoFile::invalidEntry);
1115 }
1116
1117
1118 RunItemSortByRun runItemSortByRun;
1119 stable_sort_all(emptyRuns, runItemSortByRun);
1120
1121 RunList::iterator itRuns = runs.begin(), endRuns = runs.end();
1122 for (auto const& emptyRun : emptyRuns) {
1123 for (; itRuns != endRuns; ++itRuns) {
1124 if (runItemSortByRun(emptyRun, *itRuns)) {
1125 break;
1126 }
1127 }
1128 runs.insert(itRuns, emptyRun);
1129 }
1130
1131
1132
1133 typedef std::vector<LumiItem> LumiVector;
1134 LumiVector emptyLumis;
1135
1136 typedef std::map<LuminosityBlockID, IndexIntoFile::EntryNumber_t> RunLumiMap;
1137 RunLumiMap runLumiMap;
1138
1139 if (lumiTree_.isValid()) {
1140 while (lumiTree_.next()) {
1141
1142 std::shared_ptr<LuminosityBlockAuxiliary> lumiAux = fillLumiAuxiliary();
1143 LuminosityBlockID lumiID = LuminosityBlockID(lumiAux->run(), lumiAux->luminosityBlock());
1144 if (runLumiSet.insert(lumiID).second) {
1145
1146
1147
1148
1149 PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
1150 assert(iPhidMap != phidMap.end());
1151 emptyLumis.emplace_back(
1152 iPhidMap->second, lumiAux->run(), lumiAux->luminosityBlock(), IndexIntoFile::invalidEntry);
1153 }
1154 runLumiMap.insert(std::make_pair(lumiID, lumiTree_.entryNumber()));
1155 }
1156
1157 lumiTree_.setEntryNumber(IndexIntoFile::invalidEntry);
1158 }
1159
1160
1161 LumiItemSortByRunLumi lumiItemSortByRunLumi;
1162 stable_sort_all(emptyLumis, lumiItemSortByRunLumi);
1163
1164 LumiList::iterator itLumis = lumis.begin(), endLumis = lumis.end();
1165 for (auto const& emptyLumi : emptyLumis) {
1166 for (; itLumis != endLumis; ++itLumis) {
1167 if (lumiItemSortByRunLumi(emptyLumi, *itLumis)) {
1168 break;
1169 }
1170 }
1171 lumis.insert(itLumis, emptyLumi);
1172 }
1173
1174
1175
1176 typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
1177 RunCountMap runCountMap;
1178 std::vector<ProcessHistoryID>& phids = indexIntoFile_.setProcessHistoryIDs();
1179 assert(phids.empty());
1180 std::vector<IndexIntoFile::RunOrLumiEntry>& entries = indexIntoFile_.setRunOrLumiEntries();
1181 assert(entries.empty());
1182 int rcount = 0;
1183 for (auto& run : runs) {
1184 RunCountMap::const_iterator countMapItem = runCountMap.find(run);
1185 if (countMapItem == runCountMap.end()) {
1186 countMapItem = runCountMap.insert(std::make_pair(run, rcount)).first;
1187 assert(countMapItem != runCountMap.end());
1188 ++rcount;
1189 }
1190 std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, run.phid_);
1191 if (phidItem == phids.end()) {
1192 phids.push_back(run.phid_);
1193 phidItem = phids.end() - 1;
1194 }
1195 entries.emplace_back(countMapItem->second,
1196 IndexIntoFile::invalidEntry,
1197 runMap[run.run_],
1198 phidItem - phids.begin(),
1199 run.run_,
1200 0U,
1201 IndexIntoFile::invalidEntry,
1202 IndexIntoFile::invalidEntry);
1203 }
1204
1205
1206 typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
1207 LumiCountMap lumiCountMap;
1208 int lcount = 0;
1209 for (auto& lumi : lumis) {
1210 RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(lumi.phid_, lumi.run_));
1211 assert(runCountMapItem != runCountMap.end());
1212 LumiCountMap::const_iterator countMapItem = lumiCountMap.find(lumi);
1213 if (countMapItem == lumiCountMap.end()) {
1214 countMapItem = lumiCountMap.insert(std::make_pair(lumi, lcount)).first;
1215 assert(countMapItem != lumiCountMap.end());
1216 ++lcount;
1217 }
1218 std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, lumi.phid_);
1219 assert(phidItem != phids.end());
1220 entries.emplace_back(runCountMapItem->second,
1221 countMapItem->second,
1222 runLumiMap[LuminosityBlockID(lumi.run_, lumi.lumi_)],
1223 phidItem - phids.begin(),
1224 lumi.run_,
1225 lumi.lumi_,
1226 lumi.firstEventEntry_,
1227 lumi.lastEventEntry_);
1228 }
1229 stable_sort_all(entries);
1230 }
1231
1232 void RootFile::validateFile(InputType inputType, bool usingGoToEvent) {
1233 if (!fid_.isValid()) {
1234 fid_ = FileID(createGlobalIdentifier());
1235 }
1236 if (!eventTree_.isValid()) {
1237 throw Exception(errors::EventCorruption) << "'Events' tree is corrupted or not present\n"
1238 << "in the input file.\n";
1239 }
1240 if (enforceGUIDInFileName_) {
1241 auto guidFromName = stemFromPath(file_);
1242 if (guidFromName != fid_.fid()) {
1243 throw edm::Exception(edm::errors::FileNameInconsistentWithGUID)
1244 << "GUID " << guidFromName << " extracted from file name " << file_
1245 << " is inconsistent with the GUID read from the file " << fid_.fid();
1246 }
1247 }
1248
1249 if (fileFormatVersion().hasIndexIntoFile()) {
1250 if (runTree().entries() > 0) {
1251 assert(!indexIntoFile_.empty());
1252 }
1253 if (!fileFormatVersion().useReducedProcessHistoryID()) {
1254 if (daqProvenanceHelper_) {
1255 std::vector<ProcessHistoryID>& phidVec = indexIntoFile_.setProcessHistoryIDs();
1256 for (auto& phid : phidVec) {
1257 phid = daqProvenanceHelper_->mapProcessHistoryID(phid);
1258 }
1259 }
1260 indexIntoFile_.reduceProcessHistoryIDs(*processHistoryRegistry_);
1261 }
1262 } else {
1263 assert(indexIntoFile_.empty());
1264 fillIndexIntoFile();
1265 }
1266
1267 indexIntoFile_.fixIndexes(orderedProcessHistoryIDs_);
1268 indexIntoFile_.setNumberOfEvents(eventTree_.entries());
1269 indexIntoFile_.setEventFinder(
1270 std::shared_ptr<IndexIntoFile::EventFinder>(std::make_shared<RootFileEventFinder>(eventTree_)));
1271
1272
1273 bool needEventNumbers = false;
1274 bool needIndexesForDuplicateChecker =
1275 duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled();
1276 if (inputType != InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
1277 needEventNumbers = true;
1278 }
1279 bool needEventEntries = false;
1280 if (inputType != InputType::Primary || !noEventSort_) {
1281
1282 needEventEntries = true;
1283 }
1284 indexIntoFile_.fillEventNumbersOrEntries(needEventNumbers, needEventEntries);
1285 }
1286
1287 void RootFile::reportOpened(std::string const& inputType) {
1288
1289 std::string const label = "source";
1290 std::string moduleName = "PoolSource";
1291 filePtr_->inputFileOpened(logicalFile_, inputType, moduleName, label, fid_.fid(), eventTree_.branchNames());
1292 }
1293
1294 void RootFile::close() {
1295
1296 eventHistoryTree_ = nullptr;
1297 for (auto& treePointer : treePointers_) {
1298 treePointer->close();
1299 treePointer = nullptr;
1300 }
1301 filePtr_->Close();
1302 filePtr_ = nullptr;
1303 }
1304
1305 EventAuxiliary const& RootFile::fillThisEventAuxiliary() {
1306 if (lastEventEntryNumberRead_ == eventTree_.entryNumber()) {
1307
1308 return eventAuxCache_;
1309 }
1310 if (fileFormatVersion().newAuxiliary()) {
1311 EventAuxiliary* pEvAux = &eventAuxCache_;
1312 eventTree_.fillAux<EventAuxiliary>(pEvAux);
1313 } else {
1314
1315 EventAux eventAux;
1316 EventAux* pEvAux = &eventAux;
1317 eventTree_.fillAux<EventAux>(pEvAux);
1318 conversion(eventAux, eventAuxCache_);
1319 }
1320 lastEventEntryNumberRead_ = eventTree_.entryNumber();
1321 return eventAuxCache_;
1322 }
1323
1324 EventAuxiliary RootFile::fillEventAuxiliary(IndexIntoFile::EntryNumber_t entry) {
1325 eventTree_.setEntryNumber(entry);
1326 return fillThisEventAuxiliary();
1327 }
1328
1329 void RootFile::fillEventToProcessBlockIndexes() {
1330 TBranch* eventToProcessBlockIndexesBranch = get_underlying_safe(eventToProcessBlockIndexesBranch_);
1331 if (eventToProcessBlockIndexesBranch == nullptr) {
1332 if (processBlockHelper_.get() == nullptr) {
1333 eventToProcessBlockIndexes_.setIndex(0);
1334 } else {
1335 eventToProcessBlockIndexes_.setIndex(processBlockHelper_->outerOffset());
1336 }
1337 } else {
1338 if (processBlockHelper_->cacheIndexVectorsPerFile().back() == 1u) {
1339 eventToProcessBlockIndexes_.setIndex(processBlockHelper_->outerOffset());
1340 } else {
1341 EventToProcessBlockIndexes* pEventToProcessBlockIndexes = &eventToProcessBlockIndexes_;
1342 eventTree_.fillBranchEntry(eventToProcessBlockIndexesBranch, pEventToProcessBlockIndexes);
1343 unsigned int updatedIndex = eventToProcessBlockIndexes_.index() + processBlockHelper_->outerOffset();
1344 eventToProcessBlockIndexes_.setIndex(updatedIndex);
1345 }
1346 }
1347 }
1348
1349 bool RootFile::fillEventHistory(EventAuxiliary& evtAux,
1350 EventSelectionIDVector& eventSelectionIDs,
1351 BranchListIndexes& branchListIndexes,
1352 bool assertOnFailure) {
1353
1354
1355
1356 if (fileFormatVersion().eventHistoryBranch()) {
1357
1358 EventID id(evtAux.id().run(), 0, evtAux.id().event());
1359 if (eventProcessHistoryIter_->eventID() != id) {
1360 EventProcessHistoryID target(id, ProcessHistoryID());
1361 eventProcessHistoryIter_ = lower_bound_all(eventProcessHistoryIDs_, target);
1362 assert(eventProcessHistoryIter_->eventID() == id);
1363 }
1364 evtAux.setProcessHistoryID(eventProcessHistoryIter_->processHistoryID());
1365 ++eventProcessHistoryIter_;
1366 } else if (fileFormatVersion().eventHistoryTree()) {
1367
1368 History* pHistory = history_.get();
1369 TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(poolNames::eventHistoryBranchName().c_str());
1370 if (!eventHistoryBranch) {
1371 throw Exception(errors::EventCorruption) << "Failed to find history branch in event history tree.\n";
1372 }
1373 eventHistoryBranch->SetAddress(&pHistory);
1374 roottree::getEntry(eventHistoryTree_, eventTree_.entryNumber());
1375 evtAux.setProcessHistoryID(history_->processHistoryID());
1376 eventSelectionIDs.swap(history_->eventSelectionIDs());
1377 branchListIndexes.swap(history_->branchListIndexes());
1378 } else if (fileFormatVersion().noMetaDataTrees()) {
1379
1380 EventSelectionIDVector* pESV = &eventSelectionIDs;
1381 TBranch* eventSelectionIDBranch = eventTree_.tree()->GetBranch(poolNames::eventSelectionsBranchName().c_str());
1382 assert(eventSelectionIDBranch != nullptr);
1383 eventTree_.fillBranchEntry(eventSelectionIDBranch, pESV);
1384 BranchListIndexes* pBLI = &branchListIndexes;
1385 TBranch* branchListIndexesBranch = eventTree_.tree()->GetBranch(poolNames::branchListIndexesBranchName().c_str());
1386 assert(branchListIndexesBranch != nullptr);
1387 eventTree_.fillBranchEntry(branchListIndexesBranch, pBLI);
1388 }
1389 if (provenanceAdaptor_) {
1390 evtAux.setProcessHistoryID(provenanceAdaptor_->convertID(evtAux.processHistoryID()));
1391 for (auto& esID : eventSelectionIDs) {
1392 esID = provenanceAdaptor_->convertID(esID);
1393 }
1394 }
1395 if (daqProvenanceHelper_) {
1396 evtAux.setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(evtAux.processHistoryID()));
1397 }
1398 if (!fileFormatVersion().splitProductIDs()) {
1399
1400 provenanceAdaptor_->branchListIndexes(branchListIndexes);
1401 }
1402 if (branchIDListHelper_) {
1403 return branchIDListHelper_->fixBranchListIndexes(branchListIndexes, assertOnFailure);
1404 }
1405 return true;
1406 }
1407
1408 std::shared_ptr<LuminosityBlockAuxiliary> RootFile::fillLumiAuxiliary() {
1409 auto lumiAuxiliary = std::make_shared<LuminosityBlockAuxiliary>();
1410 if (fileFormatVersion().newAuxiliary()) {
1411 LuminosityBlockAuxiliary* pLumiAux = lumiAuxiliary.get();
1412 lumiTree_.fillAux<LuminosityBlockAuxiliary>(pLumiAux);
1413 } else {
1414 LuminosityBlockAux lumiAux;
1415 LuminosityBlockAux* pLumiAux = &lumiAux;
1416 lumiTree_.fillAux<LuminosityBlockAux>(pLumiAux);
1417 conversion(lumiAux, *lumiAuxiliary);
1418 }
1419 if (provenanceAdaptor_) {
1420 lumiAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
1421 }
1422 if (daqProvenanceHelper_) {
1423 lumiAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
1424 }
1425 if (lumiAuxiliary->luminosityBlock() == 0 && !fileFormatVersion().runsAndLumis()) {
1426 lumiAuxiliary->id() = LuminosityBlockID(RunNumber_t(1), LuminosityBlockNumber_t(1));
1427 }
1428 return lumiAuxiliary;
1429 }
1430
1431 std::shared_ptr<RunAuxiliary> RootFile::fillRunAuxiliary() {
1432 auto runAuxiliary = std::make_shared<RunAuxiliary>();
1433 if (fileFormatVersion().newAuxiliary()) {
1434 RunAuxiliary* pRunAux = runAuxiliary.get();
1435 runTree_.fillAux<RunAuxiliary>(pRunAux);
1436 } else {
1437 RunAux runAux;
1438 RunAux* pRunAux = &runAux;
1439 runTree_.fillAux<RunAux>(pRunAux);
1440 conversion(runAux, *runAuxiliary);
1441 }
1442 if (provenanceAdaptor_) {
1443 runAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
1444 }
1445 if (daqProvenanceHelper_) {
1446 runAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
1447 }
1448 return runAuxiliary;
1449 }
1450
1451 bool RootFile::skipEvents(int& offset) {
1452 while (offset > 0 && indexIntoFileIter_ != indexIntoFileEnd_) {
1453 int phIndexOfSkippedEvent = IndexIntoFile::invalidIndex;
1454 RunNumber_t runOfSkippedEvent = IndexIntoFile::invalidRun;
1455 LuminosityBlockNumber_t lumiOfSkippedEvent = IndexIntoFile::invalidLumi;
1456 IndexIntoFile::EntryNumber_t skippedEventEntry = IndexIntoFile::invalidEntry;
1457
1458 indexIntoFileIter_.skipEventForward(
1459 phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1460
1461
1462 if (skippedEventEntry == IndexIntoFile::invalidEntry)
1463 break;
1464
1465 if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1466 auto const evtAux = fillEventAuxiliary(skippedEventEntry);
1467 if (eventSkipperByID_->skipIt(runOfSkippedEvent, lumiOfSkippedEvent, evtAux.id().event())) {
1468 continue;
1469 }
1470 }
1471 if (duplicateChecker_ && !duplicateChecker_->checkDisabled() && !duplicateChecker_->noDuplicatesInFile()) {
1472 auto const evtAux = fillEventAuxiliary(skippedEventEntry);
1473 if (duplicateChecker_->isDuplicateAndCheckActive(
1474 phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, evtAux.id().event(), file_)) {
1475 continue;
1476 }
1477 }
1478 --offset;
1479 }
1480
1481 while (offset < 0) {
1482 if (duplicateChecker_) {
1483 duplicateChecker_->disable();
1484 }
1485
1486 int phIndexOfEvent = IndexIntoFile::invalidIndex;
1487 RunNumber_t runOfEvent = IndexIntoFile::invalidRun;
1488 LuminosityBlockNumber_t lumiOfEvent = IndexIntoFile::invalidLumi;
1489 IndexIntoFile::EntryNumber_t eventEntry = IndexIntoFile::invalidEntry;
1490
1491 indexIntoFileIter_.skipEventBackward(phIndexOfEvent, runOfEvent, lumiOfEvent, eventEntry);
1492
1493 if (eventEntry == IndexIntoFile::invalidEntry)
1494 break;
1495
1496 if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1497 auto const evtAux = fillEventAuxiliary(eventEntry);
1498 if (eventSkipperByID_->skipIt(runOfEvent, lumiOfEvent, evtAux.id().event())) {
1499 continue;
1500 }
1501 }
1502 ++offset;
1503 }
1504 return (indexIntoFileIter_ == indexIntoFileEnd_);
1505 }
1506
1507 bool RootFile::goToEvent(EventID const& eventID) {
1508 indexIntoFile_.fillEventNumbers();
1509
1510 if (duplicateChecker_) {
1511 duplicateChecker_->disable();
1512 }
1513
1514 IndexIntoFile::SortOrder sortOrder = IndexIntoFile::numericalOrder;
1515 if (noEventSort_)
1516 sortOrder = IndexIntoFile::firstAppearanceOrder;
1517 if (noRunLumiSort_) {
1518 sortOrder = IndexIntoFile::entryOrder;
1519 }
1520
1521 IndexIntoFile::IndexIntoFileItr iter =
1522 indexIntoFile_.findPosition(sortOrder, eventID.run(), eventID.luminosityBlock(), eventID.event());
1523
1524 if (iter == indexIntoFile_.end(sortOrder)) {
1525 return false;
1526 }
1527 indexIntoFileIter_ = iter;
1528 return true;
1529 }
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543 bool RootFile::readEvent(EventPrincipal& principal) {
1544 assert(indexIntoFileIter_ != indexIntoFileEnd_);
1545 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent);
1546
1547 auto [found, succeeded] = readCurrentEvent(principal, false);
1548 auto const& evtAux = principal.aux();
1549
1550 runHelper_->checkRunConsistency(evtAux.run(), indexIntoFileIter_.run());
1551 runHelper_->checkLumiConsistency(evtAux.luminosityBlock(), indexIntoFileIter_.lumi());
1552
1553 ++indexIntoFileIter_;
1554 return succeeded;
1555 }
1556
1557
1558 std::tuple<bool, bool> RootFile::readCurrentEvent(EventPrincipal& principal, bool assertOnFailure) {
1559 bool found = true;
1560 bool succeeded = true;
1561 if (!eventTree_.current()) {
1562 found = false;
1563 return {found, succeeded};
1564 }
1565 auto evtAux = fillThisEventAuxiliary();
1566 if (!fileFormatVersion().lumiInEventID()) {
1567
1568 const_cast<EventID&>(evtAux.id()).setLuminosityBlockNumber(evtAux.oldLuminosityBlock());
1569 evtAux.resetObsoleteInfo();
1570 }
1571 fillEventToProcessBlockIndexes();
1572 EventSelectionIDVector eventSelectionIDs;
1573 BranchListIndexes branchListIndexes;
1574 if (!fillEventHistory(evtAux, eventSelectionIDs, branchListIndexes, assertOnFailure)) {
1575 succeeded = false;
1576 }
1577 runHelper_->overrideRunNumber(evtAux.id(), evtAux.isRealData());
1578
1579
1580 eventTree_.insertEntryForIndex(principal.transitionIndex());
1581 auto history = processHistoryRegistry_->getMapped(evtAux.processHistoryID());
1582 principal.fillEventPrincipal(evtAux,
1583 history,
1584 std::move(eventSelectionIDs),
1585 std::move(branchListIndexes),
1586 eventToProcessBlockIndexes_,
1587 *(makeProductProvenanceRetriever(principal.streamID().value())),
1588 eventTree_.resetAndGetRootDelayedReader());
1589
1590
1591
1592 ProcessHistoryID idToCheck = (daqProvenanceHelper_ && fileFormatVersion().useReducedProcessHistoryID()
1593 ? *daqProvenanceHelper_->oldProcessHistoryID()
1594 : evtAux.processHistoryID());
1595 ProcessHistoryID const& reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(idToCheck);
1596 assert(reducedPHID == indexIntoFile_.processHistoryID(indexIntoFileIter_.processHistoryIDIndex()));
1597
1598
1599 filePtr_->eventReadFromFile();
1600 return {found, succeeded};
1601 }
1602
1603 void RootFile::setAtEventEntry(IndexIntoFile::EntryNumber_t entry) { eventTree_.setEntryNumber(entry); }
1604
1605 std::shared_ptr<RunAuxiliary> RootFile::readRunAuxiliary_() {
1606 if (runHelper_->fakeNewRun()) {
1607 auto runAuxiliary = std::make_shared<RunAuxiliary>(*savedRunAuxiliary());
1608 runHelper_->overrideRunNumber(runAuxiliary->id());
1609 return runAuxiliary;
1610 }
1611 assert(indexIntoFileIter_ != indexIntoFileEnd_);
1612 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun);
1613
1614
1615 if (!runTree_.isValid()) {
1616
1617
1618 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisRun();
1619 assert(eventEntry != IndexIntoFile::invalidEntry);
1620 assert(eventTree_.current(eventEntry));
1621 auto const evtAux = fillEventAuxiliary(eventEntry);
1622
1623 RunID run = RunID(indexIntoFileIter_.run());
1624 runHelper_->overrideRunNumber(run);
1625 savedRunAuxiliary_ = std::make_shared<RunAuxiliary>(run.run(), evtAux.time(), Timestamp::invalidTimestamp());
1626 return savedRunAuxiliary();
1627 }
1628
1629 runTree_.setEntryNumber(indexIntoFileIter_.entry());
1630 std::shared_ptr<RunAuxiliary> runAuxiliary = fillRunAuxiliary();
1631 assert(runAuxiliary->run() == indexIntoFileIter_.run());
1632 runHelper_->overrideRunNumber(runAuxiliary->id());
1633 filePtr_->reportInputRunNumber(runAuxiliary->run());
1634
1635 if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1636 runAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1637 }
1638
1639
1640
1641
1642 if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp() ||
1643 !fileFormatVersion().processHistorySameWithinRun()) {
1644 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisRun();
1645
1646 if (eventEntry != IndexIntoFile::invalidEntry) {
1647 assert(eventTree_.current(eventEntry));
1648 auto evtAux = fillEventAuxiliary(eventEntry);
1649
1650
1651 if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1652 runAuxiliary->setBeginTime(evtAux.time());
1653 }
1654
1655
1656
1657
1658
1659 if (!fileFormatVersion().processHistorySameWithinRun()) {
1660 EventSelectionIDVector eventSelectionIDs;
1661 BranchListIndexes branchListIndexes;
1662 fillEventHistory(evtAux, eventSelectionIDs, branchListIndexes);
1663 runAuxiliary->setProcessHistoryID(evtAux.processHistoryID());
1664 }
1665 }
1666 }
1667 savedRunAuxiliary_ = runAuxiliary;
1668 return runAuxiliary;
1669 }
1670
1671 void RootFile::fillProcessBlockHelper_() {
1672 assert(inputType_ == InputType::Primary);
1673 std::vector<unsigned int> nEntries;
1674 nEntries.reserve(processBlockTrees_.size());
1675 for (auto const& processBlockTree : processBlockTrees_) {
1676 nEntries.push_back(processBlockTree->entries());
1677 }
1678 processBlockHelper_->fillFromPrimaryInput(*storedProcessBlockHelper_, nEntries);
1679 storedProcessBlockHelper_ =
1680 std::make_unique<StoredProcessBlockHelper>();
1681 }
1682
1683 bool RootFile::initializeFirstProcessBlockEntry() {
1684 if (processBlockTrees_[currentProcessBlockTree_]->entryNumber() == IndexIntoFile::invalidEntry) {
1685 processBlockTrees_[currentProcessBlockTree_]->setEntryNumber(0);
1686 assert(processBlockTrees_[currentProcessBlockTree_]->current());
1687 return true;
1688 }
1689 return false;
1690 }
1691
1692 bool RootFile::endOfProcessBlocksReached() const { return currentProcessBlockTree_ >= processBlockTrees_.size(); }
1693
1694 bool RootFile::nextProcessBlock_(ProcessBlockPrincipal&) {
1695 assert(inputType_ == InputType::Primary);
1696 if (endOfProcessBlocksReached()) {
1697 return false;
1698 }
1699 if (initializeFirstProcessBlockEntry()) {
1700 return true;
1701 }
1702
1703
1704
1705 assert(processBlockTrees_[currentProcessBlockTree_]->current());
1706
1707 if (processBlockTrees_[currentProcessBlockTree_]->nextWithCache()) {
1708 return true;
1709 }
1710
1711 ++currentProcessBlockTree_;
1712 if (endOfProcessBlocksReached()) {
1713 return false;
1714 }
1715
1716
1717 processBlockTrees_[currentProcessBlockTree_]->setEntryNumber(0);
1718 assert(processBlockTrees_[currentProcessBlockTree_]->current());
1719 return true;
1720 }
1721
1722 void RootFile::readProcessBlock_(ProcessBlockPrincipal& processBlockPrincipal) {
1723 assert(inputType_ == InputType::Primary);
1724 RootTree* rootTree = processBlockTrees_[currentProcessBlockTree_].get();
1725 rootTree->insertEntryForIndex(0);
1726 assert(!rootTree->processName().empty());
1727 processBlockPrincipal.fillProcessBlockPrincipal(rootTree->processName(), rootTree->resetAndGetRootDelayedReader());
1728 }
1729
1730 bool RootFile::readRun_(RunPrincipal& runPrincipal) {
1731 bool shouldProcessRun = indexIntoFileIter_.shouldProcessRun();
1732
1733 MergeableRunProductMetadata* mergeableRunProductMetadata = nullptr;
1734 if (shouldProcessRun) {
1735 if (inputType_ == InputType::Primary) {
1736 mergeableRunProductMetadata = runPrincipal.mergeableRunProductMetadata();
1737 RootTree::EntryNumber const& entryNumber = runTree_.entryNumber();
1738 assert(entryNumber >= 0);
1739 mergeableRunProductMetadata->readRun(
1740 entryNumber, *storedMergeableRunProductMetadata_, IndexIntoFileItrHolder(indexIntoFileIter_));
1741 }
1742 }
1743
1744 if (!runHelper_->fakeNewRun()) {
1745 assert(indexIntoFileIter_ != indexIntoFileEnd_);
1746 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun);
1747 ++indexIntoFileIter_;
1748 }
1749
1750 if (!runTree_.isValid()) {
1751 return shouldProcessRun;
1752 }
1753
1754 if (shouldProcessRun) {
1755
1756 runTree_.insertEntryForIndex(0);
1757 runPrincipal.fillRunPrincipal(*processHistoryRegistry_, runTree_.resetAndGetRootDelayedReader());
1758
1759 runPrincipal.readAllFromSourceAndMergeImmediately(mergeableRunProductMetadata);
1760 runPrincipal.setShouldWriteRun(RunPrincipal::kYes);
1761 } else {
1762 runPrincipal.fillRunPrincipal(*processHistoryRegistry_, nullptr);
1763 if (runPrincipal.shouldWriteRun() != RunPrincipal::kYes) {
1764 runPrincipal.setShouldWriteRun(RunPrincipal::kNo);
1765 }
1766 }
1767 return shouldProcessRun;
1768 }
1769
1770 std::shared_ptr<LuminosityBlockAuxiliary> RootFile::readLuminosityBlockAuxiliary_() {
1771 assert(indexIntoFileIter_ != indexIntoFileEnd_);
1772 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi);
1773
1774 if (!lumiTree_.isValid()) {
1775 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisLumi();
1776 assert(eventEntry != IndexIntoFile::invalidEntry);
1777 assert(eventTree_.current(eventEntry));
1778 auto const evtAux = fillEventAuxiliary(eventEntry);
1779
1780 LuminosityBlockID lumi = LuminosityBlockID(indexIntoFileIter_.run(), indexIntoFileIter_.lumi());
1781 runHelper_->overrideRunNumber(lumi);
1782 return std::make_shared<LuminosityBlockAuxiliary>(
1783 lumi.run(), lumi.luminosityBlock(), evtAux.time(), Timestamp::invalidTimestamp());
1784 }
1785
1786 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
1787 std::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary = fillLumiAuxiliary();
1788 assert(lumiAuxiliary->run() == indexIntoFileIter_.run());
1789 assert(lumiAuxiliary->luminosityBlock() == indexIntoFileIter_.lumi());
1790 runHelper_->overrideRunNumber(lumiAuxiliary->id());
1791 filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
1792 if (lumiAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1793 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisLumi();
1794 if (eventEntry != IndexIntoFile::invalidEntry) {
1795 assert(eventTree_.current(eventEntry));
1796 auto const evtAux = fillEventAuxiliary(eventEntry);
1797
1798 lumiAuxiliary->setBeginTime(evtAux.time());
1799 }
1800 lumiAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1801 }
1802 if (!fileFormatVersion().processHistorySameWithinRun() && savedRunAuxiliary_) {
1803 lumiAuxiliary->setProcessHistoryID(savedRunAuxiliary_->processHistoryID());
1804 }
1805 return lumiAuxiliary;
1806 }
1807
1808 bool RootFile::readLuminosityBlock_(LuminosityBlockPrincipal& lumiPrincipal) {
1809 bool shouldProcessLumi = indexIntoFileIter_.shouldProcessLumi();
1810 assert(indexIntoFileIter_ != indexIntoFileEnd_);
1811 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi);
1812
1813 if (!lumiTree_.isValid()) {
1814 ++indexIntoFileIter_;
1815 return shouldProcessLumi;
1816 }
1817
1818 if (shouldProcessLumi) {
1819 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
1820
1821 lumiTree_.insertEntryForIndex(0);
1822 auto history = processHistoryRegistry_->getMapped(lumiPrincipal.aux().processHistoryID());
1823 lumiPrincipal.fillLuminosityBlockPrincipal(history, lumiTree_.resetAndGetRootDelayedReader());
1824
1825 lumiPrincipal.readAllFromSourceAndMergeImmediately();
1826 lumiPrincipal.setShouldWriteLumi(LuminosityBlockPrincipal::kYes);
1827 } else {
1828 auto history = processHistoryRegistry_->getMapped(lumiPrincipal.aux().processHistoryID());
1829 lumiPrincipal.fillLuminosityBlockPrincipal(history, nullptr);
1830 if (lumiPrincipal.shouldWriteLumi() != LuminosityBlockPrincipal::kYes) {
1831 lumiPrincipal.setShouldWriteLumi(LuminosityBlockPrincipal::kNo);
1832 }
1833 }
1834 ++indexIntoFileIter_;
1835 return shouldProcessLumi;
1836 }
1837
1838 bool RootFile::setEntryAtEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) {
1839 indexIntoFileIter_ = indexIntoFile_.findEventPosition(run, lumi, event);
1840 if (indexIntoFileIter_ == indexIntoFileEnd_)
1841 return false;
1842 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
1843 return true;
1844 }
1845
1846 bool RootFile::setEntryAtLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) {
1847 indexIntoFileIter_ = indexIntoFile_.findLumiPosition(run, lumi);
1848 if (indexIntoFileIter_ == indexIntoFileEnd_)
1849 return false;
1850 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
1851 return true;
1852 }
1853
1854 bool RootFile::setEntryAtRun(RunNumber_t run) {
1855 indexIntoFileIter_ = indexIntoFile_.findRunPosition(run);
1856 if (indexIntoFileIter_ == indexIntoFileEnd_)
1857 return false;
1858 runTree_.setEntryNumber(indexIntoFileIter_.entry());
1859 return true;
1860 }
1861
1862 bool RootFile::setEntryAtNextEventInLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) {
1863 if (indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent) {
1864 ++indexIntoFileIter_;
1865 }
1866 indexIntoFileIter_.advanceToEvent();
1867 if (indexIntoFileIter_.getEntryType() != IndexIntoFile::kEvent)
1868 return false;
1869 if (run != indexIntoFileIter_.run())
1870 return false;
1871 if (lumi != indexIntoFileIter_.lumi())
1872 return false;
1873
1874
1875 fillEventAuxiliary(indexIntoFileIter_.entry());
1876 return true;
1877 }
1878
1879 void RootFile::readEventHistoryTree() {
1880
1881 if (fileFormatVersion().eventHistoryTree()) {
1882 history_ = std::make_unique<History>();
1883 eventHistoryTree_ = dynamic_cast<TTree*>(filePtr_->Get(poolNames::eventHistoryTreeName().c_str()));
1884 if (!eventHistoryTree_) {
1885 throw Exception(errors::EventCorruption) << "Failed to find the event history tree.\n";
1886 }
1887 }
1888 }
1889
1890 void RootFile::initializeDuplicateChecker(
1891 std::vector<std::shared_ptr<IndexIntoFile>> const& indexesIntoFiles,
1892 std::vector<std::shared_ptr<IndexIntoFile>>::size_type currentIndexIntoFile) {
1893 if (duplicateChecker_ && !duplicateChecker_->checkDisabled()) {
1894 if (eventTree_.next()) {
1895 auto const evtAux = fillThisEventAuxiliary();
1896
1897 duplicateChecker_->inputFileOpened(evtAux.isRealData(), indexIntoFile_, indexesIntoFiles, currentIndexIntoFile);
1898 }
1899 eventTree_.setEntryNumber(IndexIntoFile::invalidEntry);
1900 }
1901 }
1902
1903 void RootFile::setPresenceInProductRegistry(ProductRegistry& inputProdDescReg,
1904 StoredProcessBlockHelper const& storedProcessBlockHelper) {
1905
1906
1907
1908
1909 ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
1910 for (auto& product : pList) {
1911 BranchDescription& prod = product.second;
1912
1913
1914
1915
1916 prod.initBranchName();
1917 if (prod.branchType() == InProcess) {
1918 std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
1919 auto it = std::find(processes.begin(), processes.end(), prod.processName());
1920 if (it != processes.end()) {
1921 auto index = std::distance(processes.begin(), it);
1922 processBlockTrees_[index]->setPresence(prod, newBranchToOldBranch(prod.branchName()));
1923 } else {
1924
1925
1926 prod.setDropped(true);
1927 }
1928 } else {
1929 treePointers_[prod.branchType()]->setPresence(prod, newBranchToOldBranch(prod.branchName()));
1930 }
1931 if (prod.present()) {
1932 prod.initFromDictionary();
1933 }
1934 }
1935 }
1936
1937 void RootFile::markBranchToBeDropped(bool dropDescendants,
1938 BranchDescription const& branch,
1939 std::set<BranchID>& branchesToDrop,
1940 std::map<BranchID, BranchID> const& droppedToKeptAlias) const {
1941 if (dropDescendants) {
1942 branchChildren_->appendToDescendants(branch, branchesToDrop, droppedToKeptAlias);
1943 } else {
1944 branchesToDrop.insert(branch.branchID());
1945 }
1946 }
1947
1948 void RootFile::dropOnInputAndReorder(ProductRegistry& reg,
1949 ProductSelectorRules const& rules,
1950 bool dropDescendants,
1951 InputType inputType,
1952 StoredProcessBlockHelper& storedProcessBlockHelper,
1953 ProcessBlockHelper const* processBlockHelper) {
1954 ProductRegistry::ProductList& prodList = reg.productListUpdator();
1955
1956
1957
1958 std::map<BranchID, BranchID> droppedToKeptAlias;
1959 for (auto const& product : prodList) {
1960 BranchDescription const& prod = product.second;
1961 if (prod.branchID() != prod.originalBranchID() && prod.present()) {
1962 droppedToKeptAlias[prod.originalBranchID()] = prod.branchID();
1963 }
1964 }
1965
1966
1967
1968 ProductSelector productSelector;
1969 productSelector.initialize(rules, reg.allBranchDescriptions());
1970
1971
1972
1973 std::set<BranchID> branchesToDrop;
1974 std::vector<BranchDescription const*> associationDescriptions;
1975 for (auto const& product : prodList) {
1976 BranchDescription const& prod = product.second;
1977 if (inputType != InputType::Primary && prod.branchType() == InProcess) {
1978 markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1979 } else if (prod.unwrappedType() == typeid(ThinnedAssociation) && prod.present()) {
1980
1981 if (inputType != InputType::SecondarySource) {
1982 associationDescriptions.push_back(&prod);
1983 } else {
1984 markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1985 }
1986 } else if (!productSelector.selected(prod)) {
1987 markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1988 }
1989 }
1990
1991 if (inputType != InputType::SecondarySource) {
1992
1993
1994
1995
1996
1997
1998
1999 std::set<BranchID> keptProductsInEvent;
2000 for (auto const& product : prodList) {
2001 BranchDescription const& prod = product.second;
2002 if (branchesToDrop.find(prod.branchID()) == branchesToDrop.end() && prod.present() &&
2003 prod.branchType() == InEvent) {
2004 keptProductsInEvent.insert(prod.branchID());
2005 }
2006 }
2007
2008
2009 std::map<BranchID, bool> keepAssociation;
2010 fileThinnedAssociationsHelper_->selectAssociationProducts(
2011 associationDescriptions, keptProductsInEvent, keepAssociation);
2012
2013 for (auto association : associationDescriptions) {
2014 if (!keepAssociation[association->branchID()]) {
2015 markBranchToBeDropped(dropDescendants, *association, branchesToDrop, droppedToKeptAlias);
2016 }
2017 }
2018
2019
2020 auto temp = std::make_unique<ThinnedAssociationsHelper>();
2021 for (auto const& associationBranches : fileThinnedAssociationsHelper_->data()) {
2022 auto iter = keepAssociation.find(associationBranches.association());
2023 if (iter != keepAssociation.end() && iter->second) {
2024 temp->addAssociation(associationBranches);
2025 }
2026 }
2027
2028 fileThinnedAssociationsHelper_ = std::unique_ptr<ThinnedAssociationsHelper>(temp.release());
2029 }
2030
2031
2032 std::set<std::string> processesWithKeptProcessBlockProducts;
2033 std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
2034 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
2035 BranchDescription const& prod = it->second;
2036 bool drop = branchesToDrop.find(prod.branchID()) != branchesToDropEnd;
2037 if (drop) {
2038 if (!prod.dropped()) {
2039 if (productSelector.selected(prod) && prod.unwrappedType() != typeid(ThinnedAssociation) &&
2040 prod.branchType() != InProcess) {
2041 LogWarning("RootFile") << "Branch '" << prod.branchName() << "' is being dropped from the input\n"
2042 << "of file '" << file_ << "' because it is dependent on a branch\n"
2043 << "that was explicitly dropped.\n";
2044 }
2045 if (prod.branchType() == InProcess) {
2046 std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
2047 auto it = std::find(processes.begin(), processes.end(), prod.processName());
2048 assert(it != processes.end());
2049 auto index = std::distance(processes.begin(), it);
2050 processBlockTrees_[index]->dropBranch(newBranchToOldBranch(prod.branchName()));
2051 } else {
2052 treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
2053 }
2054 hasNewlyDroppedBranch_[prod.branchType()] = true;
2055 }
2056 ProductRegistry::ProductList::iterator icopy = it;
2057 ++it;
2058 prodList.erase(icopy);
2059 } else {
2060 if (prod.branchType() == InProcess && prod.present()) {
2061 processesWithKeptProcessBlockProducts.insert(prod.processName());
2062 }
2063 ++it;
2064 }
2065 }
2066
2067 dropProcessesAndReorder(storedProcessBlockHelper, processesWithKeptProcessBlockProducts, processBlockHelper);
2068
2069
2070 if (inputType == InputType::SecondaryFile) {
2071 TString tString;
2072 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
2073 BranchDescription const& prod = it->second;
2074 if (prod.present() and prod.branchType() != InEvent and prod.branchType() != InProcess) {
2075 TClass* cp = prod.wrappedType().getClass();
2076 void* p = cp->New();
2077 int offset = cp->GetBaseClassOffset(edProductClass_);
2078 std::unique_ptr<WrapperBase> edp = getWrapperBasePtr(p, offset);
2079 if (edp->isMergeable()) {
2080 treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
2081 ProductRegistry::ProductList::iterator icopy = it;
2082 ++it;
2083 prodList.erase(icopy);
2084 } else {
2085 ++it;
2086 }
2087 } else
2088 ++it;
2089 }
2090 }
2091 }
2092
2093 void RootFile::dropProcessesAndReorder(StoredProcessBlockHelper& storedProcessBlockHelper,
2094 std::set<std::string> const& processesWithKeptProcessBlockProducts,
2095 ProcessBlockHelper const* processBlockHelper) {
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108 if (processBlockTrees_.empty()) {
2109 return;
2110 }
2111
2112 std::vector<unsigned int> nEntries;
2113 nEntries.reserve(processBlockTrees_.size());
2114 for (auto const& processBlockTree : processBlockTrees_) {
2115 nEntries.push_back(processBlockTree->entries());
2116 }
2117
2118 bool firstInputFile = !processBlockHelper->initializedFromInput();
2119 bool isModified = false;
2120 std::vector<unsigned int> finalIndexToStoredIndex;
2121
2122 if (firstInputFile) {
2123 isModified = processBlockHelper->firstFileDropProcessesAndReorderStored(
2124 storedProcessBlockHelper, processesWithKeptProcessBlockProducts, nEntries, finalIndexToStoredIndex);
2125 } else {
2126 isModified =
2127 processBlockHelper->dropProcessesAndReorderStored(storedProcessBlockHelper,
2128 processesWithKeptProcessBlockProducts,
2129 nEntries,
2130 finalIndexToStoredIndex,
2131 processBlockHelper->processesWithProcessBlockProducts());
2132 }
2133
2134
2135
2136
2137 if (isModified) {
2138 std::vector<edm::propagate_const<std::unique_ptr<RootTree>>> newProcessBlockTrees;
2139 unsigned int nFinalProducts = storedProcessBlockHelper.processesWithProcessBlockProducts().size();
2140 for (unsigned int j = 0; j < nFinalProducts; ++j) {
2141 unsigned int iStored = finalIndexToStoredIndex[j];
2142 newProcessBlockTrees.push_back(std::move(processBlockTrees_[iStored]));
2143 }
2144 processBlockTrees_.swap(newProcessBlockTrees);
2145 }
2146 }
2147
2148 void RootFile::setSignals(
2149 signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* preEventReadSource,
2150 signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* postEventReadSource) {
2151 eventTree_.setSignals(preEventReadSource, postEventReadSource);
2152 }
2153
2154 void RootFile::makeProcessBlockRootTrees(std::shared_ptr<InputFile> filePtr,
2155 int treeMaxVirtualSize,
2156 bool enablePrefetching,
2157 InputType inputType,
2158 StoredProcessBlockHelper const& storedProcessBlockHelper) {
2159
2160
2161
2162
2163
2164
2165 for (auto const& process : storedProcessBlockHelper.processesWithProcessBlockProducts()) {
2166 processBlockTrees_.emplace_back(std::make_unique<RootTree>(filePtr,
2167 InProcess,
2168 process,
2169 1,
2170 treeMaxVirtualSize,
2171 roottree::defaultNonEventCacheSize,
2172 roottree::defaultNonEventLearningEntries,
2173 enablePrefetching,
2174 inputType));
2175 }
2176 }
2177
2178 std::unique_ptr<MakeProvenanceReader> RootFile::makeProvenanceReaderMaker(InputType inputType) {
2179 if (fileFormatVersion_.storedProductProvenanceUsed()) {
2180 readParentageTree(inputType);
2181 return std::make_unique<MakeReducedProvenanceReader>(parentageIDLookup_);
2182 } else if (fileFormatVersion_.splitProductIDs()) {
2183 readParentageTree(inputType);
2184 return std::make_unique<MakeFullProvenanceReader>();
2185 } else if (fileFormatVersion_.perEventProductIDs()) {
2186 auto entryDescriptionMap = std::make_unique<EntryDescriptionMap>();
2187 readEntryDescriptionTree(*entryDescriptionMap, inputType);
2188 return std::make_unique<MakeOldProvenanceReader>(std::move(entryDescriptionMap));
2189 } else {
2190 return std::make_unique<MakeDummyProvenanceReader>();
2191 }
2192 }
2193
2194 std::shared_ptr<ProductProvenanceRetriever> RootFile::makeProductProvenanceRetriever(unsigned int iStreamID) {
2195 if (eventProductProvenanceRetrievers_.size() <= iStreamID) {
2196 eventProductProvenanceRetrievers_.resize(iStreamID + 1);
2197 }
2198 if (!eventProductProvenanceRetrievers_[iStreamID]) {
2199
2200 eventProductProvenanceRetrievers_[iStreamID] = std::make_shared<ProductProvenanceRetriever>(
2201 provenanceReaderMaker_->makeReader(eventTree_, daqProvenanceHelper_.get()));
2202 }
2203 eventProductProvenanceRetrievers_[iStreamID]->reset();
2204 return eventProductProvenanceRetriever(iStreamID);
2205 }
2206
2207 class ReducedProvenanceReader : public ProvenanceReaderBase {
2208 public:
2209 ReducedProvenanceReader(RootTree* iRootTree,
2210 std::vector<ParentageID> const& iParentageIDLookup,
2211 DaqProvenanceHelper const* daqProvenanceHelper);
2212
2213 std::set<ProductProvenance> readProvenance(unsigned int) const override;
2214
2215 private:
2216 void readProvenanceAsync(WaitingTaskHolder task,
2217 ModuleCallingContext const* moduleCallingContext,
2218 unsigned int transitionIndex,
2219 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept override;
2220
2221 edm::propagate_const<RootTree*> rootTree_;
2222 edm::propagate_const<TBranch*> provBranch_;
2223 StoredProductProvenanceVector provVector_;
2224 StoredProductProvenanceVector const* pProvVector_;
2225 std::vector<ParentageID> const& parentageIDLookup_;
2226 DaqProvenanceHelper const* daqProvenanceHelper_;
2227 std::shared_ptr<std::recursive_mutex> mutex_;
2228 SharedResourcesAcquirer acquirer_;
2229 };
2230
2231 ReducedProvenanceReader::ReducedProvenanceReader(RootTree* iRootTree,
2232 std::vector<ParentageID> const& iParentageIDLookup,
2233 DaqProvenanceHelper const* daqProvenanceHelper)
2234 : ProvenanceReaderBase(),
2235 rootTree_(iRootTree),
2236 pProvVector_(&provVector_),
2237 parentageIDLookup_(iParentageIDLookup),
2238 daqProvenanceHelper_(daqProvenanceHelper),
2239 mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2240 acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {
2241 provBranch_ =
2242 rootTree_->tree()->GetBranch(BranchTypeToProductProvenanceBranchName(rootTree_->branchType()).c_str());
2243 }
2244
2245 namespace {
2246 using SignalType = signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)>;
2247 template <typename R>
2248 void readProvenanceAsyncImpl(R const* iThis,
2249 SerialTaskQueueChain& chain,
2250 WaitingTaskHolder task,
2251 unsigned int transitionIndex,
2252 std::atomic<const std::set<ProductProvenance>*>& writeTo,
2253 ModuleCallingContext const* iContext,
2254 SignalType const* pre,
2255 SignalType const* post) {
2256 if (nullptr == writeTo.load()) {
2257
2258 WaitingTaskHolder taskHolder{task};
2259 auto pWriteTo = &writeTo;
2260
2261 auto serviceToken = ServiceRegistry::instance().presentToken();
2262
2263 chain.push(
2264 *taskHolder.group(),
2265 [holder = std::move(taskHolder),
2266 pWriteTo,
2267 iThis,
2268 transitionIndex,
2269 iContext,
2270 pre,
2271 post,
2272 serviceToken]() mutable {
2273 if (nullptr == pWriteTo->load()) {
2274 ServiceRegistry::Operate operate(serviceToken);
2275 std::unique_ptr<const std::set<ProductProvenance>> prov;
2276 try {
2277 if (pre) {
2278 pre->emit(*(iContext->getStreamContext()), *iContext);
2279 }
2280 prov = std::make_unique<const std::set<ProductProvenance>>(iThis->readProvenance(transitionIndex));
2281 if (post) {
2282 post->emit(*(iContext->getStreamContext()), *iContext);
2283 }
2284
2285 } catch (...) {
2286 if (post) {
2287 post->emit(*(iContext->getStreamContext()), *iContext);
2288 }
2289
2290 holder.doneWaiting(std::current_exception());
2291 return;
2292 }
2293 const std::set<ProductProvenance>* expected = nullptr;
2294
2295 if (pWriteTo->compare_exchange_strong(expected, prov.get())) {
2296 prov.release();
2297 }
2298 }
2299 holder.doneWaiting(std::exception_ptr());
2300 });
2301 }
2302 }
2303 }
2304
2305 void ReducedProvenanceReader::readProvenanceAsync(
2306 WaitingTaskHolder task,
2307 ModuleCallingContext const* moduleCallingContext,
2308 unsigned int transitionIndex,
2309 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept {
2310 readProvenanceAsyncImpl(this,
2311 acquirer_.serialQueueChain(),
2312 task,
2313 transitionIndex,
2314 writeTo,
2315 moduleCallingContext,
2316 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2317 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2318 }
2319
2320 std::set<ProductProvenance> ReducedProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2321 {
2322 std::lock_guard<std::recursive_mutex> guard(*mutex_);
2323 ReducedProvenanceReader* me = const_cast<ReducedProvenanceReader*>(this);
2324 me->rootTree_->fillBranchEntry(
2325 me->provBranch_, me->rootTree_->entryNumberForIndex(transitionIndex), me->pProvVector_);
2326 }
2327 std::set<ProductProvenance> retValue;
2328 if (daqProvenanceHelper_) {
2329 for (auto const& prov : provVector_) {
2330 BranchID bid(prov.branchID_);
2331 retValue.emplace(daqProvenanceHelper_->mapBranchID(BranchID(prov.branchID_)),
2332 daqProvenanceHelper_->mapParentageID(parentageIDLookup_[prov.parentageIDIndex_]));
2333 }
2334 } else {
2335 for (auto const& prov : provVector_) {
2336 if (prov.parentageIDIndex_ >= parentageIDLookup_.size()) {
2337 throw edm::Exception(errors::LogicError)
2338 << "ReducedProvenanceReader::ReadProvenance\n"
2339 << "The parentage ID index value " << prov.parentageIDIndex_
2340 << " is out of bounds. The maximum value is " << parentageIDLookup_.size() - 1 << ".\n"
2341 << "This should never happen.\n"
2342 << "Please report this to the framework developers.";
2343 }
2344 retValue.emplace(BranchID(prov.branchID_), parentageIDLookup_[prov.parentageIDIndex_]);
2345 }
2346 }
2347 return retValue;
2348 }
2349
2350 class FullProvenanceReader : public ProvenanceReaderBase {
2351 public:
2352 explicit FullProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper);
2353 ~FullProvenanceReader() override {}
2354 std::set<ProductProvenance> readProvenance(unsigned int transitionIndex) const override;
2355
2356 private:
2357 void readProvenanceAsync(WaitingTaskHolder task,
2358 ModuleCallingContext const* moduleCallingContext,
2359 unsigned int transitionIndex,
2360 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept override;
2361
2362 RootTree* rootTree_;
2363 ProductProvenanceVector infoVector_;
2364
2365 CMS_SA_ALLOW mutable ProductProvenanceVector* pInfoVector_;
2366 DaqProvenanceHelper const* daqProvenanceHelper_;
2367 std::shared_ptr<std::recursive_mutex> mutex_;
2368 SharedResourcesAcquirer acquirer_;
2369 };
2370
2371 FullProvenanceReader::FullProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper)
2372 : ProvenanceReaderBase(),
2373 rootTree_(rootTree),
2374 infoVector_(),
2375 pInfoVector_(&infoVector_),
2376 daqProvenanceHelper_(daqProvenanceHelper),
2377 mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2378 acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {}
2379
2380 void FullProvenanceReader::readProvenanceAsync(
2381 WaitingTaskHolder task,
2382 ModuleCallingContext const* moduleCallingContext,
2383 unsigned int transitionIndex,
2384 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept {
2385 readProvenanceAsyncImpl(this,
2386 acquirer_.serialQueueChain(),
2387 task,
2388 transitionIndex,
2389 writeTo,
2390 moduleCallingContext,
2391 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2392 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2393 }
2394
2395 std::set<ProductProvenance> FullProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2396 {
2397 std::lock_guard<std::recursive_mutex> guard(*mutex_);
2398 rootTree_->fillBranchEntryMeta(
2399 rootTree_->branchEntryInfoBranch(), rootTree_->entryNumberForIndex(transitionIndex), pInfoVector_);
2400 }
2401 std::set<ProductProvenance> retValue;
2402 if (daqProvenanceHelper_) {
2403 for (auto const& info : infoVector_) {
2404 retValue.emplace(daqProvenanceHelper_->mapBranchID(info.branchID()),
2405 daqProvenanceHelper_->mapParentageID(info.parentageID()));
2406 }
2407 } else {
2408 for (auto const& info : infoVector_) {
2409 retValue.emplace(info);
2410 }
2411 }
2412 return retValue;
2413 }
2414
2415 class OldProvenanceReader : public ProvenanceReaderBase {
2416 public:
2417 explicit OldProvenanceReader(RootTree* rootTree,
2418 EntryDescriptionMap const& theMap,
2419 DaqProvenanceHelper const* daqProvenanceHelper);
2420 ~OldProvenanceReader() override {}
2421 std::set<ProductProvenance> readProvenance(unsigned int transitionIndex) const override;
2422
2423 private:
2424 void readProvenanceAsync(WaitingTaskHolder task,
2425 ModuleCallingContext const* moduleCallingContext,
2426 unsigned int transitionIndex,
2427 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept override;
2428
2429 edm::propagate_const<RootTree*> rootTree_;
2430 std::vector<EventEntryInfo> infoVector_;
2431
2432 CMS_SA_ALLOW mutable std::vector<EventEntryInfo>* pInfoVector_;
2433 EntryDescriptionMap const& entryDescriptionMap_;
2434 DaqProvenanceHelper const* daqProvenanceHelper_;
2435 std::shared_ptr<std::recursive_mutex> mutex_;
2436 SharedResourcesAcquirer acquirer_;
2437 };
2438
2439 OldProvenanceReader::OldProvenanceReader(RootTree* rootTree,
2440 EntryDescriptionMap const& theMap,
2441 DaqProvenanceHelper const* daqProvenanceHelper)
2442 : ProvenanceReaderBase(),
2443 rootTree_(rootTree),
2444 infoVector_(),
2445 pInfoVector_(&infoVector_),
2446 entryDescriptionMap_(theMap),
2447 daqProvenanceHelper_(daqProvenanceHelper),
2448 mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2449 acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {}
2450
2451 void OldProvenanceReader::readProvenanceAsync(
2452 WaitingTaskHolder task,
2453 ModuleCallingContext const* moduleCallingContext,
2454 unsigned int transitionIndex,
2455 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept {
2456 readProvenanceAsyncImpl(this,
2457 acquirer_.serialQueueChain(),
2458 task,
2459 transitionIndex,
2460 writeTo,
2461 moduleCallingContext,
2462 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2463 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2464 }
2465
2466 std::set<ProductProvenance> OldProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2467 {
2468 std::lock_guard<std::recursive_mutex> guard(*mutex_);
2469 rootTree_->branchEntryInfoBranch()->SetAddress(&pInfoVector_);
2470 roottree::getEntry(rootTree_->branchEntryInfoBranch(), rootTree_->entryNumberForIndex(transitionIndex));
2471 }
2472 std::set<ProductProvenance> retValue;
2473 for (auto const& info : infoVector_) {
2474 EntryDescriptionMap::const_iterator iter = entryDescriptionMap_.find(info.entryDescriptionID());
2475 assert(iter != entryDescriptionMap_.end());
2476 Parentage parentage(iter->second.parents());
2477 if (daqProvenanceHelper_) {
2478 retValue.emplace(daqProvenanceHelper_->mapBranchID(info.branchID()),
2479 daqProvenanceHelper_->mapParentageID(parentage.id()));
2480 } else {
2481 retValue.emplace(info.branchID(), parentage.id());
2482 }
2483 }
2484 return retValue;
2485 }
2486
2487 class DummyProvenanceReader : public ProvenanceReaderBase {
2488 public:
2489 DummyProvenanceReader();
2490 ~DummyProvenanceReader() override {}
2491
2492 private:
2493 std::set<ProductProvenance> readProvenance(unsigned int) const override;
2494 void readProvenanceAsync(WaitingTaskHolder task,
2495 ModuleCallingContext const* moduleCallingContext,
2496 unsigned int transitionIndex,
2497 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept override;
2498 };
2499
2500 DummyProvenanceReader::DummyProvenanceReader() : ProvenanceReaderBase() {}
2501
2502 std::set<ProductProvenance> DummyProvenanceReader::readProvenance(unsigned int) const {
2503
2504 return std::set<ProductProvenance>{};
2505 }
2506 void DummyProvenanceReader::readProvenanceAsync(
2507 WaitingTaskHolder task,
2508 ModuleCallingContext const* moduleCallingContext,
2509 unsigned int transitionIndex,
2510 std::atomic<const std::set<ProductProvenance>*>& writeTo) const noexcept {
2511 if (nullptr == writeTo.load()) {
2512 auto emptyProv = std::make_unique<const std::set<ProductProvenance>>();
2513 const std::set<ProductProvenance>* expected = nullptr;
2514 if (writeTo.compare_exchange_strong(expected, emptyProv.get())) {
2515 emptyProv.release();
2516 }
2517 }
2518 }
2519
2520 std::unique_ptr<ProvenanceReaderBase> MakeDummyProvenanceReader::makeReader(RootTree&,
2521 DaqProvenanceHelper const*) const {
2522 return std::make_unique<DummyProvenanceReader>();
2523 }
2524
2525 std::unique_ptr<ProvenanceReaderBase> MakeOldProvenanceReader::makeReader(
2526 RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2527 return std::make_unique<OldProvenanceReader>(&rootTree, *entryDescriptionMap_, daqProvenanceHelper);
2528 }
2529
2530 std::unique_ptr<ProvenanceReaderBase> MakeFullProvenanceReader::makeReader(
2531 RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2532 return std::make_unique<FullProvenanceReader>(&rootTree, daqProvenanceHelper);
2533 }
2534
2535 std::unique_ptr<ProvenanceReaderBase> MakeReducedProvenanceReader::makeReader(
2536 RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2537 return std::make_unique<ReducedProvenanceReader>(&rootTree, parentageIDLookup_, daqProvenanceHelper);
2538 }
2539 }