File indexing completed on 2025-01-31 02:19:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <string>
0015 #include <sstream>
0016
0017
0018 #include "FWCore/Framework/interface/one/OutputModule.h"
0019 #include "FWCore/Framework/interface/MakerMacros.h"
0020 #include "FWCore/Framework/interface/EventForOutput.h"
0021 #include "FWCore/Framework/interface/LuminosityBlockForOutput.h"
0022 #include "FWCore/Framework/interface/RunForOutput.h"
0023 #include "FWCore/Utilities/interface/Exception.h"
0024 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0025 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0026 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0027 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0028
0029 namespace edm {
0030 class ModuleCallingContext;
0031 class ParameterSet;
0032
0033 class GetProductCheckerOutputModule : public one::OutputModule<> {
0034 public:
0035
0036 explicit GetProductCheckerOutputModule(ParameterSet const& pset);
0037 ~GetProductCheckerOutputModule() override;
0038 static void fillDescriptions(ConfigurationDescriptions& descriptions);
0039
0040 private:
0041 void write(EventForOutput const& e) override;
0042 void writeLuminosityBlock(LuminosityBlockForOutput const&) override;
0043 void writeRun(RunForOutput const&) override;
0044 const std::vector<std::string> crosscheck_;
0045 const bool verbose_;
0046 };
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 GetProductCheckerOutputModule::GetProductCheckerOutputModule(ParameterSet const& iPSet)
0060 : one::OutputModuleBase(iPSet),
0061 one::OutputModule<>(iPSet),
0062 crosscheck_(iPSet.getUntrackedParameter<std::vector<std::string>>("crosscheck")),
0063 verbose_(iPSet.getUntrackedParameter<bool>("verbose")) {}
0064
0065
0066
0067
0068
0069 GetProductCheckerOutputModule::~GetProductCheckerOutputModule() {}
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 template <typename T>
0086 static void check(T const& p, std::string const& id, SelectedProducts const& iProducts, bool iVerbose) {
0087 for (auto const& product : iProducts) {
0088 ProductDescription const* productDescription = product.first;
0089 TypeID const& tid = productDescription->unwrappedTypeID();
0090 EDGetToken const& token = product.second;
0091 BasicHandle bh = p.getByToken(token, tid);
0092 if (iVerbose) {
0093 if (bh.isValid()) {
0094 edm::LogInfo("FoundProduct") << "found " << productDescription->moduleLabel() << " '"
0095 << productDescription->productInstanceName() << "' "
0096 << productDescription->processName();
0097 } else {
0098 edm::LogInfo("DidNotFindProduct")
0099 << "did not find " << productDescription->moduleLabel() << " '"
0100 << productDescription->productInstanceName() << "' " << productDescription->processName();
0101 }
0102 }
0103 if (nullptr != bh.provenance() &&
0104 bh.provenance()->productDescription().branchID() != productDescription->branchID()) {
0105 throw cms::Exception("BranchIDMissMatch")
0106 << "While processing " << id << " getByToken request for " << productDescription->moduleLabel() << " '"
0107 << productDescription->productInstanceName() << "' " << productDescription->processName()
0108 << "\n should have returned BranchID " << productDescription->branchID() << " but returned BranchID "
0109 << bh.provenance()->productDescription().branchID() << "\n";
0110 }
0111 }
0112 }
0113 namespace {
0114 std::string canonicalName(std::string const& iOriginal) {
0115 if (iOriginal.empty()) {
0116 return iOriginal;
0117 }
0118 if (iOriginal.back() == '.') {
0119 return iOriginal.substr(0, iOriginal.size() - 1);
0120 }
0121 return iOriginal;
0122 }
0123 }
0124 void GetProductCheckerOutputModule::write(EventForOutput const& e) {
0125 std::ostringstream str;
0126 str << e.id();
0127 check(e, str.str(), keptProducts()[InEvent], verbose_);
0128 if (not crosscheck_.empty()) {
0129 std::set<std::string> expectedProducts(crosscheck_.begin(), crosscheck_.end());
0130 for (auto const& kp : keptProducts()[InEvent]) {
0131 auto bn = canonicalName(kp.first->branchName());
0132 auto found = expectedProducts.find(bn);
0133 if (found == expectedProducts.end()) {
0134 throw cms::Exception("CrosscheckFailed") << "unexpected kept product " << bn;
0135 }
0136 expectedProducts.erase(bn);
0137 }
0138 if (not expectedProducts.empty()) {
0139 cms::Exception e("CrosscheckFailed");
0140 e << "Did not find the expected products:\n";
0141 for (auto const& p : expectedProducts) {
0142 e << p << "\n";
0143 }
0144 throw e;
0145 }
0146 }
0147 }
0148 void GetProductCheckerOutputModule::writeLuminosityBlock(LuminosityBlockForOutput const& l) {
0149 std::ostringstream str;
0150 str << l.id();
0151 check(l, str.str(), keptProducts()[InLumi], verbose_);
0152 }
0153 void GetProductCheckerOutputModule::writeRun(RunForOutput const& r) {
0154 std::ostringstream str;
0155 str << r.id();
0156 check(r, str.str(), keptProducts()[InRun], verbose_);
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 void GetProductCheckerOutputModule::fillDescriptions(ConfigurationDescriptions& descriptions) {
0168 ParameterSetDescription desc;
0169 one::OutputModule<>::fillDescription(desc);
0170 desc.addUntracked<std::vector<std::string>>("crosscheck", {})
0171 ->setComment("Branch names that should be in the event. If empty no check done.");
0172 desc.addUntracked<bool>("verbose", false);
0173 descriptions.add("productChecker", desc);
0174 }
0175 }
0176
0177 using edm::GetProductCheckerOutputModule;
0178 DEFINE_FWK_MODULE(GetProductCheckerOutputModule);