Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:11

0001 ///////////////////////////////////////////////////////////////////////
0002 ///
0003 /// Module to read trigger bit mappings (AlCaRecoTriggerBits) from
0004 /// DB and put out as text.
0005 /// Several output formats can be configured via parameter 'outputType':
0006 /// - simple text ('text'),
0007 /// - text in format of a Twiki table for cut and paste ('twiki')
0008 /// - or a python snippet to be inserted into configuration of the
0009 ///   AlCaRecoTriggerBitsRcdWrite ('python').
0010 ///
0011 /// Where to put the text is decided by parameter 'rawFileName':
0012 /// - if empty, use MessageLogger
0013 /// - otherwise open file <rawFileName>.<suffix> where the suffix
0014 ///   is chosen to match 'outputType'.
0015 ///
0016 ///////////////////////////////////////////////////////////////////////
0017 
0018 #include <memory>
0019 
0020 #include <map>
0021 #include <string>
0022 //#include <vector>
0023 #include <sstream>
0024 #include <fstream>
0025 
0026 // Framework
0027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0028 #include "FWCore/Framework/interface/EventSetup.h"
0029 #include "FWCore/Framework/interface/ESWatcher.h"
0030 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0031 #include "FWCore/Framework/interface/MakerMacros.h"
0032 #include "FWCore/Framework/interface/Run.h"
0033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0034 #include "FWCore/Utilities/interface/Exception.h"
0035 
0036 // What I want to read:
0037 #include "CondFormats/HLTObjects/interface/AlCaRecoTriggerBits.h"
0038 #include "CondFormats/DataRecord/interface/AlCaRecoTriggerBitsRcd.h"
0039 
0040 class AlCaRecoTriggerBitsRcdRead : public edm::one::EDAnalyzer<edm::one::WatchRuns> {
0041 public:
0042   explicit AlCaRecoTriggerBitsRcdRead(const edm::ParameterSet &cfg);
0043   ~AlCaRecoTriggerBitsRcdRead() override = default;
0044 
0045   void analyze(const edm::Event &evt, const edm::EventSetup &evtSetup) override {}
0046   void beginRun(const edm::Run &run, const edm::EventSetup &evtSetup) override;
0047   void endRun(edm::Run const &, edm::EventSetup const &) override {}
0048   void endJob() override;
0049 
0050   static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
0051 
0052 private:
0053   // types
0054   enum OutputType { kText, kTwiki, kPython };  //kHtml};
0055 
0056   // methods
0057   OutputType stringToEnum(const std::string &outputType) const;
0058   void printMap(edm::RunNumber_t firstRun, edm::RunNumber_t lastRun, const AlCaRecoTriggerBits &triggerMap) const;
0059 
0060   // members
0061   const edm::ESGetToken<AlCaRecoTriggerBits, AlCaRecoTriggerBitsRcd> triggerBitsToken_;
0062   const OutputType outputType_;
0063   edm::ESWatcher<AlCaRecoTriggerBitsRcd> watcher_;
0064   edm::RunNumber_t firstRun_;
0065   edm::RunNumber_t lastRun_;
0066   AlCaRecoTriggerBits lastTriggerBits_;
0067   std::unique_ptr<std::ofstream> output_;
0068 };
0069 
0070 ///////////////////////////////////////////////////////////////////////
0071 void AlCaRecoTriggerBitsRcdRead::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0072   edm::ParameterSetDescription desc;
0073   desc.setComment("Plugin to read payloads of type AlCaRecoTriggerBits");
0074   desc.addUntracked<std::string>("rawFileName", "");
0075   desc.addUntracked<std::string>("outputType", "twiki");
0076   descriptions.addWithDefaultLabel(desc);
0077 }
0078 
0079 ///////////////////////////////////////////////////////////////////////
0080 AlCaRecoTriggerBitsRcdRead::AlCaRecoTriggerBitsRcdRead(const edm::ParameterSet &cfg)
0081     : triggerBitsToken_(esConsumes<edm::Transition::BeginRun>()),
0082       outputType_(this->stringToEnum(cfg.getUntrackedParameter<std::string>("outputType"))),
0083       firstRun_(0),
0084       lastRun_(0) {
0085   //   edm::LogInfo("") << "@SUB=AlCaRecoTriggerBitsRcdRead"
0086   //           << cfg.getParameter<std::string>("@module_label");
0087 
0088   std::string fileName(cfg.getUntrackedParameter<std::string>("rawFileName"));
0089   switch (outputType_) {  // now append suffix
0090     case kText:
0091       fileName += ".txt";
0092       break;
0093     case kPython:
0094       fileName += ".py";
0095       break;
0096     case kTwiki:
0097       fileName += ".twiki";
0098       break;
0099   }
0100   if (!fileName.empty()) {
0101     output_ = std::make_unique<std::ofstream>(fileName.c_str());
0102     if (!output_->good()) {
0103       edm::LogError("IOproblem") << "Could not open output file " << fileName << ".";
0104       output_.reset();
0105     }
0106   }
0107 }
0108 
0109 ///////////////////////////////////////////////////////////////////////
0110 AlCaRecoTriggerBitsRcdRead::OutputType AlCaRecoTriggerBitsRcdRead::stringToEnum(const std::string &outputTypeStr) const {
0111   if (outputTypeStr == "text")
0112     return kText;
0113   if (outputTypeStr == "twiki")
0114     return kTwiki;
0115   if (outputTypeStr == "python")
0116     return kPython;
0117   // if (outputTypeStr == "html") return kHtml;
0118 
0119   throw cms::Exception("BadConfig") << "AlCaRecoTriggerBitsRcdRead: "
0120                                     << "outputType '" << outputTypeStr << "' not known,"
0121                                     << " use 'text', 'twiki' or 'python'\n";
0122 
0123   return kTwiki;  // never reached, to please compiler
0124 }
0125 
0126 ///////////////////////////////////////////////////////////////////////
0127 void AlCaRecoTriggerBitsRcdRead::beginRun(const edm::Run &run, const edm::EventSetup &iSetup) {
0128   if (watcher_.check(iSetup)) {  // new IOV for this run
0129     edm::LogPrint("AlCaRecoTriggerBitsRcdRead") << "new IOV: " << firstRun_ << "-" << lastRun_;
0130     // Print last IOV - if there has already been one:
0131     if (lastRun_ != 0)
0132       this->printMap(firstRun_, lastRun_, lastTriggerBits_);
0133 
0134     // Get AlCaRecoTriggerBits from EventSetup:
0135     const auto &triggerBits = &iSetup.getData(triggerBitsToken_);
0136     lastTriggerBits_ = *triggerBits;  // copy for later use
0137     firstRun_ = run.run();            // keep track where it started
0138   }
0139 
0140   lastRun_ = run.run();  // keep track of last visited run
0141 }
0142 
0143 ///////////////////////////////////////////////////////////////////////
0144 void AlCaRecoTriggerBitsRcdRead::endJob() {
0145   // Print for very last IOV, not treated yet in beginRun(..):
0146   this->printMap(firstRun_, lastRun_, lastTriggerBits_);
0147 }
0148 
0149 ///////////////////////////////////////////////////////////////////////
0150 void AlCaRecoTriggerBitsRcdRead::printMap(edm::RunNumber_t firstRun,
0151                                           edm::RunNumber_t lastRun,
0152                                           const AlCaRecoTriggerBits &triggerBits) const {
0153   // Get map of strings to concatenated list of names of HLT paths:
0154   typedef std::map<std::string, std::string> TriggerMap;
0155   const TriggerMap &triggerMap = triggerBits.m_alcarecoToTrig;
0156 
0157   // Collect output for given run numbers via ostringstream.
0158   // Format depends on outputType_ configuration.
0159   std::ostringstream output;
0160   switch (outputType_) {
0161     case kPython:
0162       output << "  triggerLists = cms.VPSet(\n";
0163       [[fallthrough]];
0164     case kText:
0165       output << "#\n# AlCaRecoTriggerBits settings for IOV " << firstRun << "-" << lastRun << ":\n#\n";
0166       break;
0167     case kTwiki:
0168       output << "---+++++ *IOV*: " << firstRun << "-" << lastRun << "\n"
0169              << "| *TriggerBits list key* | *HLT paths* |\n";
0170       break;
0171   }
0172 
0173   //  if (outputType_ == kPython) output << "  triggerLists = cms.VPSet(\n";
0174 
0175   // loop over entries in map
0176   for (TriggerMap::const_iterator i = triggerMap.begin(); i != triggerMap.end(); ++i) {
0177     if (outputType_ == kPython && i != triggerMap.begin())
0178       output << ",\n";
0179 
0180     switch (outputType_) {
0181       case kPython:
0182         output << "      cms.PSet(listName = cms.string('" << i->first << "'),\n"
0183                << "               hltPaths = cms.vstring(";
0184         break;
0185       case kText:
0186         output << "trigger list key: '" << i->first << "'\npaths:\n";
0187         break;
0188       case kTwiki:
0189         output << "| '" << i->first << "' | ";
0190     }
0191     // We must avoid a map<string,vector<string> > in DB for performance reason,
0192     // so the paths are mapped into one string separated by ';':
0193     const std::vector<std::string> paths = triggerBits.decompose(i->second);
0194     for (unsigned int iPath = 0; iPath < paths.size(); ++iPath) {
0195       if (iPath != 0) {
0196         output << ", ";  // next path
0197         switch (outputType_) {
0198           case kPython:  // only 2 per line
0199           case kText:    // only 4 per line
0200             if (0 == (iPath % (outputType_ == kPython ? 2 : 4))) {
0201               output << "\n";
0202               if (outputType_ == kPython)
0203                 output << "                                      ";
0204             }
0205             break;
0206           case kTwiki:  // Twiki will handle that
0207             break;
0208         }
0209       }
0210       output << "'" << paths[iPath] << "'";
0211     }
0212     switch (outputType_) {
0213       case kPython:
0214         output << ")\n              )";
0215         break;
0216       case kText:
0217         output << "\n#\n";
0218         break;
0219       case kTwiki:
0220         output << " |\n";
0221     }
0222   }
0223   if (outputType_ == kPython)
0224     output << "\n      ) # closing of VPSet triggerLists\n";
0225 
0226   // Final output - either message logger or output file:
0227   if (output_.get())
0228     *output_ << output.str();
0229   else
0230     edm::LogInfo("") << output.str();
0231 }
0232 
0233 //define this as a plug-in
0234 DEFINE_FWK_MODULE(AlCaRecoTriggerBitsRcdRead);