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,
149 unsigned int nStreams,
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,
164 std::vector<std::shared_ptr<IndexIntoFile>>::
size_type currentIndexIntoFile,
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) {
254 if (
nullptr == metaDataTree.get()) {
265 fft->SetAddress(&fftPtr);
294 typedef std::map<ParameterSetID, ParameterSetBlob> PsetMap;
296 PsetMap* psetMapPtr = &psetMap;
305 if (
nullptr == psetTree.get()) {
310 typedef std::pair<ParameterSetID, ParameterSetBlob> IdToBlobs;
312 IdToBlobs* pIdToBlob = &idToBlob;
315 std::unique_ptr<TTreeCache> psetTreeCache =
317 psetTreeCache->SetEnablePrefetching(
false);
318 filePtr_->SetCacheRead(psetTreeCache.get());
319 for (Long64_t
i = 0;
i != psetTree->GetEntries(); ++
i) {
320 psetTree->GetEntry(
i);
321 psetMap.insert(idToBlob);
346 auto branchIDListsAPtr = std::make_unique<BranchIDLists>();
354 std::make_unique<ThinnedAssociationsHelper>();
358 &thinnedAssociationsHelperPtr);
395 for (
auto const& psetEntry : psetMap) {
397 pset.setID(psetEntry.first);
408 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter,
true);
416 inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter,
false);
428 <<
"Failed to find thinnedAssociationsHelper branch in metaData tree.\n";
432 if (!bypassVersionCheck) {
433 checkReleaseVersion(pHistVector,
file());
436 if (labelRawDataLikeMC) {
441 ProductRegistry::ProductList::iterator it = pList.lower_bound(
finder);
442 if (it != pList.end() && it->first.friendlyClassName() ==
rawData && it->first.moduleLabel() ==
source) {
458 it = pList.lower_bound(
finder);
459 assert(!(it != pList.end() && it->first.friendlyClassName() ==
rawData && it->first.moduleLabel() ==
source));
469 for (
auto const& history : pHistVector) {
503 for (
auto& product : pList) {
509 auto newReg = std::make_unique<ProductRegistry>();
514 for (
auto const& product : prodList) {
517 if (newFriendlyName ==
prod.friendlyClassName()) {
518 newReg->copyProduct(
prod);
522 <<
"Cannot change friendly class name algorithm without more development work\n"
523 <<
"to update BranchIDLists and ThinnedAssociationsHelper. Contact the framework group.\n";
527 newReg->copyProduct(newBD);
531 dropOnInput(*newReg, productSelectorRules, dropDescendants, inputType);
534 *associationsFromSecondary);
540 for (
auto& product : newReg->productListUpdator()) {
554 std::array<size_t, NumBranchTypes> nBranches;
556 for (
auto const& product : prodList) {
557 ++nBranches[product.second.branchType()];
562 t->numberOfBranchesToAdd(nBranches[
i]);
566 for (
auto const& product : prodList) {
590 std::unique_ptr<TTree> entryDescriptionTree(
592 if (
nullptr == entryDescriptionTree.get()) {
610 if (idBuffer != entryDescriptionBuffer.
id()) {
613 entryDescriptionMap.insert(std::make_pair(entryDescriptionBuffer.
id(), entryDescriptionBuffer));
620 if (newID != oldID) {
637 if (
nullptr == parentageTree.get()) {
655 if (newID != oldID) {
848 itr.advanceToEvent();
858 itr.skipEventBackward(phIndex,
run,
lumi, eventEntry);
859 itr.skipEventBackward(phIndex,
run,
lumi, eventEntry);
869 struct RunItemSortByRun {
870 bool operator()(RunItem
const&
a, RunItem
const&
b)
const {
return a.run_ <
b.run_; }
872 struct RunItemSortByRunPhid {
873 bool operator()(RunItem
const&
a, RunItem
const&
b)
const {
874 return a.run_ <
b.run_ || (!(
b.run_ <
a.run_) &&
a.phid_ <
b.phid_);
885 firstEventEntry_(
entry),
886 lastEventEntry_(
entry == IndexIntoFile::invalidEntry ? IndexIntoFile::invalidEntry :
entry + 1) {}
893 struct LumiItemSortByRunLumi {
894 bool operator()(LumiItem
const&
a, LumiItem
const&
b)
const {
895 return a.run_ <
b.run_ || (!(
b.run_ <
a.run_) &&
a.lumi_ <
b.lumi_);
898 struct LumiItemSortByRunLumiPhid {
899 bool operator()(LumiItem
const&
a, LumiItem
const&
b)
const {
904 if (
a.lumi_ <
b.lumi_)
906 if (
b.lumi_ <
a.lumi_)
908 return a.phid_ <
b.phid_;
923 typedef std::list<LumiItem>
LumiList;
926 typedef std::set<LuminosityBlockID> RunLumiSet;
927 RunLumiSet runLumiSet;
929 typedef std::list<RunItem>
RunList;
932 typedef std::set<RunNumber_t> RunSet;
935 typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
936 RunItemSet runItemSet;
938 typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
952 bool newLumi =
false;
963 if (iFirst || prevPhid != reducedPHID || prevRun !=
eventAux().
run()) {
965 newRun = newLumi =
true;
966 }
else if (prevLumi !=
eventAux().luminosityBlock()) {
969 prevPhid = reducedPHID;
977 LumiItem& currentLumi =
lumis.back();
979 ++currentLumi.lastEventEntry_;
984 if (runItemSet.insert(
item).second) {
987 phidMap.insert(std::make_pair(
eventAux().
run(), reducedPHID));
998 typedef std::map<RunNumber_t, IndexIntoFile::EntryNumber_t> RunMap;
1001 typedef std::vector<RunItem> RunVector;
1002 RunVector emptyRuns;
1011 if (runSet.insert(runAux->run()).
second) {
1013 emptyRuns.emplace_back(reducedPHID, runAux->run());
1016 phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
1023 RunItemSortByRun runItemSortByRun;
1026 RunList::iterator itRuns =
runs.begin(), endRuns =
runs.end();
1027 for (
auto const& emptyRun : emptyRuns) {
1028 for (; itRuns != endRuns; ++itRuns) {
1029 if (runItemSortByRun(emptyRun, *itRuns)) {
1033 runs.insert(itRuns, emptyRun);
1038 typedef std::vector<LumiItem> LumiVector;
1039 LumiVector emptyLumis;
1041 typedef std::map<LuminosityBlockID, IndexIntoFile::EntryNumber_t> RunLumiMap;
1042 RunLumiMap runLumiMap;
1049 if (runLumiSet.insert(lumiID).second) {
1054 PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
1055 assert(iPhidMap != phidMap.end());
1056 emptyLumis.emplace_back(
1066 LumiItemSortByRunLumi lumiItemSortByRunLumi;
1069 LumiList::iterator itLumis =
lumis.begin(), endLumis =
lumis.end();
1070 for (
auto const& emptyLumi : emptyLumis) {
1071 for (; itLumis != endLumis; ++itLumis) {
1072 if (lumiItemSortByRunLumi(emptyLumi, *itLumis)) {
1076 lumis.insert(itLumis, emptyLumi);
1081 typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
1082 RunCountMap runCountMap;
1089 RunCountMap::const_iterator countMapItem = runCountMap.find(
run);
1090 if (countMapItem == runCountMap.end()) {
1091 countMapItem = runCountMap.insert(std::make_pair(
run, rcount)).first;
1092 assert(countMapItem != runCountMap.end());
1095 std::vector<ProcessHistoryID>::const_iterator phidItem =
find_in_all(phids,
run.phid_);
1096 if (phidItem == phids.end()) {
1097 phids.push_back(
run.phid_);
1098 phidItem = phids.end() - 1;
1100 entries.emplace_back(countMapItem->second,
1103 phidItem - phids.begin(),
1111 typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
1112 LumiCountMap lumiCountMap;
1115 RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(
lumi.phid_,
lumi.run_));
1116 assert(runCountMapItem != runCountMap.end());
1117 LumiCountMap::const_iterator countMapItem = lumiCountMap.find(
lumi);
1118 if (countMapItem == lumiCountMap.end()) {
1119 countMapItem = lumiCountMap.insert(std::make_pair(
lumi, lcount)).first;
1120 assert(countMapItem != lumiCountMap.end());
1123 std::vector<ProcessHistoryID>::const_iterator phidItem =
find_in_all(phids,
lumi.phid_);
1124 assert(phidItem != phids.end());
1125 entries.emplace_back(runCountMapItem->second,
1126 countMapItem->second,
1128 phidItem - phids.begin(),
1131 lumi.firstEventEntry_,
1132 lumi.lastEventEntry_);
1143 <<
"in the input file.\n";
1147 if (guidFromName !=
fid_.
fid()) {
1149 <<
"GUID " << guidFromName <<
" extracted from file name " <<
file_
1150 <<
" is inconsistent with the GUID read from the file " <<
fid_.
fid();
1155 if (
runTree().entries() > 0) {
1161 for (
auto& phid : phidVec) {
1175 std::shared_ptr<IndexIntoFile::EventFinder>(std::make_shared<RootFileEventFinder>(
eventTree_)));
1178 bool needEventNumbers =
false;
1179 bool needIndexesForDuplicateChecker =
1181 if (inputType !=
InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
1182 needEventNumbers =
true;
1184 bool needEventEntries =
false;
1187 needEventEntries =
true;
1203 treePointer->close();
1204 treePointer =
nullptr;
1256 if (!eventHistoryBranch) {
1259 eventHistoryBranch->SetAddress(&pHistory);
1268 assert(eventSelectionIDBranch !=
nullptr);
1272 assert(branchListIndexesBranch !=
nullptr);
1294 auto lumiAuxiliary = std::make_shared<LuminosityBlockAuxiliary>();
1305 lumiAuxiliary->setProcessHistoryID(
provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
1308 lumiAuxiliary->setProcessHistoryID(
daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
1313 return lumiAuxiliary;
1317 auto runAuxiliary = std::make_shared<RunAuxiliary>();
1323 RunAux* pRunAux = &runAux;
1328 runAuxiliary->setProcessHistoryID(
provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
1331 runAuxiliary->setProcessHistoryID(
daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
1333 return runAuxiliary;
1344 phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1482 runHelper_->overrideRunNumber(runAuxiliary->id());
1483 return runAuxiliary;
1506 runHelper_->overrideRunNumber(runAuxiliary->id());
1507 filePtr_->reportInputRunNumber(runAuxiliary->run());
1535 runAuxiliary->setProcessHistoryID(
eventAux().processHistoryID());
1540 return runAuxiliary;
1548 assert(entryNumber >= 0);
1549 mergeableRunProductMetadata->
readRun(
1582 return std::make_shared<LuminosityBlockAuxiliary>(
1590 runHelper_->overrideRunNumber(lumiAuxiliary->id());
1591 filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
1605 return lumiAuxiliary;
1669 history_ = std::make_unique<History>();
1678 std::vector<std::shared_ptr<IndexIntoFile>>
const& indexesIntoFiles,
1679 std::vector<std::shared_ptr<IndexIntoFile>>::
size_type currentIndexIntoFile) {
1692 std::set<BranchID>& branchesToDrop,
1693 std::map<BranchID, BranchID>
const& droppedToKeptAlias)
const {
1694 if (dropDescendants) {
1697 branchesToDrop.insert(
branch.branchID());
1703 bool dropDescendants,
1709 std::vector<BranchDescription const*> associationDescriptions;
1713 std::set<BranchID> branchesToDrop;
1714 std::map<BranchID, BranchID> droppedToKeptAlias;
1715 for (
auto const& product : prodList) {
1717 if (
prod.branchID() !=
prod.originalBranchID() &&
prod.present()) {
1718 droppedToKeptAlias[
prod.originalBranchID()] =
prod.branchID();
1721 for (
auto const& product : prodList) {
1726 associationDescriptions.push_back(&
prod);
1743 std::set<BranchID> keptProductsInEvent;
1744 for (
auto const& product : prodList) {
1746 if (branchesToDrop.find(
prod.branchID()) == branchesToDrop.end() &&
prod.present() &&
1748 keptProductsInEvent.insert(
prod.branchID());
1753 std::map<BranchID, bool> keepAssociation;
1755 associationDescriptions, keptProductsInEvent, keepAssociation);
1757 for (
auto association : associationDescriptions) {
1764 auto temp = std::make_unique<ThinnedAssociationsHelper>();
1766 auto iter = keepAssociation.find(associationBranches.association());
1767 if (iter != keepAssociation.end() && iter->second) {
1768 temp->addAssociation(associationBranches);
1776 std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
1777 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1779 bool drop = branchesToDrop.find(
prod.branchID()) != branchesToDropEnd;
1781 if (!
prod.dropped()) {
1783 LogWarning(
"RootFile") <<
"Branch '" <<
prod.branchName() <<
"' is being dropped from the input\n"
1784 <<
"of file '" <<
file_ <<
"' because it is dependent on a branch\n"
1785 <<
"that was explicitly dropped.\n";
1790 ProductRegistry::ProductList::iterator icopy = it;
1792 prodList.erase(icopy);
1801 for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1804 TClass*
cp =
prod.wrappedType().getClass();
1805 void*
p =
cp->New();
1808 if (edp->isMergeable()) {
1810 ProductRegistry::ProductList::iterator icopy = it;
1812 prodList.erase(icopy);
1834 return std::make_unique<MakeFullProvenanceReader>();
1836 auto entryDescriptionMap = std::make_unique<EntryDescriptionMap>();
1838 return std::make_unique<MakeOldProvenanceReader>(
std::move(entryDescriptionMap));
1840 return std::make_unique<MakeDummyProvenanceReader>();
1860 std::vector<ParentageID>
const& iParentageIDLookup,
1863 std::set<ProductProvenance>
readProvenance(
unsigned int)
const override;
1868 unsigned int transitionIndex,
1869 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
1877 std::shared_ptr<std::recursive_mutex>
mutex_;
1882 std::vector<ParentageID>
const& iParentageIDLookup,
1885 rootTree_(iRootTree),
1886 pProvVector_(&provVector_),
1887 parentageIDLookup_(iParentageIDLookup),
1888 daqProvenanceHelper_(daqProvenanceHelper),
1897 template <
typename R>
1898 void readProvenanceAsyncImpl(
R const* iThis,
1901 unsigned int transitionIndex,
1902 std::atomic<
const std::set<ProductProvenance>*>& writeTo,
1904 SignalType
const* pre,
1905 SignalType
const* post) {
1906 if (
nullptr == writeTo.load()) {
1909 auto pWriteTo = &writeTo;
1920 serviceToken]()
mutable {
1921 if (
nullptr == pWriteTo->load()) {
1923 std::unique_ptr<const std::set<ProductProvenance>> prov;
1928 prov = std::make_unique<const std::set<ProductProvenance>>(iThis->readProvenance(transitionIndex));
1938 holder.doneWaiting(std::current_exception());
1941 const std::set<ProductProvenance>* expected =
nullptr;
1943 if (pWriteTo->compare_exchange_strong(expected, prov.get())) {
1947 holder.doneWaiting(std::exception_ptr());
1955 unsigned int transitionIndex,
1956 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
1957 readProvenanceAsyncImpl(
this,
1962 moduleCallingContext,
1963 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
1964 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
1969 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
1971 me->rootTree_->fillBranchEntry(
1972 me->provBranch_,
me->rootTree_->entryNumberForIndex(transitionIndex),
me->pProvVector_);
1974 std::set<ProductProvenance> retValue;
1985 <<
"ReducedProvenanceReader::ReadProvenance\n"
1986 <<
"The parentage ID index value " << prov.parentageIDIndex_
1987 <<
" is out of bounds. The maximum value is " <<
parentageIDLookup_.size() - 1 <<
".\n"
1988 <<
"This should never happen.\n"
1989 <<
"Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
2001 std::set<ProductProvenance>
readProvenance(
unsigned int transitionIndex)
const override;
2006 unsigned int transitionIndex,
2007 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2014 std::shared_ptr<std::recursive_mutex>
mutex_;
2020 rootTree_(rootTree),
2022 pInfoVector_(&infoVector_),
2023 daqProvenanceHelper_(daqProvenanceHelper),
2029 unsigned int transitionIndex,
2030 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2031 readProvenanceAsyncImpl(
this,
2036 moduleCallingContext,
2043 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
2047 std::set<ProductProvenance> retValue;
2055 retValue.emplace(
info);
2067 std::set<ProductProvenance>
readProvenance(
unsigned int transitionIndex)
const override;
2072 unsigned int transitionIndex,
2073 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2081 std::shared_ptr<std::recursive_mutex>
mutex_;
2089 rootTree_(rootTree),
2091 pInfoVector_(&infoVector_),
2092 entryDescriptionMap_(theMap),
2093 daqProvenanceHelper_(daqProvenanceHelper),
2099 unsigned int transitionIndex,
2100 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2101 readProvenanceAsyncImpl(
this,
2106 moduleCallingContext,
2107 rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2108 rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2113 std::lock_guard<std::recursive_mutex> guard(*
mutex_);
2117 std::set<ProductProvenance> retValue;
2121 Parentage parentage(iter->second.parents());
2126 retValue.emplace(
info.branchID(), parentage.id());
2138 std::set<ProductProvenance>
readProvenance(
unsigned int)
const override;
2141 unsigned int transitionIndex,
2142 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const override;
2149 return std::set<ProductProvenance>{};
2153 unsigned int transitionIndex,
2154 std::atomic<
const std::set<ProductProvenance>*>& writeTo)
const {
2155 if (
nullptr == writeTo.load()) {
2156 auto emptyProv = std::make_unique<const std::set<ProductProvenance>>();
2157 const std::set<ProductProvenance>* expected =
nullptr;
2158 if (writeTo.compare_exchange_strong(expected, emptyProv.get())) {
2159 emptyProv.release();
2166 return std::make_unique<DummyProvenanceReader>();
2171 return std::make_unique<OldProvenanceReader>(&rootTree, *
entryDescriptionMap_, daqProvenanceHelper);
2176 return std::make_unique<FullProvenanceReader>(&rootTree, daqProvenanceHelper);
2181 return std::make_unique<ReducedProvenanceReader>(&rootTree,
parentageIDLookup_, daqProvenanceHelper);