Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-12 02:41:42

0001 // -*- C++ -*-
0002 //
0003 // Package:     Modules
0004 // Class  :     GetProductCheckerOutputModule
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:
0010 //         Created:  Wed Oct  7 14:41:26 CDT 2009
0011 //
0012 
0013 // system include files
0014 #include <string>
0015 #include <sstream>
0016 
0017 // user include files
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     // We do not take ownership of passed stream.
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   // constants, enums and typedefs
0050   //
0051 
0052   //
0053   // static data member definitions
0054   //
0055 
0056   //
0057   // constructors and destructor
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   // GetProductCheckerOutputModule::GetProductCheckerOutputModule(GetProductCheckerOutputModule const& rhs) {
0066   //    // do actual copying here;
0067   // }
0068 
0069   GetProductCheckerOutputModule::~GetProductCheckerOutputModule() {}
0070 
0071   //
0072   // assignment operators
0073   //
0074   // GetProductCheckerOutputModule const& GetProductCheckerOutputModule::operator=(GetProductCheckerOutputModule const& rhs) {
0075   //   //An exception safe implementation is
0076   //   GetProductCheckerOutputModule temp(rhs);
0077   //   swap(rhs);
0078   //
0079   //   return *this;
0080   // }
0081 
0082   //
0083   // member functions
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       BranchDescription const* branchDescription = product.first;
0089       TypeID const& tid = branchDescription->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 " << branchDescription->moduleLabel() << " '"
0095                                        << branchDescription->productInstanceName() << "' "
0096                                        << branchDescription->processName();
0097         } else {
0098           edm::LogInfo("DidNotFindProduct")
0099               << "did not find " << branchDescription->moduleLabel() << " '" << branchDescription->productInstanceName()
0100               << "' " << branchDescription->processName();
0101         }
0102       }
0103       if (nullptr != bh.provenance() &&
0104           bh.provenance()->branchDescription().branchID() != branchDescription->branchID()) {
0105         throw cms::Exception("BranchIDMissMatch")
0106             << "While processing " << id << " getByToken request for " << branchDescription->moduleLabel() << " '"
0107             << branchDescription->productInstanceName() << "' " << branchDescription->processName()
0108             << "\n should have returned BranchID " << branchDescription->branchID() << " but returned BranchID "
0109             << bh.provenance()->branchDescription().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   }  // namespace
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   // const member functions
0161   //
0162 
0163   //
0164   // static member functions
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 }  // namespace edm
0176 
0177 using edm::GetProductCheckerOutputModule;
0178 DEFINE_FWK_MODULE(GetProductCheckerOutputModule);