Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:13:00

0001 ///////////////////////////////////////////////////////////////////////////////
0002 //
0003 // PrescaleService
0004 // ---------------
0005 //
0006 ///////////////////////////////////////////////////////////////////////////////
0007 
0008 #include "FWCore/PrescaleService/interface/PrescaleService.h"
0009 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0010 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0012 #include "FWCore/ServiceRegistry/interface/ProcessContext.h"
0013 #include "FWCore/Utilities/interface/Exception.h"
0014 
0015 #include <iostream>
0016 #include <set>
0017 #include <algorithm>
0018 
0019 namespace edm {
0020   namespace service {
0021 
0022     // constructor
0023     PrescaleService::PrescaleService(ParameterSet const& iPS, ActivityRegistry& iReg)
0024         : forceDefault_(iPS.getParameter<bool>("forceDefault")),
0025           lvl1Labels_(iPS.getParameter<std::vector<std::string> >("lvl1Labels")),
0026           lvl1Default_(findDefaultIndex(iPS.getParameter<std::string>("lvl1DefaultLabel"), lvl1Labels_)),
0027           vpsetPrescales_(iPS.getParameterSetVector("prescaleTable")),
0028           prescaleTable_() {
0029       iReg.watchPreBeginJob(this, &PrescaleService::preBeginJob);
0030       iReg.watchPostBeginJob(this, &PrescaleService::postBeginJob);
0031 
0032       // Sanity check
0033       if (lvl1Default_ >= lvl1Labels_.size()) {
0034         throw cms::Exception("InvalidLvl1Index")
0035             << "lvl1Default_ '" << lvl1Default_ << "' exceeds number of prescale columns " << lvl1Labels_.size() << "!";
0036       }
0037 
0038       // Check and store Prescale Table
0039       for (unsigned int iVPSet = 0; iVPSet < vpsetPrescales_.size(); ++iVPSet) {
0040         const ParameterSet& psetPrescales = vpsetPrescales_[iVPSet];
0041         const std::string pathName = psetPrescales.getParameter<std::string>("pathName");
0042         if (prescaleTable_.find(pathName) != prescaleTable_.end()) {
0043           throw cms::Exception("PrescaleServiceConfigError") << " Path '" << pathName << "' found more than once!";
0044         }
0045         std::vector<unsigned int> prescales = psetPrescales.getParameter<std::vector<unsigned int> >("prescales");
0046         if (prescales.size() != lvl1Labels_.size()) {
0047           throw cms::Exception("PrescaleServiceConfigError")
0048               << " Path '" << pathName << "' has " << prescales.size() << " prescales, instead of expected "
0049               << lvl1Labels_.size() << "!";
0050         }
0051         prescaleTable_[pathName] = prescales;
0052       }
0053     }
0054 
0055     // destructor
0056     PrescaleService::~PrescaleService() {}
0057 
0058     // member functions
0059 
0060     void PrescaleService::preBeginJob(PathsAndConsumesOfModulesBase const&, ProcessContext const& processContext) {
0061       if (!processParameterSetID_.isValid()) {
0062         processParameterSetID_ = processContext.parameterSetID();
0063       }
0064     }
0065 
0066     void PrescaleService::postBeginJob() {
0067       // Acess to Process ParameterSet needed - can't be done in c'tor
0068       ParameterSet const& prcPS = edm::getParameterSet(processParameterSetID_);
0069       // Label of HLTPrescaler on each path, keyed on pathName
0070       std::map<std::string, std::string> path2module;
0071       // Name of path for each HLTPrescaler, keyed on moduleLabel
0072       std::map<std::string, std::string> module2path;
0073 
0074       // Check process config:
0075       // * each path contains at most one HLTPrescaler instance
0076       // * each HLTPrescaler instance is part of at most one path
0077       // * each HLTPrescaler instance is part of at least one ptah
0078 
0079       // Find all HLTPrescaler instances
0080       const std::vector<std::string> allModules = prcPS.getParameter<std::vector<std::string> >("@all_modules");
0081       for (unsigned int i = 0; i < allModules.size(); ++i) {
0082         ParameterSet const& pset = prcPS.getParameterSet(allModules[i]);
0083         const std::string moduleLabel = pset.getParameter<std::string>("@module_label");
0084         const std::string moduleType = pset.getParameter<std::string>("@module_type");
0085         if (moduleType == "HLTPrescaler")
0086           module2path[moduleLabel] = "";
0087       }
0088       // Check all modules on all paths
0089       const std::vector<std::string> allPaths = prcPS.getParameter<std::vector<std::string> >("@paths");
0090       for (unsigned int iP = 0; iP < allPaths.size(); ++iP) {
0091         const std::string& pathName = allPaths[iP];
0092         std::vector<std::string> modules = prcPS.getParameter<std::vector<std::string> >(pathName);
0093         for (unsigned int iM = 0; iM < modules.size(); ++iM) {
0094           const std::string& moduleLabel = modules[iM];
0095           if (module2path.find(moduleLabel) != module2path.end()) {
0096             if (path2module.find(pathName) == path2module.end()) {
0097               path2module[pathName] = moduleLabel;
0098             } else {
0099               throw cms::Exception("PrescaleServiceConfigError")
0100                   << "Path '" << pathName << "' with (>1) HLTPrescalers: " << path2module[pathName] << "+"
0101                   << moduleLabel << "!";
0102             }
0103             if (module2path[moduleLabel].empty()) {
0104               module2path[moduleLabel] = pathName;
0105             } else {
0106               throw cms::Exception("PrescaleServiceConfigError")
0107                   << " HLTPrescaler '" << moduleLabel << "' on (>1) Paths: " << module2path[moduleLabel] << "+"
0108                   << pathName << "!";
0109             }
0110           }
0111         }
0112       }
0113       // Check all HLTPrescaler instances are on a path
0114       for (std::map<std::string, std::string>::const_iterator it = module2path.begin(); it != module2path.end(); ++it) {
0115         if (it->second.empty()) {
0116           throw cms::Exception("PrescaleServiceConfigError")
0117               << " HLTPrescaler '" << it->first << "' not found on any path!";
0118         }
0119       }
0120 
0121       // Check paths stored Prescale Table: each path is actually in the process config
0122       for (std::map<std::string, std::vector<unsigned int> >::const_iterator it = prescaleTable_.begin();
0123            it != prescaleTable_.end();
0124            ++it) {
0125         if (path2module.find(it->first) == path2module.end()) {
0126           throw cms::Exception("PrescaleServiceConfigError")
0127               << " Path '" << it->first << "' is unknown or does not contain any HLTPrescaler!";
0128         }
0129       }
0130     }
0131 
0132     // const method
0133     unsigned int PrescaleService::getPrescale(std::string const& prescaledPath) const {
0134       return getPrescale(lvl1Default_, prescaledPath);
0135     }
0136 
0137     // const method
0138     unsigned int PrescaleService::getPrescale(unsigned int lvl1Index, std::string const& prescaledPath) const {
0139       if (forceDefault_)
0140         lvl1Index = lvl1Default_;
0141 
0142       if (lvl1Index >= lvl1Labels_.size()) {
0143         throw cms::Exception("InvalidLvl1Index")
0144             << "lvl1Index '" << lvl1Index << "' exceeds number of prescale columns " << lvl1Labels_.size() << "!";
0145       }
0146       PrescaleTable_t::const_iterator it = prescaleTable_.find(prescaledPath);
0147       return (it == prescaleTable_.end()) ? 1 : it->second[lvl1Index];
0148     }
0149 
0150     // static method
0151     unsigned int PrescaleService::findDefaultIndex(std::string const& label, std::vector<std::string> const& labels) {
0152       for (unsigned int i = 0; i < labels.size(); ++i) {
0153         if (labels[i] == label) {
0154           return i;
0155         }
0156       }
0157       return labels.size();
0158     }
0159 
0160     // static method
0161     void PrescaleService::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0162       edm::ParameterSetDescription desc;
0163 
0164       std::vector<std::string> defaultVector;
0165       defaultVector.push_back(std::string("default"));
0166       desc.add<std::vector<std::string> >("lvl1Labels", defaultVector);
0167 
0168       // This default vector<ParameterSet> will be used when
0169       // the configuration does not include this parameter and
0170       // it also gets written into the generated cfi file.
0171       std::vector<edm::ParameterSet> defaultVPSet;
0172       edm::ParameterSet pset0;
0173       pset0.addParameter<std::string>("pathName", std::string("HLTPath"));
0174       std::vector<unsigned> defaultVectorU;
0175       defaultVectorU.push_back(1u);
0176       pset0.addParameter<std::vector<unsigned> >("prescales", defaultVectorU);
0177       defaultVPSet.push_back(pset0);
0178 
0179       edm::ParameterSetDescription validator;
0180       validator.add<std::string>("pathName");
0181       validator.add<std::vector<unsigned int> >("prescales");
0182 
0183       desc.addVPSet("prescaleTable", validator, defaultVPSet);
0184 
0185       desc.add<std::string>("lvl1DefaultLabel", std::string("default"));
0186       desc.add<bool>("forceDefault", false);
0187 
0188       descriptions.add("PrescaleService", desc);
0189     }
0190 
0191   }  // namespace service
0192 }  // namespace edm