64 #include "TTreeCache.h"
104 void checkReleaseVersion(std::vector<ProcessHistory> processHistoryVector,
std::string const&
fileName) {
107 for (
auto const& ph : processHistoryVector) {
108 for (
auto const& pc : ph) {
112 <<
"a release (" << pc.releaseVersion() <<
") used in writing the input file, " <<
fileName <<
".\n"
113 <<
"Forward compatibility cannot be supported.\n";
133 return eventAux.
event();
144 std::shared_ptr<InputFile> filePtr,
145 std::shared_ptr<EventSkipperByID> eventSkipperByID,
150 unsigned int treeCacheSize,
151 int treeMaxVirtualSize,
157 std::shared_ptr<BranchIDListHelper> branchIDListHelper,
158 std::shared_ptr<ThinnedAssociationsHelper> thinnedAssociationsHelper,
159 std::vector<BranchID>
const* associationsFromSecondary,
160 std::shared_ptr<DuplicateChecker> duplicateChecker,
161 bool dropDescendants,
163 std::vector<std::shared_ptr<IndexIntoFile>>
const& indexesIntoFiles,
165 std::vector<ProcessHistoryID>& orderedProcessHistoryIDs,
166 bool bypassVersionCheck,
167 bool labelRawDataLikeMC,
169 bool enablePrefetching,
170 bool enforceGUIDInFileName)
172 logicalFile_(logicalFileName),
173 processConfiguration_(processConfiguration),
174 processHistoryRegistry_(&processHistoryRegistry),
176 eventSkipperByID_(eventSkipperByID),
177 fileFormatVersion_(),
180 indexIntoFile_(*indexIntoFileSharedPtr_),
181 orderedProcessHistoryIDs_(orderedProcessHistoryIDs),
184 indexIntoFileEnd_(indexIntoFileBegin_),
185 indexIntoFileIter_(indexIntoFileBegin_),
188 eventProcessHistoryIDs_(),
189 eventProcessHistoryIter_(eventProcessHistoryIDs_.begin()),
190 savedRunAuxiliary_(),
191 skipAnyEvents_(skipAnyEvents),
193 enforceGUIDInFileName_(enforceGUIDInFileName),
194 whyNotFastClonable_(0),
195 hasNewlyDroppedBranch_(),
196 branchListIndexesUnchanged_(
false),
226 branchIDListHelper_(branchIDListHelper),
227 fileThinnedAssociationsHelper_(),
228 thinnedAssociationsHelper_(thinnedAssociationsHelper),
230 runHelper_(runHelper),
231 newBranchToOldBranch_(),
232 eventHistoryTree_(nullptr),
235 duplicateChecker_(duplicateChecker),
236 provenanceAdaptor_(),
237 provenanceReaderMaker_(),
238 eventProductProvenanceRetrievers_(),
239 parentageIDLookup_(),
240 daqProvenanceHelper_(),
241 edProductClass_(
TypeWithDict::byName(
"edm::WrapperBase").getClass()),
242 inputType_(inputType) {
253 if (
nullptr == metaDataTree.get()) {
264 fft->SetAddress(&fftPtr);
293 typedef std::map<ParameterSetID, ParameterSetBlob> PsetMap;
295 PsetMap* psetMapPtr = &psetMap;
304 if (
nullptr == psetTree.get()) {
309 typedef std::pair<ParameterSetID, ParameterSetBlob> IdToBlobs;
311 IdToBlobs* pIdToBlob = &idToBlob;
314 std::unique_ptr<TTreeCache> psetTreeCache =
316 psetTreeCache->SetEnablePrefetching(
false);
317 filePtr_->SetCacheRead(psetTreeCache.get());
318 for (Long64_t
i = 0;
i != psetTree->GetEntries(); ++
i) {
319 psetTree->GetEntry(
i);
320 psetMap.insert(idToBlob);
345 auto branchIDListsAPtr = std::make_unique<BranchIDLists>();
353 std::make_unique<ThinnedAssociationsHelper>();
357 &thinnedAssociationsHelperPtr);
394 for (
auto const& psetEntry : psetMap) {
396 pset.setID(psetEntry.first);
407 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter,
true);
415 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter,
false);
427 <<
"Failed to find thinnedAssociationsHelper branch in metaData tree.\n";
431 if (!bypassVersionCheck) {
432 checkReleaseVersion(pHistVector,
file());
435 if (labelRawDataLikeMC) {
440 ProductRegistry::ProductList::iterator it = pList.lower_bound(
finder);
441 if (it != pList.end() && it->first.friendlyClassName() ==
rawData && it->first.moduleLabel() ==
source) {
457 it = pList.lower_bound(
finder);
458 assert(!(it != pList.end() && it->first.friendlyClassName() ==
rawData && it->first.moduleLabel() ==
source));
468 for (
auto const& history : pHistVector) {
502 for (
auto& product : pList) {
512 auto newReg = std::make_unique<ProductRegistry>();
517 for (
auto const& product : prodList) {
520 if (newFriendlyName ==
prod.friendlyClassName()) {
521 newReg->copyProduct(
prod);
525 <<
"Cannot change friendly class name algorithm without more development work\n"
526 <<
"to update BranchIDLists and ThinnedAssociationsHelper. Contact the framework group.\n";
530 newReg->copyProduct(newBD);
534 dropOnInput(*newReg, productSelectorRules, dropDescendants, inputType);
537 *associationsFromSecondary);
543 for (
auto& product : newReg->productListUpdator()) {
548 for (
auto& product : newReg->productListUpdator()) {
549 product.second.setOnDemand(
true);
561 std::array<size_t, NumBranchTypes> nBranches;
563 for (
auto const& product : prodList) {
564 ++nBranches[product.second.branchType()];
573 t->numberOfBranchesToAdd(nBranches[
i]);
577 for (
auto const& product : prodList) {
605 std::unique_ptr<TTree> entryDescriptionTree(
607 if (
nullptr == entryDescriptionTree.get()) {
625 if (idBuffer != entryDescriptionBuffer.
id()) {
628 entryDescriptionMap.insert(std::make_pair(entryDescriptionBuffer.
id(), entryDescriptionBuffer));
635 if (newID != oldID) {
652 if (
nullptr == parentageTree.get()) {
670 if (newID != oldID) {
808 eventAux.id().event(),
857 event = eventAux.
event();
884 struct RunItemSortByRun {
885 bool operator()(RunItem
const&
a, RunItem
const&
b)
const {
return a.run_ <
b.run_; }
887 struct RunItemSortByRunPhid {
888 bool operator()(RunItem
const&
a, RunItem
const&
b)
const {
889 return a.run_ <
b.run_ || (!(
b.run_ <
a.run_) &&
a.phid_ <
b.phid_);
900 firstEventEntry_(
entry),
901 lastEventEntry_(
entry == IndexIntoFile::invalidEntry ? IndexIntoFile::invalidEntry :
entry + 1) {}
908 struct LumiItemSortByRunLumi {
909 bool operator()(LumiItem
const&
a, LumiItem
const&
b)
const {
910 return a.run_ <
b.run_ || (!(
b.run_ <
a.run_) &&
a.lumi_ <
b.lumi_);
913 struct LumiItemSortByRunLumiPhid {
914 bool operator()(LumiItem
const&
a, LumiItem
const&
b)
const {
919 if (
a.lumi_ <
b.lumi_)
921 if (
b.lumi_ <
a.lumi_)
923 return a.phid_ <
b.phid_;
938 typedef std::list<LumiItem>
LumiList;
941 typedef std::set<LuminosityBlockID> RunLumiSet;
942 RunLumiSet runLumiSet;
944 typedef std::list<RunItem>
RunList;
947 typedef std::set<RunNumber_t> RunSet;
950 typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
951 RunItemSet runItemSet;
953 typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
969 bool newLumi =
false;
980 if (iFirst || prevPhid != reducedPHID || prevRun != evtAux.run()) {
982 newRun = newLumi =
true;
983 }
else if (prevLumi != evtAux.luminosityBlock()) {
986 prevPhid = reducedPHID;
987 prevRun = evtAux.run();
988 prevLumi = evtAux.luminosityBlock();
994 LumiItem& currentLumi =
lumis.back();
996 ++currentLumi.lastEventEntry_;
1000 RunItem
item(reducedPHID, evtAux.run());
1001 if (runItemSet.insert(
item).second) {
1003 runSet.insert(evtAux.run());
1004 phidMap.insert(std::make_pair(evtAux.run(), reducedPHID));
1014 typedef std::map<RunNumber_t, IndexIntoFile::EntryNumber_t> RunMap;
1017 typedef std::vector<RunItem> RunVector;
1018 RunVector emptyRuns;
1027 if (runSet.insert(runAux->run()).
second) {
1029 emptyRuns.emplace_back(reducedPHID, runAux->run());
1032 phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
1039 RunItemSortByRun runItemSortByRun;
1042 RunList::iterator itRuns =
runs.begin(), endRuns =
runs.end();
1043 for (
auto const& emptyRun : emptyRuns) {
1044 for (; itRuns != endRuns; ++itRuns) {
1045 if (runItemSortByRun(emptyRun, *itRuns)) {
1049 runs.insert(itRuns, emptyRun);
1054 typedef std::vector<LumiItem> LumiVector;
1055 LumiVector emptyLumis;
1057 typedef std::map<LuminosityBlockID, IndexIntoFile::EntryNumber_t> RunLumiMap;
1058 RunLumiMap runLumiMap;
1065 if (runLumiSet.insert(lumiID).second) {
1070 PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
1071 assert(iPhidMap != phidMap.end());
1072 emptyLumis.emplace_back(
1082 LumiItemSortByRunLumi lumiItemSortByRunLumi;
1085 LumiList::iterator itLumis =
lumis.begin(), endLumis =
lumis.end();
1086 for (
auto const& emptyLumi : emptyLumis) {
1087 for (; itLumis != endLumis; ++itLumis) {
1088 if (lumiItemSortByRunLumi(emptyLumi, *itLumis)) {
1092 lumis.insert(itLumis, emptyLumi);
1097 typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
1098 RunCountMap runCountMap;
1105 RunCountMap::const_iterator countMapItem = runCountMap.find(
run);
1106 if (countMapItem == runCountMap.end()) {
1107 countMapItem = runCountMap.insert(std::make_pair(
run, rcount)).first;
1108 assert(countMapItem != runCountMap.end());
1111 std::vector<ProcessHistoryID>::const_iterator phidItem =
find_in_all(phids,
run.phid_);
1112 if (phidItem == phids.end()) {
1113 phids.push_back(
run.phid_);
1114 phidItem = phids.end() - 1;
1116 entries.emplace_back(countMapItem->second,
1119 phidItem - phids.begin(),
1127 typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
1128 LumiCountMap lumiCountMap;
1131 RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(
lumi.phid_,
lumi.run_));
1132 assert(runCountMapItem != runCountMap.end());
1133 LumiCountMap::const_iterator countMapItem = lumiCountMap.find(
lumi);
1134 if (countMapItem == lumiCountMap.end()) {
1135 countMapItem = lumiCountMap.insert(std::make_pair(
lumi, lcount)).first;
1136 assert(countMapItem != lumiCountMap.end());
1139 std::vector<ProcessHistoryID>::const_iterator phidItem =
find_in_all(phids,
lumi.phid_);
1140 assert(phidItem != phids.end());
1141 entries.emplace_back(runCountMapItem->second,
1142 countMapItem->second,
1144 phidItem - phids.begin(),
1147 lumi.firstEventEntry_,
1148 lumi.lastEventEntry_);
1159 <<
"in the input file.\n";
1163 if (guidFromName !=
fid_.
fid()) {
1165 <<
"GUID " << guidFromName <<
" extracted from file name " <<
file_
1166 <<
" is inconsistent with the GUID read from the file " <<
fid_.
fid();
1171 if (
runTree().entries() > 0) {
1177 for (
auto& phid : phidVec) {
1191 std::shared_ptr<IndexIntoFile::EventFinder>(std::make_shared<RootFileEventFinder>(
eventTree_)));
1194 bool needEventNumbers =
false;
1195 bool needIndexesForDuplicateChecker =
1197 if (inputType !=
InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
1198 needEventNumbers =
true;
1200 bool needEventEntries =
false;
1203 needEventEntries =
true;
1219 if (treePointer ==
nullptr) {
1223 treePointer->close();
1224 treePointer =
nullptr;
1274 if (!eventHistoryBranch) {
1277 eventHistoryBranch->SetAddress(&pHistory);
1280 eventSelectionIDs.swap(
history_->eventSelectionIDs());
1281 branchListIndexes.swap(
history_->branchListIndexes());
1286 assert(eventSelectionIDBranch !=
nullptr);
1290 assert(branchListIndexesBranch !=
nullptr);
1295 for (
auto& esID : eventSelectionIDs) {
1312 auto lumiAuxiliary = std::make_shared<LuminosityBlockAuxiliary>();
1323 lumiAuxiliary->setProcessHistoryID(
provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
1326 lumiAuxiliary->setProcessHistoryID(
daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
1331 return lumiAuxiliary;
1335 auto runAuxiliary = std::make_shared<RunAuxiliary>();
1341 RunAux* pRunAux = &runAux;
1346 runAuxiliary->setProcessHistoryID(
provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
1349 runAuxiliary->setProcessHistoryID(
daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
1351 return runAuxiliary;
1362 phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1370 if (
eventSkipperByID_->skipIt(runOfSkippedEvent, lumiOfSkippedEvent, evtAux.id().event())) {
1377 phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, evtAux.id().event(),
file_)) {
1448 auto const& evtAux = principal.
aux();
1464 const_cast<EventID&>(evtAux.id()).setLuminosityBlockNumber(evtAux.oldLuminosityBlock());
1465 evtAux.resetObsoleteInfo();
1470 runHelper_->overrideRunNumber(evtAux.id(), evtAux.isRealData());
1486 : evtAux.processHistoryID());
1500 runHelper_->overrideRunNumber(runAuxiliary->id());
1501 return runAuxiliary;
1524 runHelper_->overrideRunNumber(runAuxiliary->id());
1525 filePtr_->reportInputRunNumber(runAuxiliary->run());
1544 runAuxiliary->setBeginTime(evtAux.time());
1555 runAuxiliary->setProcessHistoryID(evtAux.processHistoryID());
1560 return runAuxiliary;
1568 assert(entryNumber >= 0);
1569 mergeableRunProductMetadata->
readRun(
1602 return std::make_shared<LuminosityBlockAuxiliary>(
1610 runHelper_->overrideRunNumber(lumiAuxiliary->id());
1611 filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
1618 lumiAuxiliary->setBeginTime(evtAux.time());
1625 return lumiAuxiliary;
1691 history_ = std::make_unique<History>();
1700 std::vector<std::shared_ptr<IndexIntoFile>>
const& indexesIntoFiles,
1714 std::set<BranchID>& branchesToDrop,
1715 std::map<BranchID, BranchID>
const& droppedToKeptAlias)
const {
1716 if (dropDescendants) {
1719 branchesToDrop.insert(
branch.branchID());
1725 bool dropDescendants,
1731 std::vector<BranchDescription const*> associationDescriptions;
1735 std::set<BranchID> branchesToDrop;
1736 std::map<BranchID, BranchID> droppedToKeptAlias;
1737 for (
auto const& product : prodList) {
1739 if (
prod.branchID() !=
prod.originalBranchID() &&
prod.present()) {
1740 droppedToKeptAlias[
prod.originalBranchID()] =
prod.branchID();
1743 for (
auto const& product : prodList) {
1748 associationDescriptions.push_back(&
prod);
1765 std::set<BranchID> keptProductsInEvent;
1766 for (
auto const& product : prodList) {
1768 if (branchesToDrop.find(
prod.branchID()) == branchesToDrop.end() &&
prod.present() &&
1770 keptProductsInEvent.insert(
prod.branchID());
1775 std::map<BranchID, bool> keepAssociation;
1777 associationDescriptions, keptProductsInEvent, keepAssociation);
1779 for (
auto association : associationDescriptions) {
1786 auto temp = std::make_unique<ThinnedAssociationsHelper>();
1788 auto iter = keepAssociation.find(associationBranches.association());
1789 if (iter != keepAssociation.end() && iter->second) {
1790 temp->addAssociation(associationBranches);
1798 std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
1799 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1801 bool drop = branchesToDrop.find(
prod.branchID()) != branchesToDropEnd;
1803 if (!
prod.dropped()) {
1805 LogWarning(
"RootFile") <<
"Branch '" <<
prod.branchName() <<
"' is being dropped from the input\n"
1806 <<
"of file '" <<
file_ <<
"' because it is dependent on a branch\n"
1807 <<
"that was explicitly dropped.\n";
1815 ProductRegistry::ProductList::iterator icopy = it;
1817 prodList.erase(icopy);
1826 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1829 TClass*
cp =
prod.wrappedType().getClass();
1830 void*
p =
cp->New();
1833 if (edp->isMergeable()) {
1835 ProductRegistry::ProductList::iterator icopy = it;
1837 prodList.erase(icopy);
1859 return std::make_unique<MakeFullProvenanceReader>();
1861 auto entryDescriptionMap = std::make_unique<EntryDescriptionMap>();
1863 return std::make_unique<MakeOldProvenanceReader>(
std::move(entryDescriptionMap));
1865 return std::make_unique<MakeDummyProvenanceReader>();
1885 std::vector<ParentageID>
const& iParentageIDLookup,
1888 std::set<ProductProvenance>
readProvenance(
unsigned int)
const override;
1893 unsigned int transitionIndex,
1894 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
1902 std::shared_ptr<std::recursive_mutex>
mutex_;
1907 std::vector<ParentageID>
const& iParentageIDLookup,
1910 rootTree_(iRootTree),
1911 pProvVector_(&provVector_),
1912 parentageIDLookup_(iParentageIDLookup),
1913 daqProvenanceHelper_(daqProvenanceHelper),
1922 template <
typename R>
1923 void readProvenanceAsyncImpl(
R const* iThis,
1926 unsigned int transitionIndex,
1927 std::atomic<
const std::set<ProductProvenance>*>& writeTo,
1929 SignalType
const* pre,
1930 SignalType
const* post) {
1931 if (
nullptr == writeTo.load()) {
1934 auto pWriteTo = &writeTo;
1939 *taskHolder.group(),
1947 serviceToken]()
mutable {
1948 if (
nullptr == pWriteTo->load()) {
1950 std::unique_ptr<const std::set<ProductProvenance>> prov;
1953 pre->emit(*(iContext->getStreamContext()), *iContext);
1955 prov = std::make_unique<const std::set<ProductProvenance>>(iThis->readProvenance(transitionIndex));
1957 post->emit(*(iContext->getStreamContext()), *iContext);
1962 post->emit(*(iContext->getStreamContext()), *iContext);
1965 holder.doneWaiting(std::current_exception());
1968 const std::set<ProductProvenance>* expected =
nullptr;
1970 if (pWriteTo->compare_exchange_strong(expected, prov.get())) {
1974 holder.doneWaiting(std::exception_ptr());
1982 unsigned int transitionIndex,
1983 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
1984 readProvenanceAsyncImpl(
this,
1989 moduleCallingContext,
1990 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
1991 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
1996 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
1998 me->rootTree_->fillBranchEntry(
1999 me->provBranch_,
me->rootTree_->entryNumberForIndex(transitionIndex),
me->pProvVector_);
2001 std::set<ProductProvenance> retValue;
2012 <<
"ReducedProvenanceReader::ReadProvenance\n"
2013 <<
"The parentage ID index value " << prov.parentageIDIndex_
2014 <<
" is out of bounds. The maximum value is " <<
parentageIDLookup_.size() - 1 <<
".\n"
2015 <<
"This should never happen.\n"
2016 <<
"Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
2028 std::set<ProductProvenance>
readProvenance(
unsigned int transitionIndex)
const override;
2033 unsigned int transitionIndex,
2034 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2041 std::shared_ptr<std::recursive_mutex>
mutex_;
2047 rootTree_(rootTree),
2049 pInfoVector_(&infoVector_),
2050 daqProvenanceHelper_(daqProvenanceHelper),
2056 unsigned int transitionIndex,
2057 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2058 readProvenanceAsyncImpl(
this,
2063 moduleCallingContext,
2070 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
2074 std::set<ProductProvenance> retValue;
2082 retValue.emplace(
info);
2094 std::set<ProductProvenance>
readProvenance(
unsigned int transitionIndex)
const override;
2099 unsigned int transitionIndex,
2100 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2108 std::shared_ptr<std::recursive_mutex>
mutex_;
2116 rootTree_(rootTree),
2118 pInfoVector_(&infoVector_),
2119 entryDescriptionMap_(theMap),
2120 daqProvenanceHelper_(daqProvenanceHelper),
2126 unsigned int transitionIndex,
2127 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2128 readProvenanceAsyncImpl(
this,
2133 moduleCallingContext,
2134 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2135 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2140 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
2144 std::set<ProductProvenance> retValue;
2148 Parentage parentage(iter->second.parents());
2153 retValue.emplace(
info.branchID(), parentage.id());
2165 std::set<ProductProvenance>
readProvenance(
unsigned int)
const override;
2168 unsigned int transitionIndex,
2169 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2176 return std::set<ProductProvenance>{};
2180 unsigned int transitionIndex,
2181 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2182 if (
nullptr == writeTo.load()) {
2183 auto emptyProv = std::make_unique<const std::set<ProductProvenance>>();
2184 const std::set<ProductProvenance>* expected =
nullptr;
2185 if (writeTo.compare_exchange_strong(expected, emptyProv.get())) {
2186 emptyProv.release();
2193 return std::make_unique<DummyProvenanceReader>();
2198 return std::make_unique<OldProvenanceReader>(&rootTree, *
entryDescriptionMap_, daqProvenanceHelper);
2203 return std::make_unique<FullProvenanceReader>(&rootTree, daqProvenanceHelper);
2208 return std::make_unique<ReducedProvenanceReader>(&rootTree,
parentageIDLookup_, daqProvenanceHelper);