27 #include "boost/program_options.hpp"
37 typedef std::map<std::string, std::vector<edm::BranchDescription>>
IdToBranches;
40 static std::ostream&
prettyPrint(std::ostream& oStream,
51 typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob>
ParameterSetMap;
55 HistoryNode() : config_(), simpleId_(0) {}
58 : config_(iConfig), simpleId_(iSimpleId) {}
60 void addChild(HistoryNode
const&
child) { children_.push_back(
child); }
66 std::size_t
size()
const {
return children_.size(); }
68 HistoryNode* lastChildAddress() {
return &children_.back(); }
70 typedef std::vector<HistoryNode>::const_iterator const_iterator;
71 typedef std::vector<HistoryNode>::iterator iterator;
73 iterator
begin() {
return children_.begin(); }
74 iterator
end() {
return children_.end(); }
76 const_iterator
begin()
const {
return children_.begin(); }
77 const_iterator
end()
const {
return children_.end(); }
79 void print(std::ostream& os)
const {
80 os << config_.processName() <<
" '" << config_.passID() <<
"' '" << config_.releaseVersion() <<
"' [" << simpleId_
81 <<
"] (" << config_.parameterSetID() <<
")" << std::endl;
86 std::vector<std::string>
const& iFindMatch,
87 std::ostream& oErrorLog)
const;
90 std::vector<std::string>
const& iFindMatch,
91 std::ostream& oErrorLog)
const;
93 std::vector<std::string>
const& iFindMatch,
94 std::ostream& oErrorLog)
const;
102 std::vector<HistoryNode> children_;
103 unsigned int simpleId_;
106 std::ostream&
operator<<(std::ostream& os, HistoryNode
const& node) {
110 bool HistoryNode::sort_ =
false;
116 for (
auto const&
process : iHist) {
118 <<
process.parameterSetID() <<
")" << std::endl;
124 void HistoryNode::printHistory(
std::string const& iIndent)
const {
127 for (
auto const&
item : *
this) {
137 std::ostringstream
result;
144 result << iType <<
": " <<
name <<
" " << iProcessName <<
"\n"
151 std::vector<std::string>
const& iFindMatch,
152 std::ostream& oErrorLog)
const {
153 for (
auto const& itH : *
this) {
155 ParameterSetMap::const_iterator itFind = iPSM.find(itH.parameterSetID());
156 if (itFind == iPSM.end()) {
157 oErrorLog <<
"No ParameterSetID for " << itH.parameterSetID() << std::endl;
160 std::vector<std::string> sourceStrings, moduleStrings;
162 std::vector<std::string>
sources = processConfig.getParameter<std::vector<std::string>>(
"@all_essources");
165 bool foundMatch =
true;
166 if (!iFindMatch.empty()) {
167 for (
auto const& stringToFind : iFindMatch) {
168 if (retValue.find(stringToFind) == std::string::npos) {
175 sourceStrings.push_back(
std::move(retValue));
179 std::vector<std::string>
modules = processConfig.getParameter<std::vector<std::string>>(
"@all_esmodules");
182 bool foundMatch =
true;
183 if (!iFindMatch.empty()) {
184 for (
auto const& stringToFind : iFindMatch) {
185 if (retValue.find(stringToFind) == std::string::npos) {
192 moduleStrings.push_back(
std::move(retValue));
196 std::sort(sourceStrings.begin(), sourceStrings.end());
197 std::sort(moduleStrings.begin(), moduleStrings.end());
199 std::copy(sourceStrings.begin(), sourceStrings.end(), std::ostream_iterator<std::string>(
std::cout,
"\n"));
200 std::copy(moduleStrings.begin(), moduleStrings.end(), std::ostream_iterator<std::string>(
std::cout,
"\n"));
202 itH.printEventSetupHistory(iPSM, iFindMatch, oErrorLog);
209 std::ostringstream
result;
213 result <<
"Module: " <<
label <<
" " << iProcessName <<
"\n"
219 void HistoryNode::printOtherModulesHistory(
ParameterSetMap const& iPSM,
221 std::vector<std::string>
const& iFindMatch,
222 std::ostream& oErrorLog)
const {
223 for (
auto const& itH : *
this) {
225 ParameterSetMap::const_iterator itFind = iPSM.find(itH.parameterSetID());
226 if (itFind == iPSM.end()) {
227 oErrorLog <<
"No ParameterSetID for " << itH.parameterSetID() << std::endl;
230 std::vector<std::string> moduleStrings;
232 std::vector<std::string>
modules = processConfig.getParameter<std::vector<std::string>>(
"@all_modules");
235 if (iModules.end() == iModules.find(std::make_pair(itH.processName(), itM))) {
237 bool foundMatch =
true;
238 if (!iFindMatch.empty()) {
239 for (
auto const& stringToFind : iFindMatch) {
240 if (retValue.find(stringToFind) == std::string::npos) {
247 moduleStrings.push_back(
std::move(retValue));
252 std::sort(moduleStrings.begin(), moduleStrings.end());
254 std::copy(moduleStrings.begin(), moduleStrings.end(), std::ostream_iterator<std::string>(
std::cout,
"\n"));
256 itH.printOtherModulesHistory(iPSM, iModules, iFindMatch, oErrorLog);
260 static void appendToSet(std::set<std::string>& iSet, std::vector<std::string>
const& iFrom) {
261 for (
auto const&
n : iFrom) {
269 std::ostringstream
result;
272 result <<
"PSet: " << iName <<
" " << iProcessName <<
"\n"
278 void HistoryNode::printTopLevelPSetsHistory(
ParameterSetMap const& iPSM,
279 std::vector<std::string>
const& iFindMatch,
280 std::ostream& oErrorLog)
const {
281 for (
auto const& itH : *
this) {
283 ParameterSetMap::const_iterator itFind = iPSM.find(itH.parameterSetID());
284 if (itFind == iPSM.end()) {
285 oErrorLog <<
"No ParameterSetID for " << itH.parameterSetID() << std::endl;
289 std::set<std::string> namesToExclude;
290 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>(
"@all_modules"));
291 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>(
"@all_sources"));
292 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>(
"@all_loopers"));
294 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>(
"@all_esmodules"));
295 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>(
"@all_essources"));
296 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>(
"@all_esprefers"));
297 if (processConfig.existsAs<std::vector<std::string>>(
"all_aliases")) {
298 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>(
"@all_aliases"));
301 std::vector<std::string> allNames{};
302 processConfig.getParameterSetNames(allNames);
304 std::vector<std::string>
results;
305 for (
auto const&
name : allNames) {
306 if (
name.empty() ||
'@' ==
name[0] || namesToExclude.find(
name) != namesToExclude.end()) {
311 bool foundMatch =
true;
312 if (!iFindMatch.empty()) {
313 for (
auto const& stringToFind : iFindMatch) {
314 if (retValue.find(stringToFind) == std::string::npos) {
329 itH.printTopLevelPSetsHistory(iPSM, iFindMatch, oErrorLog);
336 std::unique_ptr<edm::SiteLocalConfig> slcptr =
338 auto slc = std::make_shared<edm::serviceregistry::ServiceWrapper<edm::SiteLocalConfig>>(
std::move(slcptr));
347 <<
"File " <<
filename <<
" was not found or could not be opened.\n";
350 std::unique_ptr<TFile>
result(TFile::Open(
catalog.fileNames(0)[0].c_str()));
353 <<
"File " <<
fileNames[0] <<
" was not found or could not be opened.\n";
368 return makeTFileWithLookup(
filename);
378 char const* trackiness = (psetEntry.
isTracked() ?
"tracked" :
"untracked");
379 os <<
"PSet " << trackiness <<
" = (";
380 prettyPrint(os, psetEntry.
pset(), iIndent + iIndentDelta, iIndentDelta);
389 std::vector<edm::ParameterSet>
const& vps = vpsetEntry.
vpset();
390 os <<
"VPSet " << (vpsetEntry.
isTracked() ?
"tracked" :
"untracked") <<
" = ({" << std::endl;
394 for (
auto const&
item : vps) {
395 os <<
start << newIndent;
402 os << iIndent <<
"})";
412 oStream <<
"{" << std::endl;
413 for (
auto const&
item : iPSet.
tbl()) {
415 oStream << newIndent <<
item.first <<
": " <<
item.second << std::endl;
420 oStream << newIndent <<
item.first <<
": ";
422 oStream << std::endl;
427 oStream << newIndent <<
item.first <<
": ";
429 oStream << std::endl;
431 oStream << iIndent <<
"}";
441 bool showDependencies,
442 bool extendedAncestors,
443 bool extendedDescendants,
444 bool excludeESModules,
446 bool showTopLevelPSets,
447 std::vector<std::string>
const& findMatch,
448 bool dontPrintProducts,
461 std::set<edm::BranchID>& ancestorBranchIDs,
462 std::ostringstream& sout,
466 std::set<edm::BranchID>& descendantBranchIDs,
467 std::ostringstream& sout,
499 bool showDependencies,
500 bool extendedAncestors,
501 bool extendedDescendants,
502 bool excludeESModules,
503 bool showOtherModules,
504 bool showTopLevelPSets,
505 std::vector<std::string>
const& findMatch,
506 bool dontPrintProducts,
513 showDependencies_(showDependencies),
514 extendedAncestors_(extendedAncestors),
515 extendedDescendants_(extendedDescendants),
516 excludeESModules_(excludeESModules),
517 showOtherModules_(showOtherModules),
518 productRegistryPresent_(
true),
519 showTopLevelPSets_(showTopLevelPSets),
520 findMatch_(findMatch),
521 dontPrintProducts_(dontPrintProducts),
522 dumpPSetID_(dumpPSetID) {}
536 std::cout <<
"No event filtering information is available.\n";
537 std::cout <<
"------------------------------\n";
539 std::cout <<
"Event filtering information for " << num_ids <<
" processing steps is available.\n"
540 <<
"The ParameterSets will be printed out, "
541 <<
"with the oldest printed first.\n";
550 if (history !=
nullptr) {
555 if (history->GetEntry(0) <= 0) {
556 std::cout <<
"No event filtering information is available; the event history tree has no entries\n";
564 if (eventSelectionsBranch ==
nullptr)
568 eventSelectionsBranch->SetAddress(&pids);
569 if (eventSelectionsBranch->GetEntry(0) <= 0) {
570 std::cout <<
"No event filtering information is available; the event selections branch has no entries\n";
578 std::cout <<
"ParameterSetID: " <<
id <<
'\n';
580 ParameterSetMap::const_iterator
i =
psm_.find(
id);
581 if (
i ==
psm_.end()) {
582 std::cout <<
"We are unable to find the corresponding ParameterSet\n";
585 if (
id ==
empty.id()) {
586 std::cout <<
"But it would have been empty anyway\n";
596 std::cout <<
" -------------------------\n";
600 std::cout <<
"Processing History:" << std::endl;
601 std::map<edm::ProcessConfigurationID, unsigned int> simpleIDs;
602 for (
auto const& ph :
phv_) {
605 for (
auto const& pc : ph) {
606 if (
parent->size() == 0) {
607 unsigned int id = simpleIDs[pc.id()];
610 simpleIDs[pc.id()] =
id;
612 parent->addChild(HistoryNode(pc,
id));
616 bool isUnique =
true;
618 if (
child.configurationID() == pc.id()) {
625 simpleIDs[pc.id()] =
parent->size() + 1;
626 parent->addChild(HistoryNode(pc, simpleIDs[pc.id()]));
651 assert(
nullptr != psetTree);
652 typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs;
654 IdToBlobs* pIdToBlob = &idToBlob;
656 for (
long long i = 0;
i != psetTree->GetEntries(); ++
i) {
657 psetTree->GetEntry(
i);
658 psm_.insert(idToBlob);
692 for (
auto const& history :
phv_) {
693 for (
auto const&
process : history) {
702 else if (!phm.empty()) {
703 for (
auto const& history : phm) {
704 phv_.push_back(history.second);
705 for (
auto const&
process : history.second) {
719 <<
"Illegal ParameterSetID string. It should contain 32 hexadecimal characters";
726 std::map<edm::BranchID, std::set<edm::ParentageID>> perProductParentage;
730 if (
nullptr == parentageTree) {
731 std::cerr <<
"ERROR, no Parentage tree available so cannot show dependencies, ancestors, or descendants.\n";
732 std::cerr <<
"Possibly this is not a standard EDM format file. For example, dependency, ancestor, and\n";
733 std::cerr <<
"descendant options to edmProvDump will not work with nanoAOD format files.\n\n";
740 std::vector<edm::ParentageID> orderedParentageIDs;
741 orderedParentageIDs.reserve(parentageTree->GetEntries());
746 parentageTree->GetEntry(
i);
748 orderedParentageIDs.push_back(parentageBuffer.
id());
752 TTree* eventMetaTree =
754 if (
nullptr == eventMetaTree) {
757 if (
nullptr == eventMetaTree) {
759 <<
"' Tree in file so can not show dependencies\n";
764 TBranch* storedProvBranch =
767 if (
nullptr != storedProvBranch) {
768 std::vector<edm::StoredProductProvenance>
info;
769 std::vector<edm::StoredProductProvenance>* pInfo = &
info;
770 storedProvBranch->SetAddress(&pInfo);
772 storedProvBranch->GetEntry(
i);
775 perProductParentage[bid].insert(orderedParentageIDs.at(
item.parentageIDIndex_));
780 TBranch* productProvBranch =
782 if (
nullptr != productProvBranch) {
783 std::vector<edm::ProductProvenance>
info;
784 std::vector<edm::ProductProvenance>* pInfo = &
info;
785 productProvBranch->SetAddress(&pInfo);
787 productProvBranch->GetEntry(
i);
789 perProductParentage[
item.branchID()].insert(
item.parentageID());
793 std::cerr <<
" ERROR, could not find provenance information so can not show dependencies\n";
803 std::map<edm::BranchID, std::set<edm::BranchID>> parentToChildren;
807 for (
auto const& itParentageSet : perProductParentage) {
809 for (
auto const& itParentageID : itParentageSet.second) {
811 if (
nullptr != parentage) {
813 parentToChildren[
branch].insert(childBranchID);
816 std::cerr <<
" ERROR:parentage info not in registry ParentageID=" << itParentageID << std::endl;
827 std::cout <<
"---------Producers with data in file---------" << std::endl;
835 std::map<edm::BranchID, std::string> branchIDToBranchName;
837 for (
auto const& processConfig :
phc_) {
840 if (
nullptr == processParameterSet || processParameterSet->
empty()) {
844 auto& product =
item.second;
845 if (product.processName() != processConfig.processName()) {
853 branchIDToBranchName[product.branchID()] = product.branchName();
873 s << moduleParameterSetCopy.
id();
875 s << moduleParameterSet.
id();
877 moduleToIdBranches[std::make_pair(product.processName(), product.moduleLabel())][
s.str()].push_back(product);
882 for (
auto const&
item : moduleToIdBranches) {
883 std::ostringstream sout;
884 sout <<
"Module: " <<
item.first.second <<
" " <<
item.first.first << std::endl;
885 std::set<edm::BranchID> allBranchIDsForLabelAndProcess;
887 for (
auto const& idBranch : idToBranches) {
888 sout <<
" PSet id:" << idBranch.first << std::endl;
890 sout <<
" products: {" << std::endl;
892 std::set<edm::BranchID> branchIDs;
893 for (
auto const&
branch : idBranch.second) {
895 sout <<
" " <<
branch.branchName() << std::endl;
897 branchIDs.insert(
branch.branchID());
898 allBranchIDsForLabelAndProcess.insert(
branch.branchID());
900 sout <<
" }" << std::endl;
902 ParameterSetMap::const_iterator itpsm =
psm_.find(psid);
903 if (
psm_.end() == itpsm) {
905 errorLog_ <<
"No ParameterSetID for " << psid << std::endl;
908 sout <<
" parameters: ";
913 sout <<
" dependencies: {" << std::endl;
914 std::set<edm::ParentageID> parentageIDs;
915 for (
auto const&
branch : branchIDs) {
917 std::set<edm::ParentageID>
const&
temp = perProductParentage[
branch];
918 parentageIDs.insert(
temp.begin(),
temp.end());
920 for (
auto const& parentID : parentageIDs) {
922 if (
nullptr != parentage) {
924 sout <<
" " << branchIDToBranchName[
branch] << std::endl;
927 sout <<
" ERROR:parentage info not in registry ParentageID=" << parentID << std::endl;
930 if (parentageIDs.empty()) {
931 sout <<
" no dependencies recorded (event may not contain data from this module)" << std::endl;
933 sout <<
" }" << std::endl;
937 sout <<
" extendedAncestors: {" << std::endl;
938 std::set<edm::BranchID> ancestorBranchIDs;
939 for (
auto const& branchID : allBranchIDsForLabelAndProcess) {
940 addAncestors(branchID, ancestorBranchIDs, sout, perProductParentage);
942 for (
auto const& ancestorBranchID : ancestorBranchIDs) {
943 sout <<
" " << branchIDToBranchName[ancestorBranchID] <<
"\n";
945 sout <<
" }" << std::endl;
949 sout <<
" extendedDescendants: {" << std::endl;
950 std::set<edm::BranchID> descendantBranchIDs;
951 for (
auto const& branchID : allBranchIDsForLabelAndProcess) {
952 addDescendants(branchID, descendantBranchIDs, sout, parentToChildren);
954 for (
auto const& descendantBranchID : descendantBranchIDs) {
955 sout <<
" " << branchIDToBranchName[descendantBranchID] <<
"\n";
957 sout <<
" }" << std::endl;
959 bool foundMatch =
true;
962 if (sout.str().find(stringToFind) == std::string::npos) {
974 std::cout <<
"---------Other Modules---------" << std::endl;
977 std::cout <<
"---------All Modules---------" << std::endl;
982 std::cout <<
"---------EventSetup---------" << std::endl;
987 std::cout <<
"---------Top Level PSets---------" << std::endl;
996 std::set<edm::BranchID>& ancestorBranchIDs,
997 std::ostringstream& sout,
1001 std::set<edm::ParentageID>
const& parentIDs = perProductParentage[branchID];
1002 for (
auto const& parentageID : parentIDs) {
1004 if (
nullptr != parentage) {
1006 if (ancestorBranchIDs.insert(
branch).second) {
1011 sout <<
" ERROR:parentage info not in registry ParentageID=" << parentageID << std::endl;
1017 std::set<edm::BranchID>& descendantBranchIDs,
1018 std::ostringstream& sout,
1020 for (
auto const& childBranchID : parentToChildren[branchID]) {
1021 if (descendantBranchIDs.insert(childBranchID).second) {
1022 addDescendants(childBranchID, descendantBranchIDs, sout, parentToChildren);
1052 using namespace boost::program_options;
1055 descString +=
" [options] <filename>";
1056 descString +=
"\nAllowed options";
1057 options_description desc(descString);
1062 "print what data depends on the data each EDProducer produces including indirect dependences")(
1067 boost::program_options::value<std::vector<std::string>>(),
1068 "show only modules whose information contains the matching string (or all the matching strings, this option can "
1071 value<std::string>(),
1072 "print the parameter set associated with the parameter set ID string (and print nothing else)");
1075 options_description hidden;
1076 hidden.add_options()(
kFileNameOpt, value<std::string>(),
"file name");
1079 options_description cmdline_options;
1080 cmdline_options.add(desc).add(hidden);
1082 positional_options_description
p;
1089 }
catch (
error const& iException) {
1100 HistoryNode::sort_ =
true;
1103 bool showDependencies =
false;
1105 showDependencies =
true;
1108 bool extendedAncestors =
false;
1110 extendedAncestors =
true;
1113 bool extendedDescendants =
false;
1115 extendedDescendants =
true;
1118 bool excludeESModules =
false;
1120 excludeESModules =
true;
1123 bool showAllModules =
false;
1125 showAllModules =
true;
1128 bool showTopLevelPSets =
false;
1130 showTopLevelPSets =
true;
1137 }
catch (boost::bad_any_cast
const&
e) {
1142 std::cout <<
"Data file not specified." << std::endl;
1151 }
catch (boost::bad_any_cast
const&
e) {
1157 std::vector<std::string> findMatch;
1160 findMatch = vm[
kFindMatchOpt].as<std::vector<std::string>>();
1161 }
catch (boost::bad_any_cast
const&
e) {
1167 bool dontPrintProducts =
false;
1169 dontPrintProducts =
true;
1178 extendedDescendants,
1198 std::cerr <<
"Unknown exception caught\n";