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),
233 eventSelectionIDs_(),
234 branchListIndexes_(),
237 duplicateChecker_(duplicateChecker),
238 provenanceAdaptor_(),
239 provenanceReaderMaker_(),
240 eventProductProvenanceRetrievers_(),
241 parentageIDLookup_(),
242 daqProvenanceHelper_(),
244 inputType_(inputType) {
255 if (
nullptr == metaDataTree.get()) {
266 fft->SetAddress(&fftPtr);
295 typedef std::map<ParameterSetID, ParameterSetBlob> PsetMap;
297 PsetMap* psetMapPtr = &psetMap;
306 if (
nullptr == psetTree.get()) {
311 typedef std::pair<ParameterSetID, ParameterSetBlob> IdToBlobs;
313 IdToBlobs* pIdToBlob = &idToBlob;
316 std::unique_ptr<TTreeCache> psetTreeCache =
318 psetTreeCache->SetEnablePrefetching(
false);
319 filePtr_->SetCacheRead(psetTreeCache.get());
320 for (Long64_t
i = 0;
i != psetTree->GetEntries(); ++
i) {
321 psetTree->GetEntry(
i);
322 psetMap.insert(idToBlob);
347 auto branchIDListsAPtr = std::make_unique<BranchIDLists>();
355 std::make_unique<ThinnedAssociationsHelper>();
359 &thinnedAssociationsHelperPtr);
396 for (
auto const& psetEntry : psetMap) {
398 pset.setID(psetEntry.first);
409 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter,
true);
417 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter,
false);
429 <<
"Failed to find thinnedAssociationsHelper branch in metaData tree.\n";
433 if (!bypassVersionCheck) {
434 checkReleaseVersion(pHistVector,
file());
437 if (labelRawDataLikeMC) {
442 ProductRegistry::ProductList::iterator it = pList.lower_bound(
finder);
443 if (it != pList.end() && it->first.friendlyClassName() ==
rawData && it->first.moduleLabel() ==
source) {
459 it = pList.lower_bound(
finder);
460 assert(!(it != pList.end() && it->first.friendlyClassName() ==
rawData && it->first.moduleLabel() ==
source));
470 for (
auto const& history : pHistVector) {
504 for (
auto& product : pList) {
514 auto newReg = std::make_unique<ProductRegistry>();
519 for (
auto const& product : prodList) {
522 if (newFriendlyName ==
prod.friendlyClassName()) {
523 newReg->copyProduct(
prod);
527 <<
"Cannot change friendly class name algorithm without more development work\n"
528 <<
"to update BranchIDLists and ThinnedAssociationsHelper. Contact the framework group.\n";
532 newReg->copyProduct(newBD);
536 dropOnInput(*newReg, productSelectorRules, dropDescendants, inputType);
539 *associationsFromSecondary);
545 for (
auto& product : newReg->productListUpdator()) {
559 std::array<size_t, NumBranchTypes> nBranches;
561 for (
auto const& product : prodList) {
562 ++nBranches[product.second.branchType()];
571 t->numberOfBranchesToAdd(nBranches[
i]);
575 for (
auto const& product : prodList) {
603 std::unique_ptr<TTree> entryDescriptionTree(
605 if (
nullptr == entryDescriptionTree.get()) {
623 if (idBuffer != entryDescriptionBuffer.
id()) {
626 entryDescriptionMap.insert(std::make_pair(entryDescriptionBuffer.
id(), entryDescriptionBuffer));
633 if (newID != oldID) {
650 if (
nullptr == parentageTree.get()) {
668 if (newID != oldID) {
861 itr.advanceToEvent();
871 itr.skipEventBackward(phIndex,
run,
lumi, eventEntry);
872 itr.skipEventBackward(phIndex,
run,
lumi, eventEntry);
882 struct RunItemSortByRun {
883 bool operator()(RunItem
const&
a, RunItem
const&
b)
const {
return a.run_ <
b.run_; }
885 struct RunItemSortByRunPhid {
886 bool operator()(RunItem
const&
a, RunItem
const&
b)
const {
887 return a.run_ <
b.run_ || (!(
b.run_ <
a.run_) &&
a.phid_ <
b.phid_);
898 firstEventEntry_(
entry),
899 lastEventEntry_(
entry == IndexIntoFile::invalidEntry ? IndexIntoFile::invalidEntry :
entry + 1) {}
906 struct LumiItemSortByRunLumi {
907 bool operator()(LumiItem
const&
a, LumiItem
const&
b)
const {
908 return a.run_ <
b.run_ || (!(
b.run_ <
a.run_) &&
a.lumi_ <
b.lumi_);
911 struct LumiItemSortByRunLumiPhid {
912 bool operator()(LumiItem
const&
a, LumiItem
const&
b)
const {
917 if (
a.lumi_ <
b.lumi_)
919 if (
b.lumi_ <
a.lumi_)
921 return a.phid_ <
b.phid_;
936 typedef std::list<LumiItem>
LumiList;
939 typedef std::set<LuminosityBlockID> RunLumiSet;
940 RunLumiSet runLumiSet;
942 typedef std::list<RunItem>
RunList;
945 typedef std::set<RunNumber_t> RunSet;
948 typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
949 RunItemSet runItemSet;
951 typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
965 bool newLumi =
false;
976 if (iFirst || prevPhid != reducedPHID || prevRun !=
eventAux().
run()) {
978 newRun = newLumi =
true;
979 }
else if (prevLumi !=
eventAux().luminosityBlock()) {
982 prevPhid = reducedPHID;
990 LumiItem& currentLumi =
lumis.back();
992 ++currentLumi.lastEventEntry_;
997 if (runItemSet.insert(
item).second) {
1000 phidMap.insert(std::make_pair(
eventAux().
run(), reducedPHID));
1011 typedef std::map<RunNumber_t, IndexIntoFile::EntryNumber_t> RunMap;
1014 typedef std::vector<RunItem> RunVector;
1015 RunVector emptyRuns;
1024 if (runSet.insert(runAux->run()).
second) {
1026 emptyRuns.emplace_back(reducedPHID, runAux->run());
1029 phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
1036 RunItemSortByRun runItemSortByRun;
1039 RunList::iterator itRuns =
runs.begin(), endRuns =
runs.end();
1040 for (
auto const& emptyRun : emptyRuns) {
1041 for (; itRuns != endRuns; ++itRuns) {
1042 if (runItemSortByRun(emptyRun, *itRuns)) {
1046 runs.insert(itRuns, emptyRun);
1051 typedef std::vector<LumiItem> LumiVector;
1052 LumiVector emptyLumis;
1054 typedef std::map<LuminosityBlockID, IndexIntoFile::EntryNumber_t> RunLumiMap;
1055 RunLumiMap runLumiMap;
1062 if (runLumiSet.insert(lumiID).second) {
1067 PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
1068 assert(iPhidMap != phidMap.end());
1069 emptyLumis.emplace_back(
1079 LumiItemSortByRunLumi lumiItemSortByRunLumi;
1082 LumiList::iterator itLumis =
lumis.begin(), endLumis =
lumis.end();
1083 for (
auto const& emptyLumi : emptyLumis) {
1084 for (; itLumis != endLumis; ++itLumis) {
1085 if (lumiItemSortByRunLumi(emptyLumi, *itLumis)) {
1089 lumis.insert(itLumis, emptyLumi);
1094 typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
1095 RunCountMap runCountMap;
1102 RunCountMap::const_iterator countMapItem = runCountMap.find(
run);
1103 if (countMapItem == runCountMap.end()) {
1104 countMapItem = runCountMap.insert(std::make_pair(
run, rcount)).first;
1105 assert(countMapItem != runCountMap.end());
1108 std::vector<ProcessHistoryID>::const_iterator phidItem =
find_in_all(phids,
run.phid_);
1109 if (phidItem == phids.end()) {
1110 phids.push_back(
run.phid_);
1111 phidItem = phids.end() - 1;
1113 entries.emplace_back(countMapItem->second,
1116 phidItem - phids.begin(),
1124 typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
1125 LumiCountMap lumiCountMap;
1128 RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(
lumi.phid_,
lumi.run_));
1129 assert(runCountMapItem != runCountMap.end());
1130 LumiCountMap::const_iterator countMapItem = lumiCountMap.find(
lumi);
1131 if (countMapItem == lumiCountMap.end()) {
1132 countMapItem = lumiCountMap.insert(std::make_pair(
lumi, lcount)).first;
1133 assert(countMapItem != lumiCountMap.end());
1136 std::vector<ProcessHistoryID>::const_iterator phidItem =
find_in_all(phids,
lumi.phid_);
1137 assert(phidItem != phids.end());
1138 entries.emplace_back(runCountMapItem->second,
1139 countMapItem->second,
1141 phidItem - phids.begin(),
1144 lumi.firstEventEntry_,
1145 lumi.lastEventEntry_);
1156 <<
"in the input file.\n";
1160 if (guidFromName !=
fid_.
fid()) {
1162 <<
"GUID " << guidFromName <<
" extracted from file name " <<
file_
1163 <<
" is inconsistent with the GUID read from the file " <<
fid_.
fid();
1168 if (
runTree().entries() > 0) {
1174 for (
auto& phid : phidVec) {
1188 std::shared_ptr<IndexIntoFile::EventFinder>(std::make_shared<RootFileEventFinder>(
eventTree_)));
1191 bool needEventNumbers =
false;
1192 bool needIndexesForDuplicateChecker =
1194 if (inputType !=
InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
1195 needEventNumbers =
true;
1197 bool needEventEntries =
false;
1200 needEventEntries =
true;
1216 if (treePointer ==
nullptr) {
1220 treePointer->close();
1221 treePointer =
nullptr;
1273 if (!eventHistoryBranch) {
1276 eventHistoryBranch->SetAddress(&pHistory);
1285 assert(eventSelectionIDBranch !=
nullptr);
1289 assert(branchListIndexesBranch !=
nullptr);
1311 auto lumiAuxiliary = std::make_shared<LuminosityBlockAuxiliary>();
1322 lumiAuxiliary->setProcessHistoryID(
provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
1325 lumiAuxiliary->setProcessHistoryID(
daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
1330 return lumiAuxiliary;
1334 auto runAuxiliary = std::make_shared<RunAuxiliary>();
1340 RunAux* pRunAux = &runAux;
1345 runAuxiliary->setProcessHistoryID(
provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
1348 runAuxiliary->setProcessHistoryID(
daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
1350 return runAuxiliary;
1361 phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1499 runHelper_->overrideRunNumber(runAuxiliary->id());
1500 return runAuxiliary;
1523 runHelper_->overrideRunNumber(runAuxiliary->id());
1524 filePtr_->reportInputRunNumber(runAuxiliary->run());
1552 runAuxiliary->setProcessHistoryID(
eventAux().processHistoryID());
1557 return runAuxiliary;
1565 assert(entryNumber >= 0);
1566 mergeableRunProductMetadata->
readRun(
1599 return std::make_shared<LuminosityBlockAuxiliary>(
1607 runHelper_->overrideRunNumber(lumiAuxiliary->id());
1608 filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
1622 return lumiAuxiliary;
1686 history_ = std::make_unique<History>();
1695 std::vector<std::shared_ptr<IndexIntoFile>>
const& indexesIntoFiles,
1709 std::set<BranchID>& branchesToDrop,
1710 std::map<BranchID, BranchID>
const& droppedToKeptAlias)
const {
1711 if (dropDescendants) {
1714 branchesToDrop.insert(
branch.branchID());
1720 bool dropDescendants,
1726 std::vector<BranchDescription const*> associationDescriptions;
1730 std::set<BranchID> branchesToDrop;
1731 std::map<BranchID, BranchID> droppedToKeptAlias;
1732 for (
auto const& product : prodList) {
1734 if (
prod.branchID() !=
prod.originalBranchID() &&
prod.present()) {
1735 droppedToKeptAlias[
prod.originalBranchID()] =
prod.branchID();
1738 for (
auto const& product : prodList) {
1743 associationDescriptions.push_back(&
prod);
1760 std::set<BranchID> keptProductsInEvent;
1761 for (
auto const& product : prodList) {
1763 if (branchesToDrop.find(
prod.branchID()) == branchesToDrop.end() &&
prod.present() &&
1765 keptProductsInEvent.insert(
prod.branchID());
1770 std::map<BranchID, bool> keepAssociation;
1772 associationDescriptions, keptProductsInEvent, keepAssociation);
1774 for (
auto association : associationDescriptions) {
1781 auto temp = std::make_unique<ThinnedAssociationsHelper>();
1783 auto iter = keepAssociation.find(associationBranches.association());
1784 if (iter != keepAssociation.end() && iter->second) {
1785 temp->addAssociation(associationBranches);
1793 std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
1794 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1796 bool drop = branchesToDrop.find(
prod.branchID()) != branchesToDropEnd;
1798 if (!
prod.dropped()) {
1800 LogWarning(
"RootFile") <<
"Branch '" <<
prod.branchName() <<
"' is being dropped from the input\n"
1801 <<
"of file '" <<
file_ <<
"' because it is dependent on a branch\n"
1802 <<
"that was explicitly dropped.\n";
1810 ProductRegistry::ProductList::iterator icopy = it;
1812 prodList.erase(icopy);
1821 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1824 TClass*
cp =
prod.wrappedType().getClass();
1825 void*
p =
cp->New();
1828 if (edp->isMergeable()) {
1830 ProductRegistry::ProductList::iterator icopy = it;
1832 prodList.erase(icopy);
1854 return std::make_unique<MakeFullProvenanceReader>();
1856 auto entryDescriptionMap = std::make_unique<EntryDescriptionMap>();
1858 return std::make_unique<MakeOldProvenanceReader>(
std::move(entryDescriptionMap));
1860 return std::make_unique<MakeDummyProvenanceReader>();
1880 std::vector<ParentageID>
const& iParentageIDLookup,
1883 std::set<ProductProvenance>
readProvenance(
unsigned int)
const override;
1888 unsigned int transitionIndex,
1889 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
1897 std::shared_ptr<std::recursive_mutex>
mutex_;
1902 std::vector<ParentageID>
const& iParentageIDLookup,
1905 rootTree_(iRootTree),
1906 pProvVector_(&provVector_),
1907 parentageIDLookup_(iParentageIDLookup),
1908 daqProvenanceHelper_(daqProvenanceHelper),
1917 template <
typename R>
1918 void readProvenanceAsyncImpl(
R const* iThis,
1921 unsigned int transitionIndex,
1922 std::atomic<
const std::set<ProductProvenance>*>& writeTo,
1924 SignalType
const* pre,
1925 SignalType
const* post) {
1926 if (
nullptr == writeTo.load()) {
1929 auto pWriteTo = &writeTo;
1940 serviceToken]()
mutable {
1941 if (
nullptr == pWriteTo->load()) {
1943 std::unique_ptr<const std::set<ProductProvenance>> prov;
1948 prov = std::make_unique<const std::set<ProductProvenance>>(iThis->readProvenance(transitionIndex));
1958 holder.doneWaiting(std::current_exception());
1961 const std::set<ProductProvenance>* expected =
nullptr;
1963 if (pWriteTo->compare_exchange_strong(expected, prov.get())) {
1967 holder.doneWaiting(std::exception_ptr());
1975 unsigned int transitionIndex,
1976 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
1977 readProvenanceAsyncImpl(
this,
1982 moduleCallingContext,
1983 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
1984 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
1989 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
1991 me->rootTree_->fillBranchEntry(
1992 me->provBranch_,
me->rootTree_->entryNumberForIndex(transitionIndex),
me->pProvVector_);
1994 std::set<ProductProvenance> retValue;
2005 <<
"ReducedProvenanceReader::ReadProvenance\n"
2006 <<
"The parentage ID index value " << prov.parentageIDIndex_
2007 <<
" is out of bounds. The maximum value is " <<
parentageIDLookup_.size() - 1 <<
".\n"
2008 <<
"This should never happen.\n"
2009 <<
"Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
2021 std::set<ProductProvenance>
readProvenance(
unsigned int transitionIndex)
const override;
2026 unsigned int transitionIndex,
2027 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2034 std::shared_ptr<std::recursive_mutex>
mutex_;
2040 rootTree_(rootTree),
2042 pInfoVector_(&infoVector_),
2043 daqProvenanceHelper_(daqProvenanceHelper),
2049 unsigned int transitionIndex,
2050 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2051 readProvenanceAsyncImpl(
this,
2056 moduleCallingContext,
2063 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
2067 std::set<ProductProvenance> retValue;
2075 retValue.emplace(
info);
2087 std::set<ProductProvenance>
readProvenance(
unsigned int transitionIndex)
const override;
2092 unsigned int transitionIndex,
2093 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2101 std::shared_ptr<std::recursive_mutex>
mutex_;
2109 rootTree_(rootTree),
2111 pInfoVector_(&infoVector_),
2112 entryDescriptionMap_(theMap),
2113 daqProvenanceHelper_(daqProvenanceHelper),
2119 unsigned int transitionIndex,
2120 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2121 readProvenanceAsyncImpl(
this,
2126 moduleCallingContext,
2127 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2128 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2133 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
2137 std::set<ProductProvenance> retValue;
2141 Parentage parentage(iter->second.parents());
2146 retValue.emplace(
info.branchID(), parentage.id());
2158 std::set<ProductProvenance>
readProvenance(
unsigned int)
const override;
2161 unsigned int transitionIndex,
2162 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2169 return std::set<ProductProvenance>{};
2173 unsigned int transitionIndex,
2174 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2175 if (
nullptr == writeTo.load()) {
2176 auto emptyProv = std::make_unique<const std::set<ProductProvenance>>();
2177 const std::set<ProductProvenance>* expected =
nullptr;
2178 if (writeTo.compare_exchange_strong(expected, emptyProv.get())) {
2179 emptyProv.release();
2186 return std::make_unique<DummyProvenanceReader>();
2191 return std::make_unique<OldProvenanceReader>(&rootTree, *
entryDescriptionMap_, daqProvenanceHelper);
2196 return std::make_unique<FullProvenanceReader>(&rootTree, daqProvenanceHelper);
2201 return std::make_unique<ReducedProvenanceReader>(&rootTree,
parentageIDLookup_, daqProvenanceHelper);