Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:22:20

0001 /**
0002  * \class L1GtTriggerMenuTester
0003  *
0004  *
0005  * Description: test analyzer for L1 GT trigger menu.
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *
0010  * \author: Vasile Mihai Ghete - HEPHY Vienna
0011  *
0012  *
0013  */
0014 
0015 // this class header
0016 #include "L1TriggerConfig/L1GtConfigProducers/interface/L1GtTriggerMenuTester.h"
0017 
0018 // system include files
0019 #include <iomanip>
0020 #include <boost/algorithm/string/erase.hpp>
0021 
0022 // user include files
0023 #include "FWCore/Framework/interface/Event.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 
0026 #include "FWCore/Framework/interface/EventSetup.h"
0027 #include "FWCore/Framework/interface/ESHandle.h"
0028 
0029 #include "CondFormats/L1TObjects/interface/L1GtStableParameters.h"
0030 #include "CondFormats/DataRecord/interface/L1GtStableParametersRcd.h"
0031 
0032 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
0033 #include "CondFormats/DataRecord/interface/L1GtTriggerMenuRcd.h"
0034 
0035 #include "CondFormats/L1TObjects/interface/L1GtPrescaleFactors.h"
0036 
0037 #include "CondFormats/DataRecord/interface/L1GtPrescaleFactorsAlgoTrigRcd.h"
0038 #include "CondFormats/DataRecord/interface/L1GtPrescaleFactorsTechTrigRcd.h"
0039 
0040 #include "CondFormats/L1TObjects/interface/L1GtTriggerMask.h"
0041 
0042 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskAlgoTrigRcd.h"
0043 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskTechTrigRcd.h"
0044 
0045 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskVetoAlgoTrigRcd.h"
0046 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskVetoTechTrigRcd.h"
0047 
0048 #include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h"
0049 
0050 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0051 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0052 
0053 // forward declarations
0054 
0055 // constructor(s)
0056 L1GtTriggerMenuTester::L1GtTriggerMenuTester(const edm::ParameterSet& parSet)
0057     : m_overwriteHtmlFile(parSet.getParameter<bool>("OverwriteHtmlFile")),
0058       m_htmlFile(parSet.getParameter<std::string>("HtmlFile")),
0059       m_useHltMenu(parSet.getParameter<bool>("UseHltMenu")),
0060       m_hltProcessName(parSet.getParameter<std::string>("HltProcessName")),
0061       m_noThrowIncompatibleMenu(parSet.getParameter<bool>("NoThrowIncompatibleMenu")),
0062       m_printPfsRates(parSet.getParameter<bool>("PrintPfsRates")),
0063       m_indexPfSet(parSet.getParameter<int>("IndexPfSet")),
0064       m_l1GtStableParToken(esConsumes<edm::Transition::BeginRun>()),
0065       m_l1GtPfAlgoToken(esConsumes<edm::Transition::BeginRun>()),
0066       m_l1GtPfTechToken(esConsumes<edm::Transition::BeginRun>()),
0067       m_l1GtTmTechToken(esConsumes<edm::Transition::BeginRun>()),
0068       m_l1GtTmVetoAlgoToken(esConsumes<edm::Transition::BeginRun>()),
0069       m_l1GtTmVetoTechToken(esConsumes<edm::Transition::BeginRun>()),
0070       m_l1GtMenuToken(esConsumes<edm::Transition::BeginRun>()),
0071       m_numberAlgorithmTriggers(0),
0072       m_numberTechnicalTriggers(0) {
0073   // empty
0074 }
0075 
0076 // begin run
0077 void L1GtTriggerMenuTester::beginRun(const edm::Run& iRun, const edm::EventSetup& evSetup) {
0078   // retrieve L1 trigger configuration
0079   retrieveL1EventSetup(evSetup);
0080 
0081   // print with various level of verbosity
0082 
0083   // define an output stream to print into
0084   // it can then be directed to whatever log level is desired
0085   std::ostringstream myCout;
0086 
0087   int printVerbosity = 0;
0088   m_l1GtMenu->print(myCout, printVerbosity);
0089   myCout << std::flush << std::endl;
0090 
0091   printVerbosity = 1;
0092   m_l1GtMenu->print(myCout, printVerbosity);
0093   myCout << std::flush << std::endl;
0094 
0095   printVerbosity = 2;
0096   m_l1GtMenu->print(myCout, printVerbosity);
0097   myCout << std::flush << std::endl;
0098 
0099   // redirect myCout to edm::LogVerbatim TODO - parameter to choose the log
0100   edm::LogVerbatim("L1GtTriggerMenuTester") << myCout.str() << std::endl;
0101 
0102   // prepare L1 - HLT
0103   if (m_useHltMenu) {
0104     associateL1SeedsHltPath(iRun, evSetup);
0105 
0106     if (m_noThrowIncompatibleMenu) {
0107       edm::LogVerbatim("L1GtTriggerMenuTester")
0108           << "\n List of algorithm triggers used as L1 seeds but not in L1 menu" << std::endl;
0109 
0110       for (std::vector<std::string>::const_iterator strIter = m_algoTriggerSeedNotInL1Menu.begin();
0111            strIter != m_algoTriggerSeedNotInL1Menu.end();
0112            ++strIter) {
0113         edm::LogVerbatim("L1GtTriggerMenuTester") << "   " << (*strIter) << std::endl;
0114       }
0115     }
0116   }
0117 
0118   // print in wiki format
0119   printWiki();
0120 }
0121 
0122 // loop over events
0123 void L1GtTriggerMenuTester::analyze(const edm::Event& iEvent, const edm::EventSetup& evSetup) {
0124   // empty
0125 }
0126 
0127 // end run
0128 void L1GtTriggerMenuTester::endRun(const edm::Run&, const edm::EventSetup& evSetup) {}
0129 
0130 void L1GtTriggerMenuTester::retrieveL1EventSetup(const edm::EventSetup& evSetup) {
0131   // get / update the stable parameters from the EventSetup
0132 
0133   m_l1GtStablePar = &evSetup.getData(m_l1GtStableParToken);
0134 
0135   // number of algorithm triggers
0136   m_numberAlgorithmTriggers = m_l1GtStablePar->gtNumberPhysTriggers();
0137 
0138   // number of technical triggers
0139   m_numberTechnicalTriggers = m_l1GtStablePar->gtNumberTechnicalTriggers();
0140 
0141   //    int maxNumberTrigger = std::max(m_numberAlgorithmTriggers,
0142   //            m_numberTechnicalTriggers);
0143 
0144   //    m_triggerMaskSet.reserve(maxNumberTrigger);
0145   //    m_prescaleFactorSet.reserve(maxNumberTrigger);
0146 
0147   // get / update the prescale factors from the EventSetup
0148 
0149   m_l1GtPfAlgo = &evSetup.getData(m_l1GtPfAlgoToken);
0150 
0151   m_prescaleFactorsAlgoTrig = &(m_l1GtPfAlgo->gtPrescaleFactors());
0152 
0153   m_l1GtPfTech = &evSetup.getData(m_l1GtPfTechToken);
0154 
0155   m_prescaleFactorsTechTrig = &(m_l1GtPfTech->gtPrescaleFactors());
0156 
0157   // get / update the trigger mask from the EventSetup
0158 
0159   m_l1GtTmAlgo = &evSetup.getData(m_l1GtTmAlgoToken);
0160 
0161   m_triggerMaskAlgoTrig = &(m_l1GtTmAlgo->gtTriggerMask());
0162 
0163   m_l1GtTmTech = &evSetup.getData(m_l1GtTmTechToken);
0164 
0165   m_triggerMaskTechTrig = &(m_l1GtTmTech->gtTriggerMask());
0166 
0167   m_l1GtTmVetoAlgo = &evSetup.getData(m_l1GtTmVetoAlgoToken);
0168 
0169   m_triggerMaskVetoAlgoTrig = &(m_l1GtTmVetoAlgo->gtTriggerMask());
0170 
0171   m_l1GtTmVetoTech = &evSetup.getData(m_l1GtTmVetoTechToken);
0172 
0173   m_triggerMaskVetoTechTrig = &(m_l1GtTmVetoTech->gtTriggerMask());
0174 
0175   // get / update the trigger menu from the EventSetup
0176 
0177   m_l1GtMenu = &evSetup.getData(m_l1GtMenuToken);
0178   m_algorithmMap = &(m_l1GtMenu->gtAlgorithmMap());
0179   m_algorithmAliasMap = &(m_l1GtMenu->gtAlgorithmAliasMap());
0180   m_technicalTriggerMap = &(m_l1GtMenu->gtTechnicalTriggerMap());
0181 }
0182 
0183 void L1GtTriggerMenuTester::associateL1SeedsHltPath(const edm::Run& iRun, const edm::EventSetup& evSetup) {
0184   bool hltChanged = true;
0185 
0186   if (m_hltConfig.init(iRun, evSetup, m_hltProcessName, hltChanged)) {
0187     // if init returns TRUE, initialization has succeeded!
0188     if (hltChanged) {
0189       // HLT configuration has actually changed wrt the previous run
0190       m_hltTableName = m_hltConfig.tableName();
0191 
0192       edm::LogVerbatim("L1GtTriggerMenuTester") << "\nHLT ConfDB menu name: \n   " << m_hltTableName << std::endl;
0193 
0194       // loop over trigger paths, get the HLTLevel1GTSeed logical expression, and add the path to
0195       // each L1 trigger
0196 
0197       m_hltPathsForL1AlgorithmTrigger.resize(m_numberAlgorithmTriggers);
0198       m_hltPathsForL1TechnicalTrigger.resize(m_numberTechnicalTriggers);
0199 
0200       m_algoTriggerSeedNotInL1Menu.reserve(m_numberAlgorithmTriggers);
0201       m_techTriggerSeedNotInL1Menu.reserve(m_numberTechnicalTriggers);
0202 
0203       for (unsigned int iHlt = 0; iHlt < m_hltConfig.size(); ++iHlt) {
0204         const std::string& hltPathName = m_hltConfig.triggerName(iHlt);
0205 
0206         const std::vector<std::pair<bool, std::string> >& hltL1Seed = m_hltConfig.hltL1GTSeeds(hltPathName);
0207 
0208         unsigned int numberHltL1GTSeeds = hltL1Seed.size();
0209 
0210         edm::LogVerbatim("L1GtTriggerMenuTester") << "\nPath: " << hltPathName << " :    <== " << numberHltL1GTSeeds
0211                                                   << " HLTLevel1GTSeed module(s)" << std::endl;
0212 
0213         for (unsigned int iSeedModule = 0; iSeedModule < numberHltL1GTSeeds; ++iSeedModule) {
0214           // one needs a non-const logical expression... TODO check why
0215           std::string m_l1SeedsLogicalExpression = (hltL1Seed[iSeedModule]).second;
0216 
0217           edm::LogVerbatim("L1GtTriggerMenuTester") << "      '" << m_l1SeedsLogicalExpression << "'";
0218 
0219           // parse logical expression
0220 
0221           if (m_l1SeedsLogicalExpression != "L1GlobalDecision") {
0222             // check also the logical expression - add/remove spaces if needed
0223             L1GtLogicParser m_l1AlgoLogicParser = L1GtLogicParser(m_l1SeedsLogicalExpression);
0224 
0225             // list of required algorithms for seeding
0226             std::vector<L1GtLogicParser::OperandToken> m_l1AlgoSeeds = m_l1AlgoLogicParser.expressionSeedsOperandList();
0227             size_t l1AlgoSeedsSize = m_l1AlgoSeeds.size();
0228 
0229             edm::LogVerbatim("L1GtTriggerMenuTester") << " :    <== " << l1AlgoSeedsSize << " L1 seeds" << std::endl;
0230 
0231             // for each algorithm trigger, check if it is in the L1 menu, get the bit number
0232             // and add path to the vector of strings for that bit number
0233 
0234             for (size_t i = 0; i < l1AlgoSeedsSize; ++i) {
0235               const std::string& trigNameOrAlias = (m_l1AlgoSeeds[i]).tokenName;
0236 
0237               CItAlgo itAlgo = m_algorithmAliasMap->find(trigNameOrAlias);
0238               if (itAlgo != m_algorithmAliasMap->end()) {
0239                 int bitNr = (itAlgo->second).algoBitNumber();
0240 
0241                 (m_hltPathsForL1AlgorithmTrigger.at(bitNr)).push_back(hltPathName);
0242 
0243                 edm::LogVerbatim("L1GtTriggerMenuTester")
0244                     << "         " << trigNameOrAlias << " bit " << bitNr << std::endl;
0245 
0246               } else {
0247                 if (m_noThrowIncompatibleMenu) {
0248                   edm::LogVerbatim("L1GtTriggerMenuTester")
0249                       << "         " << trigNameOrAlias << " trigger not in L1 menu " << m_l1GtMenu->gtTriggerMenuName()
0250                       << std::endl;
0251 
0252                   m_algoTriggerSeedNotInL1Menu.push_back(trigNameOrAlias);
0253 
0254                 } else {
0255                   throw cms::Exception("FailModule")
0256                       << "\nAlgorithm  " << trigNameOrAlias
0257                       << ", requested as seed by a HLT path, not found in the L1 trigger menu\n   "
0258                       << m_l1GtMenu->gtTriggerMenuName() << "\nIncompatible L1 and HLT menus.\n"
0259                       << std::endl;
0260                 }
0261               }
0262             }
0263           }
0264         }
0265       }
0266     }
0267   } else {
0268     // if init returns FALSE, initialization has NOT succeeded, which indicates a problem
0269     // with the file and/or code and needs to be investigated!
0270     edm::LogError("MyAnalyzer") << " HLT config extraction failure with process name " << m_hltProcessName;
0271   }
0272 }
0273 
0274 // printing template for a trigger group
0275 void L1GtTriggerMenuTester::printTriggerGroup(const std::string& trigGroupName,
0276                                               const std::map<std::string, const L1GtAlgorithm*>& trigGroup,
0277                                               const bool compactPrint,
0278                                               const bool printPfsRates) {
0279   // FIXME get values - either read from a specific L1 menu file, or from
0280   std::string lumiVal1 = "5.0E33";
0281   std::string lumiVal2 = "7.0E33";
0282   std::string trigComment;
0283 
0284   int trigPfVal1 = 0;
0285   int trigPfVal2 = 0;
0286 
0287   int trigRateVal1 = 0;
0288   int trigRateVal2 = 0;
0289 
0290   // cumulative list of L1 triggers not used as seed by HLT
0291   std::vector<std::string> algoTriggerNotSeed;
0292   algoTriggerNotSeed.reserve(m_numberAlgorithmTriggers);
0293 
0294   std::vector<std::string> techTriggerNotSeed;
0295   techTriggerNotSeed.reserve(m_numberTechnicalTriggers);
0296 
0297   // force a page break before each group
0298   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "<p style=\"page-break-before: always\">&nbsp;</p>";
0299 
0300   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "\n---++++ " << trigGroupName << "\n" << std::endl;
0301 
0302   if (compactPrint) {
0303     edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0304         << "|  *Trigger Name*  |  *Trigger Alias*  |  *Bit*  |  *Comments*  |" << std::endl;
0305 
0306   } else {
0307     if (printPfsRates) {
0308       edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "|  *Trigger Name*  |  *Trigger Alias*  |  *Bit*  |  "
0309                                                        "*Luminosity*  ||||  *Seed for !HLT path(s)*  |  *Comments*  |"
0310                                                     << std::endl;
0311 
0312       edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0313           << "|^|^|^|  *" << lumiVal1 << "*  ||  *" << lumiVal2 << "*  ||  **  |  **  |" << std::endl;
0314 
0315       edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0316           << "|^|^|^|  *PF*  |  *Rate*  |  *PF*  |  *Rate*  |  ** |  **  |" << std::endl;
0317 
0318     } else {
0319       edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0320           << "|  *Trigger Name*  |  *Trigger Alias*  |  *Bit*  |  *Seed for !HLT path(s)*  |" << std::endl;
0321     }
0322   }
0323 
0324   for (CItAlgoP itAlgo = trigGroup.begin(); itAlgo != trigGroup.end(); itAlgo++) {
0325     const std::string& aName = (itAlgo->second)->algoName();
0326     const std::string& aAlias = (itAlgo->second)->algoAlias();
0327     const int& bitNumber = (itAlgo->second)->algoBitNumber();
0328 
0329     // concatenate in a string, to simplify the next print instruction
0330     std::string seedsHlt;
0331     if (m_useHltMenu) {
0332       const std::vector<std::string>& hltPaths = m_hltPathsForL1AlgorithmTrigger.at(bitNumber);
0333 
0334       if (hltPaths.empty()) {
0335         algoTriggerNotSeed.push_back(aAlias);
0336         seedsHlt = "<font color = \"red\">Not used as seed by any !HLT path</font>";
0337       } else {
0338         for (std::vector<std::string>::const_iterator strIter = hltPaths.begin(); strIter != hltPaths.end();
0339              ++strIter) {
0340           seedsHlt = seedsHlt + (*strIter) + "<BR>";
0341         }
0342       }
0343     }
0344 
0345     if (compactPrint) {
0346       edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0347           << "|" << std::left << "[[" << (m_htmlFile + "#" + aName) << "][ " << aName << "]] "
0348           << "  |" << aAlias << "  |  " << bitNumber << "| |" << std::endl;
0349 
0350     } else {
0351       if (printPfsRates) {
0352         edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0353             << "|" << std::left << "[[" << (m_htmlFile + "#" + aName) << "][ " << aName << "]] "
0354             << "  |" << aAlias << "  |  " << bitNumber << "|  " << ((trigPfVal1 != 0) ? trigPfVal1 : 0) << "  |  "
0355             << ((trigRateVal1 != 0) ? trigRateVal1 : 0) << "  |  " << ((trigPfVal2 != 0) ? trigPfVal2 : 0) << "  |  "
0356             << ((trigRateVal2 != 0) ? trigRateVal2 : 0) << "  |  " << seedsHlt << "  |  " << trigComment << "  |"
0357             << std::endl;
0358 
0359       } else {
0360         edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0361             << "|" << std::left << "[[" << (m_htmlFile + "#" + aName) << "][ " << aName << "]] "
0362             << "  |" << aAlias << "  |  " << bitNumber << "|" << seedsHlt << "  |  " << std::endl;
0363       }
0364     }
0365   }
0366 
0367   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0368       << "\n"
0369       << trigGroupName << ": " << (trigGroup.size()) << " bits defined." << std::endl;
0370 
0371   if (m_useHltMenu && (!compactPrint)) {
0372     edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0373         << "\n Algorithm triggers from " << trigGroupName << " not used as seeds by !HLT:" << std::endl;
0374 
0375     if (!algoTriggerNotSeed.empty()) {
0376       for (std::vector<std::string>::const_iterator strIter = algoTriggerNotSeed.begin();
0377            strIter != algoTriggerNotSeed.end();
0378            ++strIter) {
0379         edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "   * " << (*strIter) << std::endl;
0380       }
0381 
0382     } else {
0383       edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "   * none" << std::endl;
0384     }
0385   }
0386 }
0387 
0388 /// printing in Wiki format
0389 void L1GtTriggerMenuTester::printWiki() {
0390   //
0391   // print menu, prescale factors and trigger mask in wiki format
0392   //
0393 
0394   // L1 GT prescale factors for algorithm triggers
0395 
0396   std::vector<int> prescaleFactorsAlgoTrig = m_prescaleFactorsAlgoTrig->at(m_indexPfSet);
0397 
0398   // L1 GT prescale factors for technical triggers
0399 
0400   std::vector<int> prescaleFactorsTechTrig = m_prescaleFactorsTechTrig->at(m_indexPfSet);
0401 
0402   // use another map <int, L1GtAlgorithm> to get the menu sorted after bit number
0403   // both algorithm and bit numbers are unique
0404   typedef std::map<int, const L1GtAlgorithm*>::const_iterator CItBit;
0405 
0406   //    algorithm triggers
0407 
0408   std::map<int, const L1GtAlgorithm*> algoBitToAlgo;
0409 
0410   std::map<std::string, const L1GtAlgorithm*> jetAlgoTrig;
0411   std::map<std::string, const L1GtAlgorithm*> egammaAlgoTrig;
0412   std::map<std::string, const L1GtAlgorithm*> esumAlgoTrig;
0413   std::map<std::string, const L1GtAlgorithm*> muonAlgoTrig;
0414   std::map<std::string, const L1GtAlgorithm*> crossAlgoTrig;
0415   std::map<std::string, const L1GtAlgorithm*> bkgdAlgoTrig;
0416 
0417   int algoTrigNumber = 0;
0418   int freeAlgoTrigNumber = 0;
0419 
0420   int jetAlgoTrigNumber = 0;
0421   int egammaAlgoTrigNumber = 0;
0422   int esumAlgoTrigNumber = 0;
0423   int muonAlgoTrigNumber = 0;
0424   int crossAlgoTrigNumber = 0;
0425   int bkgdAlgoTrigNumber = 0;
0426 
0427   for (CItAlgo itAlgo = m_algorithmMap->begin(); itAlgo != m_algorithmMap->end(); itAlgo++) {
0428     const int bitNumber = (itAlgo->second).algoBitNumber();
0429     const std::string& algName = (itAlgo->second).algoName();
0430 
0431     algoBitToAlgo[bitNumber] = &(itAlgo->second);
0432 
0433     algoTrigNumber++;
0434 
0435     // per category
0436 
0437     const ConditionMap& conditionMap = (m_l1GtMenu->gtConditionMap()).at((itAlgo->second).algoChipNumber());
0438 
0439     const std::vector<L1GtLogicParser::TokenRPN>& rpnVector = (itAlgo->second).algoRpnVector();
0440     const L1GtLogicParser::OperationType condOperand = L1GtLogicParser::OP_OPERAND;
0441 
0442     std::list<L1GtObject> listObjects;
0443 
0444     for (size_t i = 0; i < rpnVector.size(); ++i) {
0445       if ((rpnVector[i]).operation == condOperand) {
0446         const std::string& cndName = (rpnVector[i]).operand;
0447 
0448         // search the condition in the condition list
0449 
0450         bool foundCond = false;
0451 
0452         CItCond itCond = conditionMap.find(cndName);
0453         if (itCond != conditionMap.end()) {
0454           foundCond = true;
0455 
0456           // loop through object types and add them to the list
0457 
0458           const std::vector<L1GtObject>& objType = (itCond->second)->objectType();
0459 
0460           for (std::vector<L1GtObject>::const_iterator itObject = objType.begin(); itObject != objType.end();
0461                itObject++) {
0462             listObjects.push_back(*itObject);
0463 
0464             edm::LogVerbatim("L1GtTriggerMenuTester") << (*itObject) << std::endl;
0465           }
0466 
0467           // FIXME for XML parser, add GtExternal to objType correctly
0468           if ((itCond->second)->condCategory() == CondExternal) {
0469             listObjects.push_back(GtExternal);
0470           }
0471         }
0472 
0473         if (!foundCond) {
0474           // it should never be happen, all conditions are in the maps
0475           throw cms::Exception("FailModule") << "\nCondition " << cndName << " not found in the condition map"
0476                                              << " for chip number " << ((itAlgo->second).algoChipNumber()) << std::endl;
0477         }
0478       }
0479     }
0480 
0481     // eliminate duplicates
0482     listObjects.sort();
0483     listObjects.unique();
0484 
0485     // add the algorithm to the corresponding group
0486 
0487     bool jetGroup = false;
0488     bool egammaGroup = false;
0489     bool esumGroup = false;
0490     bool muonGroup = false;
0491     bool crossGroup = false;
0492     bool bkgdGroup = false;
0493 
0494     for (std::list<L1GtObject>::const_iterator itObj = listObjects.begin(); itObj != listObjects.end(); ++itObj) {
0495       switch (*itObj) {
0496         case Mu: {
0497           muonGroup = true;
0498         }
0499 
0500         break;
0501         case NoIsoEG: {
0502           egammaGroup = true;
0503         }
0504 
0505         break;
0506         case IsoEG: {
0507           egammaGroup = true;
0508         }
0509 
0510         break;
0511         case CenJet: {
0512           jetGroup = true;
0513         }
0514 
0515         break;
0516         case ForJet: {
0517           jetGroup = true;
0518         }
0519 
0520         break;
0521         case TauJet: {
0522           jetGroup = true;
0523         }
0524 
0525         break;
0526         case ETM: {
0527           esumGroup = true;
0528 
0529         }
0530 
0531         break;
0532         case ETT: {
0533           esumGroup = true;
0534 
0535         }
0536 
0537         break;
0538         case HTT: {
0539           esumGroup = true;
0540 
0541         }
0542 
0543         break;
0544         case HTM: {
0545           esumGroup = true;
0546 
0547         }
0548 
0549         break;
0550         case JetCounts: {
0551           // do nothing - not available
0552         }
0553 
0554         break;
0555         case HfBitCounts: {
0556           bkgdGroup = true;
0557         }
0558 
0559         break;
0560         case HfRingEtSums: {
0561           bkgdGroup = true;
0562         }
0563 
0564         break;
0565         case GtExternal: {
0566           bkgdGroup = true;
0567         }
0568 
0569         break;
0570         case TechTrig:
0571         case Castor:
0572         case BPTX:
0573         default: {
0574           // should not arrive here
0575 
0576           edm::LogVerbatim("L1GtTriggerMenuTester") << "\n      Unknown object of type " << *itObj << std::endl;
0577         } break;
0578       }
0579     }
0580 
0581     int sumGroup = jetGroup + egammaGroup + esumGroup + muonGroup + crossGroup + bkgdGroup;
0582 
0583     if (sumGroup > 1) {
0584       crossAlgoTrig[algName] = &(itAlgo->second);
0585     } else {
0586       if (jetGroup) {
0587         jetAlgoTrig[algName] = &(itAlgo->second);
0588 
0589       } else if (egammaGroup) {
0590         egammaAlgoTrig[algName] = &(itAlgo->second);
0591 
0592       } else if (esumGroup && (listObjects.size() > 1)) {
0593         crossAlgoTrig[algName] = &(itAlgo->second);
0594 
0595       } else if (esumGroup) {
0596         esumAlgoTrig[algName] = &(itAlgo->second);
0597 
0598       } else if (muonGroup) {
0599         muonAlgoTrig[algName] = &(itAlgo->second);
0600 
0601       } else if (bkgdGroup) {
0602         bkgdAlgoTrig[algName] = &(itAlgo->second);
0603 
0604       } else {
0605         // do nothing
0606       }
0607     }
0608 
0609     edm::LogVerbatim("L1GtTriggerMenuTester")
0610         << algName << " sum: " << sumGroup << " size: " << listObjects.size() << std::endl;
0611   }
0612 
0613   freeAlgoTrigNumber = m_numberAlgorithmTriggers - algoTrigNumber;
0614 
0615   jetAlgoTrigNumber = jetAlgoTrig.size();
0616   egammaAlgoTrigNumber = egammaAlgoTrig.size();
0617   esumAlgoTrigNumber = esumAlgoTrig.size();
0618   muonAlgoTrigNumber = muonAlgoTrig.size();
0619   crossAlgoTrigNumber = crossAlgoTrig.size();
0620   bkgdAlgoTrigNumber = bkgdAlgoTrig.size();
0621 
0622   //    technical triggers
0623   std::map<int, const L1GtAlgorithm*> techBitToAlgo;
0624 
0625   int techTrigNumber = 0;
0626   int freeTechTrigNumber = 0;
0627 
0628   for (CItAlgo itAlgo = m_technicalTriggerMap->begin(); itAlgo != m_technicalTriggerMap->end(); itAlgo++) {
0629     int bitNumber = (itAlgo->second).algoBitNumber();
0630     techBitToAlgo[bitNumber] = &(itAlgo->second);
0631 
0632     techTrigNumber++;
0633   }
0634 
0635   freeTechTrigNumber = m_numberTechnicalTriggers - techTrigNumber;
0636 
0637   // name of the attached HTML file
0638   if (!m_overwriteHtmlFile) {
0639     std::string menuName = m_l1GtMenu->gtTriggerMenuImplementation();
0640 
0641     // replace "/" with "_"
0642     std::replace(menuName.begin(), menuName.end(), '/', '_');
0643     m_htmlFile = "%ATTACHURL%/" + menuName + ".html";
0644   } else {
0645     m_htmlFile = "%ATTACHURL%/" + m_htmlFile;
0646   }
0647 
0648   // header for printing algorithms
0649 
0650   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0651       << "\n   ********** L1 Trigger Menu - printing in wiki format  ********** \n\n"
0652       << "\n---+++ L1 menu identification\n"
0653       << "\n|L1 Trigger Menu Interface: |!" << m_l1GtMenu->gtTriggerMenuInterface() << " |"
0654       << "\n|L1 Trigger Menu Name: |!" << m_l1GtMenu->gtTriggerMenuName() << " |"
0655       << "\n|L1 Trigger Menu Implementation: |!" << m_l1GtMenu->gtTriggerMenuImplementation() << " |"
0656       << "\n|Associated L1 scale DB key: |!" << m_l1GtMenu->gtScaleDbKey() << " |"
0657       << "\n\n"
0658       << std::flush << std::endl;
0659 
0660   // Overview page
0661   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "\n---+++ Summary\n" << std::endl;
0662   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0663       << "   * Number of algorithm triggers: " << algoTrigNumber << " defined, 128 possible." << std::endl;
0664   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0665       << "   * Number of technical triggers: " << techTrigNumber << " defined,  64 possible.<BR><BR>" << std::endl;
0666 
0667   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0668       << "   * Number of free bits for algorithm triggers: " << freeAlgoTrigNumber << std::endl;
0669   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0670       << "   * Number of free bits for technical triggers: " << freeTechTrigNumber << "<BR>" << std::endl;
0671 
0672   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "\nNumber of algorithm triggers per trigger group\n" << std::endl;
0673   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "    | *Trigger group* | *Number of bits used*|" << std::endl;
0674   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0675       << "    | Jet algorithm triggers: |  " << jetAlgoTrigNumber << "|" << std::endl;
0676   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0677       << "    | EGamma algorithm triggers: |  " << egammaAlgoTrigNumber << "|" << std::endl;
0678   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0679       << "    | Energy sum algorithm triggers: |  " << esumAlgoTrigNumber << "|" << std::endl;
0680   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0681       << "    | Muon algorithm triggers: |  " << muonAlgoTrigNumber << "|" << std::endl;
0682   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0683       << "    | Cross algorithm triggers: |  " << crossAlgoTrigNumber << "|" << std::endl;
0684   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0685       << "    | Background algorithm triggers: |  " << bkgdAlgoTrigNumber << "|" << std::endl;
0686 
0687   // force a page break
0688   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "<p style=\"page-break-before: always\">&nbsp;</p>";
0689 
0690   // compact print - without HLT path
0691   bool compactPrint = true;
0692 
0693   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "\n---+++ List of algorithm triggers sorted by trigger groups\n"
0694                                                 << std::endl;
0695 
0696   // Jet algorithm triggers
0697   printTriggerGroup("Jet algorithm triggers", jetAlgoTrig, compactPrint, m_printPfsRates);
0698 
0699   // EGamma algorithm triggers
0700   printTriggerGroup("EGamma algorithm triggers", egammaAlgoTrig, compactPrint, m_printPfsRates);
0701 
0702   // Energy sum algorithm triggers
0703   printTriggerGroup("Energy sum algorithm triggers", esumAlgoTrig, compactPrint, m_printPfsRates);
0704 
0705   // Muon algorithm triggers
0706   printTriggerGroup("Muon algorithm triggers", muonAlgoTrig, compactPrint, m_printPfsRates);
0707 
0708   // Cross algorithm triggers
0709   printTriggerGroup("Cross algorithm triggers", crossAlgoTrig, compactPrint, m_printPfsRates);
0710 
0711   // Background algorithm triggers
0712   printTriggerGroup("Background algorithm triggers", bkgdAlgoTrig, compactPrint, m_printPfsRates);
0713 
0714   // force a page break
0715   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "<p style=\"page-break-before: always\">&nbsp;</p>";
0716 
0717   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "\n---+++ List of algorithm triggers sorted by bits\n" << std::endl;
0718 
0719   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "| *Algorithm* | *Alias* | *Bit number* |" << std::endl;
0720 
0721   for (CItBit itBit = algoBitToAlgo.begin(); itBit != algoBitToAlgo.end(); itBit++) {
0722     int bitNumber = itBit->first;
0723     std::string aName = (itBit->second)->algoName();
0724     std::string aAlias = (itBit->second)->algoAlias();
0725 
0726     edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0727         << "|" << std::left << "[[" << (m_htmlFile + "#" + aName) << "][ " << aName << "]] "
0728         << "  |" << aAlias << "  |  " << bitNumber << "| |" << std::endl;
0729   }
0730 
0731   // force a page break
0732   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "<p style=\"page-break-before: always\">&nbsp;</p>";
0733   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "\n---+++ List of technical triggers\n" << std::endl;
0734 
0735   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "| *Technical trigger* | *Bit number* |" << std::endl;
0736 
0737   for (CItBit itBit = techBitToAlgo.begin(); itBit != techBitToAlgo.end(); itBit++) {
0738     int bitNumber = itBit->first;
0739     std::string aName = (itBit->second)->algoName();
0740     std::string aAlias = (itBit->second)->algoAlias();
0741 
0742     edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0743         << "|!" << std::left << aName << "  |  " << std::right << bitNumber << " |" << std::endl;
0744   }
0745 
0746   // force a page break
0747   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << "<p style=\"page-break-before: always\">&nbsp;</p>";
0748 
0749   // compact print false: with HLT path association, if the parameter m_useHltMenu is true
0750   // otherwise, we have no association computed
0751 
0752   if (m_useHltMenu) {
0753     compactPrint = false;
0754   } else {
0755     return;
0756   }
0757 
0758   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0759       << "\n---+++ List of algorithm triggers sorted by trigger groups, including !HLT path association \n"
0760       << std::endl;
0761 
0762   edm::LogVerbatim("L1GtTriggerMenuTesterWiki")
0763       << "\n The following !HLT menu was used to associate the !HLT path to the L1 algorithm triggers:\n    "
0764       << std::endl;
0765   edm::LogVerbatim("L1GtTriggerMenuTesterWiki") << m_hltTableName << std::endl;
0766 
0767   // Jet algorithm triggers
0768   printTriggerGroup("Jet algorithm triggers", jetAlgoTrig, compactPrint, m_printPfsRates);
0769 
0770   // EGamma algorithm triggers
0771   printTriggerGroup("EGamma algorithm triggers", egammaAlgoTrig, compactPrint, m_printPfsRates);
0772 
0773   // Energy sum algorithm triggers
0774   printTriggerGroup("Energy sum algorithm triggers", esumAlgoTrig, compactPrint, m_printPfsRates);
0775 
0776   // Muon algorithm triggers
0777   printTriggerGroup("Muon algorithm triggers", muonAlgoTrig, compactPrint, m_printPfsRates);
0778 
0779   // Cross algorithm triggers
0780   printTriggerGroup("Cross algorithm triggers", crossAlgoTrig, compactPrint, m_printPfsRates);
0781 
0782   // Background algorithm triggers
0783   printTriggerGroup("Background algorithm triggers", bkgdAlgoTrig, compactPrint, m_printPfsRates);
0784 }