Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:06:55

0001 /*
0002  * =====================================================================================
0003  *
0004  *       Filename:  Configuration.h
0005  *
0006  *    Description:  CSCDQM Configuration parameter storage
0007  *
0008  *        Version:  1.0
0009  *        Created:  10/03/2008 10:26:04 AM
0010  *       Revision:  none
0011  *       Compiler:  gcc
0012  *
0013  *         Author:  Valdas Rapsevicius, valdas.rapsevicius@cern.ch
0014  *        Company:  CERN, CH
0015  *
0016  * =====================================================================================
0017  */
0018 
0019 #ifndef CSCDQM_Configuration_H
0020 #define CSCDQM_Configuration_H
0021 
0022 #include <string>
0023 #include <sstream>
0024 #include <ctime>
0025 #include <functional>
0026 
0027 #include <xercesc/parsers/XercesDOMParser.hpp>
0028 #include <xercesc/dom/DOMNodeList.hpp>
0029 #include <xercesc/dom/DOMElement.hpp>
0030 #include <xercesc/dom/DOMComment.hpp>
0031 #include <xercesc/sax/ErrorHandler.hpp>
0032 #include <xercesc/sax/SAXParseException.hpp>
0033 #include <xercesc/dom/DOMImplementation.hpp>
0034 #include <xercesc/framework/StdOutFormatTarget.hpp>
0035 #include <xercesc/dom/DOM.hpp>
0036 
0037 #include <boost/multi_index_container.hpp>
0038 #include <boost/multi_index/member.hpp>
0039 #include <boost/multi_index/composite_key.hpp>
0040 #include <boost/multi_index/ordered_index.hpp>
0041 #include "boost/tuple/tuple.hpp"
0042 
0043 #include <boost/preprocessor/tuple/elem.hpp>
0044 #include <boost/preprocessor/seq/for_each_i.hpp>
0045 #include <boost/preprocessor/stringize.hpp>
0046 #include <boost/preprocessor/cat.hpp>
0047 #include <boost/preprocessor/comparison/equal.hpp>
0048 
0049 /** Headers for Global DQM Only */
0050 #ifdef DQMGLOBAL
0051 
0052 #include <FWCore/ParameterSet/interface/ParameterSet.h>
0053 
0054 #endif
0055 
0056 #include "CSCDQM_MonitorObjectProvider.h"
0057 #include "CSCDQM_Exception.h"
0058 #include "CSCDQM_Utility.h"
0059 #include "CSCDQM_Logger.h"
0060 
0061 /** Length of Global Parameter sequence */
0062 #define CONFIG_PARAMETERS_SEQ_LEN 4
0063 
0064 /** 
0065  * Sequence of Global Parameters. Add new line or edit existing in form:
0066  * (( type (C++), name (upper case), default value, "description" )) \
0067  */
0068 #define CONFIG_PARAMETERS_SEQ                                                                                           \
0069                                                                                                                         \
0070   ((bool, PROCESS_DDU, true, "enter DDU (and latter Chamber) sections (EventProcessor flag)"))(                         \
0071       (bool, PROCESS_CSC, true, "enter Chamber section (EventProcessor flag)"))(                                        \
0072       (bool, PROCESS_EFF_HISTOS, true, "calculate efficiency histograms (Dispatcher flag)"))(                           \
0073       (bool, PROCESS_EFF_PARAMETERS, true, "calculate efficiency parameters (EventProcessor flag)"))(                   \
0074       (bool, BINCHECKER_CRC_ALCT, false, "check ALCT CRC (CSCDCCExaminer flag)"))(                                      \
0075       (bool, BINCHECKER_CRC_CLCT, false, "check CLCT CRC (CSCDCCExaminer flag)"))(                                      \
0076       (bool, BINCHECKER_CRC_CFEB, false, "check CFEB CRC (CSCDCCExaminer flag)"))(                                      \
0077       (bool, BINCHECKER_MODE_DDU, true, "set DDU mode (CSCDCCExaminer flag)"))(                                         \
0078       (bool, BINCHECKER_OUTPUT, false, "print 1 and 2 output (CSCDCCExaminer flag)"))(                                  \
0079       (bool,                                                                                                            \
0080        FRAEFF_AUTO_UPDATE,                                                                                              \
0081        false,                                                                                                           \
0082        "start fractional and efficiency histogram update automatically (Dispatcher flag)"))(                            \
0083       (bool,                                                                                                            \
0084        FRAEFF_SEPARATE_THREAD,                                                                                          \
0085        false,                                                                                                           \
0086        "start fractional and efficiency histogram update on separate thread (EventProcessor flag)"))(                   \
0087       (bool, PRINT_STATS_ON_EXIT, true, "print statistics on exit (destruction)"))(                                     \
0088       (bool, IN_FULL_STANDBY, true, "full detector is in standby mode from the beginning of the run"))(                 \
0089       (std::string, BOOKING_XML_FILE, "", "histogram description (booking) file in XML format (Collection)"))(          \
0090       (std::string, FOLDER_EMU, "", "root file folder name to be used for EMU histograms (EventProcessor)"))(           \
0091       (std::string, FOLDER_DDU, "", "root file folder name to be used for DDU histograms (EventProcessor)"))(           \
0092       (std::string, FOLDER_CSC, "", "root file folder name to be used for CSC histograms (EventProcessor)"))(           \
0093       (std::string, FOLDER_PAR, "", "root file folder name to be used for parameters (EventProcessor)"))((              \
0094       unsigned int, DDU_CHECK_MASK, 0xFFFFFFFF, "mask for cumulative EmuFileReader DDU error flags (EventProcessor)"))( \
0095       (unsigned int, DDU_BINCHECK_MASK, 0x02080016, "mask for DDU level examiner errors (CSCDCCExaminer)"))(            \
0096       (unsigned int, BINCHECK_MASK, 0xFFFFFFFF, "mask for chamber level examiner errors (CSCDCCExaminer)"))(            \
0097       (unsigned int,                                                                                                    \
0098        FRAEFF_AUTO_UPDATE_START,                                                                                        \
0099        5,                                                                                                               \
0100        "event number to start automatic fractional and efficiency histogram updates from (Dispatcer)"))(                \
0101       (unsigned int,                                                                                                    \
0102        FRAEFF_AUTO_UPDATE_FREQ,                                                                                         \
0103        1,                                                                                                               \
0104        "frequency in events to perform automatic fractional and efficiency histogram updates (Dispatcher)"))((          \
0105       double, EFF_COLD_THRESHOLD, 0.1, "threshold in fraction to check for cold (not reporting) HW (EventProcessor)"))( \
0106       (double, EFF_COLD_SIGFAIL, 5.0, "statistical significance for cold (not reporting) HW (EventProcessor)"))(        \
0107       (double, EFF_HOT_THRESHOLD, 0.1, "threshold in fraction to check for hot HW (EventProcessor)"))(                  \
0108       (double, EFF_HOT_SIGFAIL, 5.0, "statistical significance for hot HW (EventProcessor)"))(                          \
0109       (double, EFF_ERR_THRESHOLD, 0.1, "threshold in fraction to check for errors in HW (EventProcessor)"))(            \
0110       (double, EFF_ERR_SIGFAIL, 5.0, "statistical significance for errors in HW (EventProcessor)"))(                    \
0111       (double,                                                                                                          \
0112        EFF_NODATA_THRESHOLD,                                                                                            \
0113        0.1,                                                                                                             \
0114        "threshold in fraction to check for not reporting elements in HW (EventProcessor)"))(                            \
0115       (double, EFF_NODATA_SIGFAIL, 5.0, "statistical significance for not reportingelements in HW (EventProcessor)"))(  \
0116       (unsigned int, EVENTS_ECHO, 1000, "frequency in events to print echo message (EventProcessor)"))(                 \
0117       (std::string, FOLDER_FED, "", "root file folder name to be used for FED histograms (EventProcessor)"))(           \
0118       (bool, PREBOOK_ALL_HISTOS, true, "pre-book all FED, DDU, CSC histogragrams before run begins"))
0119 
0120 /**
0121  * Global Parameter Manipulation macros.
0122  */
0123 
0124 /** Parameter as class property definition */
0125 #define CONFIG_PARAMETER_DEFINE_MACRO(r, data, i, elem) \
0126   BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem) BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem);
0127 
0128 /** Parameter Default value definition (in constructor) */
0129 #define CONFIG_PARAMETER_DEFAULT_MACRO(r, data, i, elem) \
0130   BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem) = BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 2, elem);
0131 
0132 /** Parameter Getter method */
0133 #define CONFIG_PARAMETER_GETTER_MACRO(r, data, i, elem)                                    \
0134   const BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem)                            \
0135       BOOST_PP_CAT(get, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))() const { \
0136     return BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem);                        \
0137   }
0138 
0139 /** Parameter Setter method */
0140 #define CONFIG_PARAMETER_SETTER_MACRO(r, data, i, elem)                            \
0141   void BOOST_PP_CAT(set, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))( \
0142       BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem) p) {                 \
0143     BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem) = p;                   \
0144   }
0145 
0146 #ifdef DQMGLOBAL
0147 
0148 /** Load parameter from parameters set line (Global DQM) */
0149 #define CONFIG_PARAMETER_LOADPS_MACRO(r, data, i, elem)                               \
0150   BOOST_PP_CAT(set, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))          \
0151   (ps.getUntrackedParameter<BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem)>( \
0152       BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem)),    \
0153                          BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 2, elem)));
0154 
0155 #endif
0156 
0157 #ifdef DQMLOCAL
0158 
0159 /** Load parameter from XML node line (Local DQM) */
0160 #define CONFIG_PARAMETER_LOADXML_MACRO(r, data, i, elem)                                                    \
0161   if (nodeName.compare(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))) == 0) { \
0162     stm >> BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem);                                         \
0163     continue;                                                                                               \
0164   }
0165 
0166 /** Include parameter into XML stream for printing */
0167 #define CONFIG_PARAMETER_PRINTXML_MACRO(r, data, i, elem)                                                              \
0168   {                                                                                                                    \
0169     DOMComment* comment =                                                                                              \
0170         doc->createComment(XERCES_TRANSCODE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 3, elem)));                 \
0171     DOMElement* el = doc->createElement(                                                                               \
0172         XERCES_TRANSCODE(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))));                \
0173     std::string value = toString(config.BOOST_PP_CAT(get, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))()); \
0174     DOMText* tdata = doc->createTextNode(XERCES_TRANSCODE(value.c_str()));                                             \
0175     el->appendChild(tdata);                                                                                            \
0176     rootElem->appendChild(comment);                                                                                    \
0177     rootElem->appendChild(el);                                                                                         \
0178   }
0179 
0180 #endif
0181 
0182 namespace cscdqm {
0183 
0184   /** @brief MO filter Item definition (loaded from XML/PSet) */
0185   struct MOFilterItem {
0186     /** Regexp filter pattern */
0187     TPRegexp pattern;
0188     /** Include filtered item or not */
0189     bool include;
0190     /** Constructor */
0191     MOFilterItem(const std::string pattern_, const bool include_) : pattern(pattern_.c_str()), include(include_) {}
0192   };
0193 
0194   /** @brief Chamber level counter types */
0195   enum ChamberCounterType {
0196     DMB_EVENTS,
0197     BAD_EVENTS,
0198     DMB_TRIGGERS,
0199     ALCT_TRIGGERS,
0200     CLCT_TRIGGERS,
0201     CFEB_TRIGGERS,
0202     EVENT_DISPLAY_PLOT
0203   };
0204 
0205   /** Single Chamber counters type */
0206   typedef std::map<ChamberCounterType, uint32_t> ChamberCounterMapType;
0207 
0208   /** @brief Chamber Counters key type */
0209   struct ChamberCounterKeyType {
0210     HwId crateId;
0211     HwId dmbId;
0212     ChamberCounterMapType counters;
0213     ChamberCounterKeyType(const HwId& crateId_, const HwId& dmbId_, const ChamberCounterMapType& c_)
0214         : crateId(crateId_), dmbId(dmbId_), counters(c_) {}
0215   };
0216 
0217   /** Map of Chamber Counters Type */
0218   typedef boost::multi_index_container<
0219       ChamberCounterKeyType,
0220       boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::composite_key<
0221           ChamberCounterKeyType,
0222           boost::multi_index::member<ChamberCounterKeyType, HwId, &ChamberCounterKeyType::crateId>,
0223           boost::multi_index::member<ChamberCounterKeyType, HwId, &ChamberCounterKeyType::dmbId> > > > >
0224       ChamberMapCounterMapType;
0225 
0226   /**
0227    * @class Configuration
0228    * @brief CSCDQM Framework Global Configuration
0229    */
0230   class Configuration {
0231   private:
0232     unsigned short printStatsLocal;
0233 
0234     /** Map of MO Filters */
0235     std::vector<MOFilterItem> MOFilterItems;
0236 
0237     /** Define parameters */
0238     BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_DEFINE_MACRO, _, CONFIG_PARAMETERS_SEQ)
0239 
0240     /**
0241        * @brief  Initialize parameter values and reset counters (used by constructors)
0242        * @return 
0243        */
0244     void init() {
0245       /** Assign default values to parameters */
0246       BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_DEFAULT_MACRO, _, CONFIG_PARAMETERS_SEQ)
0247       globalTimer = eventTimer = fraTimer = effTimer = std::clock();
0248       reset();
0249     }
0250 
0251   public:
0252     /**
0253         * Pointers to Shared functions (created in Dispatcher)
0254         */
0255 
0256     /** Get MO Globally */
0257     std::function<bool(const HistoDef& histoT, MonitorObject*&)> fnGetHisto;
0258 
0259     /** Pointers to Cache Functions */
0260     std::function<bool(const HistoId id, MonitorObject*& mo)> fnGetCacheEMUHisto;
0261     std::function<bool(const HistoId id, const HwId& id1, MonitorObject*& mo)> fnGetCacheFEDHisto;
0262     std::function<bool(const HistoId id, const HwId& id1, MonitorObject*& mo)> fnGetCacheDDUHisto;
0263     std::function<bool(const HistoId id, const HwId& id1, const HwId& id2, const HwId& id3, MonitorObject*& mo)>
0264         fnGetCacheCSCHisto;
0265     std::function<bool(const HistoId id, MonitorObject*& mo)> fnGetCacheParHisto;
0266     std::function<void(const HistoDef& histoT, MonitorObject*&)> fnPutHisto;
0267     std::function<bool(unsigned int&, unsigned int&, unsigned int&)> fnNextBookedCSC;
0268     std::function<bool(unsigned int&, unsigned int&)> fnIsBookedCSC;
0269     std::function<bool(unsigned int&)> fnIsBookedDDU;
0270     std::function<bool(unsigned int&)> fnIsBookedFED;
0271 
0272     /** Pointer to Collection Book Function */
0273     std::function<MonitorObject*(const HistoBookRequest&)> fnBook;
0274 
0275     /** Pointer to CSC Det Id function */
0276     std::function<bool(const unsigned int, const unsigned int, CSCDetId&)> fnGetCSCDetId;
0277 
0278     /** Parameter Getters */
0279     BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_GETTER_MACRO, _, CONFIG_PARAMETERS_SEQ)
0280 
0281     /** Parameter Setters */
0282     BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_SETTER_MACRO, _, CONFIG_PARAMETERS_SEQ)
0283 
0284     /**
0285        * @brief  Constructor
0286        */
0287     Configuration() {
0288       init();
0289       printStatsLocal = 0;
0290     }
0291 
0292     /**
0293        * @brief  Constructor
0294        * @param printStats Print statistics on exit or not (overrides configuration parameter)
0295        */
0296     Configuration(const bool printStats) {
0297       init();
0298       if (printStats) {
0299         printStatsLocal = 1;
0300       } else {
0301         printStatsLocal = 2;
0302       }
0303     }
0304 
0305     /**
0306        * @brief  Destructor
0307        */
0308     ~Configuration() {
0309       if ((PRINT_STATS_ON_EXIT && printStatsLocal == 0) || printStatsLocal == 1) {
0310         printStats();
0311       }
0312     }
0313 
0314 #ifdef DQMLOCAL
0315 
0316     /**
0317        * @brief  Load parameters from XML file (Local DQM)
0318        * @param  configFile Parameters file in XML format
0319        * @return 
0320        */
0321     void load(const std::string& configFile) {
0322       cms::concurrency::xercesInitialize();
0323 
0324       {
0325         XercesDOMParser parser;
0326 
0327         XMLFileErrorHandler eh;
0328         parser.setErrorHandler(&eh);
0329 
0330         parser.parse(configFile.c_str());
0331         DOMDocument* doc = parser.getDocument();
0332         DOMNode* docNode = (DOMNode*)doc->getDocumentElement();
0333 
0334         DOMNodeList* itemList = docNode->getChildNodes();
0335         for (XMLSize_t i = 0; i < itemList->getLength(); i++) {
0336           DOMNode* node = itemList->item(i);
0337           if (node->getNodeType() != DOMNode::ELEMENT_NODE) {
0338             continue;
0339           }
0340 
0341           std::string nodeName = XMLString::transcode(node->getNodeName());
0342           std::string value = XMLString::transcode(node->getTextContent());
0343           std::istringstream stm(value);
0344 
0345           BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_LOADXML_MACRO, _, CONFIG_PARAMETERS_SEQ)
0346 
0347           if (nodeName.compare("MO_FILTER") == 0) {
0348             DOMNodeList* filterList = node->getChildNodes();
0349             for (XMLSize_t j = 0; j < filterList->getLength(); j++) {
0350               DOMNode* filter = filterList->item(j);
0351               if (filter->getNodeType() != DOMNode::ELEMENT_NODE) {
0352                 continue;
0353               }
0354               std::string filterName = XMLString::transcode(filter->getNodeName());
0355               std::string filterValue = XMLString::transcode(filter->getTextContent());
0356               MOFilterItems.insert(MOFilterItems.end(),
0357                                    MOFilterItem(filterValue, (filterName.compare("INCLUDE") == 0)));
0358             }
0359           }
0360         }
0361       }
0362 
0363       cms::concurrency::xercesTerminate();
0364     }
0365 
0366     /**
0367        * @brief  Print configuration in XML format
0368        * @param  config Configuration object to print
0369        * @return 
0370        */
0371     static void printXML(const Configuration& config) {
0372       cms::concurrency::xercesInitialize();
0373 
0374       DOMImplementation* domImpl = DOMImplementationRegistry::getDOMImplementation(XERCES_TRANSCODE("core"));
0375       DOMDocument* doc = domImpl->createDocument(0, XERCES_TRANSCODE("processor_configuration"), 0);
0376       DOMElement* rootElem = doc->getDocumentElement();
0377 
0378       BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_PRINTXML_MACRO, _, CONFIG_PARAMETERS_SEQ)
0379 
0380       DOMLSSerializer* ser = domImpl->createLSSerializer();
0381       if (ser->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)) {
0382         ser->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
0383       }
0384       XMLFileErrorHandler eh;
0385       ser->setErrorHandler((DOMErrorHandler*)&eh);
0386       ser->writeNode(new StdOutFormatTarget(), *doc);
0387 
0388       doc->release();
0389       cms::concurrency::xercesTerminate();
0390     }
0391 
0392 #endif
0393 
0394 #ifdef DQMGLOBAL
0395 
0396     /**
0397        * @brief  Load parameters from ParameterSet (Global DQM)
0398        * @param  ps ParameterSet to load parameters from
0399        * @return 
0400        */
0401     void load(const edm::ParameterSet& ps) {
0402       BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_LOADPS_MACRO, _, CONFIG_PARAMETERS_SEQ)
0403       std::vector<std::string> moFilter = ps.getUntrackedParameter<std::vector<std::string> >("MO_FILTER");
0404       for (std::vector<std::string>::iterator it = moFilter.begin(); it != moFilter.end(); it++) {
0405         std::string f = *it;
0406         if (!Utility::regexMatch("^[-+]/.*/$", f)) {
0407           LOG_WARN << "MO_FILTER item " << f << " does not recognized to be a valid one. Skipping...";
0408           continue;
0409         }
0410         bool include = Utility::regexMatch("^[+]", f);
0411         Utility::regexReplace("^./(.*)/$", f, "$1");
0412         MOFilterItems.insert(MOFilterItems.end(), MOFilterItem(f, include));
0413       }
0414     }
0415 
0416 #endif
0417 
0418     /**
0419       * Statistics collection and printing section
0420       */
0421 
0422   private:
0423     /** Global Timer */
0424     std::clock_t globalTimer;
0425 
0426     /** Event processing Timer */
0427     std::clock_t eventTimer;
0428 
0429     /** Fractional MO update Timer */
0430     std::clock_t fraTimer;
0431 
0432     /** Efficiency MO update Timer */
0433     std::clock_t effTimer;
0434 
0435     /** Event processing time cummulative */
0436     double eventTimeSum;
0437 
0438     /** Fractional MO update time cummulative */
0439     double fraTimeSum;
0440 
0441     /** Efficiency MO update time cummulative */
0442     double effTimeSum;
0443 
0444   public:
0445 /** Statistics field definition */
0446 #define STATFIELD(caption, value, units)                                            \
0447   logger << std::setfill(' ');                                                      \
0448   logger << std::setiosflags(std::ios::right) << std::setw(25) << caption << " : "; \
0449   logger << std::setiosflags(std::ios::right) << std::setw(12);                     \
0450   if (((double)value) < 0) {                                                        \
0451     logger << "NA";                                                                 \
0452   } else {                                                                          \
0453     logger << value;                                                                \
0454   }                                                                                 \
0455   logger << std::setiosflags(std::ios::left) << std::setw(2) << units;              \
0456   logger << std::endl;
0457 
0458 /** Statistics separator definition */
0459 #define SEPFIELD                 \
0460   logger << std::setfill('-');   \
0461   logger << std::setw(25) << ""; \
0462   logger << std::setw(10) << ""; \
0463   logger << std::setw(2) << "";  \
0464   logger << std::endl;
0465 
0466     /**
0467        * @brief  Print Statistics on Exit (Destruction)
0468        * @return 
0469        */
0470     void printStats() {
0471       double allTime = double(std::clock() - globalTimer) / CLOCKS_PER_SEC;
0472       LogInfo logger;
0473       logger << std::endl;
0474 
0475       STATFIELD("Events processed", nEvents, "")
0476       STATFIELD("Bad events", nEventsBad, "")
0477       STATFIELD("Good events", nEventsGood, "")
0478       STATFIELD("CSC DCC events", nEventsCSC, "")
0479       STATFIELD("Unpacked CSCs", nUnpackedCSC, "")
0480 
0481       SEPFIELD
0482 
0483       STATFIELD("All event time", eventTimeSum, "s")
0484       double eventTimeAverage = (nEvents > 0 ? eventTimeSum / nEvents : -1.0);
0485       STATFIELD("Avg. event time", eventTimeAverage, "s")
0486       double eventRateAverage = (eventTimeSum > 0 ? nEvents / eventTimeSum : -1.0);
0487       STATFIELD("Avg. event rate", eventRateAverage, "Hz")
0488       double chamberRateAverage = (eventTimeSum > 0 ? nUnpackedCSC / eventTimeSum : -1.0);
0489       STATFIELD("Avg. chamber rate", chamberRateAverage, "Hz")
0490 
0491       SEPFIELD
0492 
0493       STATFIELD("All fra update time", fraTimeSum, "s")
0494       STATFIELD("All fra update count", fraCount, "")
0495       double fraTimeAverage = (fraCount > 0 ? fraTimeSum / fraCount : -1.0);
0496       STATFIELD("Avg. fra update time", fraTimeAverage, "s")
0497 
0498       SEPFIELD
0499 
0500       STATFIELD("All eff update time", effTimeSum, "s")
0501       STATFIELD("All eff update count", effCount, "")
0502       double effTimeAverage = (effCount > 0 ? effTimeSum / effCount : -1.0);
0503       STATFIELD("Avg. eff update time", effTimeAverage, "s")
0504 
0505       SEPFIELD
0506 
0507       STATFIELD("All time", allTime, "s")
0508       double allTimeAverage = (nEvents > 0 ? allTime / nEvents : -1.0);
0509       STATFIELD("Avg. event all time", allTimeAverage, "s")
0510       double allRateAverage = (allTime > 0 ? nEvents / allTime : -1.0);
0511       STATFIELD("Avg. event all rate", allRateAverage, "Hz")
0512       double chamberAllRateAverage = (allTime > 0 ? nUnpackedCSC / allTime : -1.0);
0513       STATFIELD("Avg. chamber all rate", chamberAllRateAverage, "Hz")
0514     }
0515 
0516 #undef STATFIELD
0517 #undef SEPFIELD
0518 
0519     /**
0520        * @brief  Switch on/off event processing timer
0521        * @param start timer action (true - start, false - stop) 
0522        * @return 
0523        */
0524     void eventProcessTimer(const bool start) {
0525       if (start) {
0526         eventTimer = std::clock();
0527       } else {
0528         eventTimeSum += double(std::clock() - eventTimer) / CLOCKS_PER_SEC;
0529       }
0530     }
0531 
0532     /**
0533        * @brief  Switch on/off fractional MO processing timer
0534        * @param start timer action (true - start, false - stop) 
0535        * @return 
0536        */
0537     void updateFraTimer(const bool start) {
0538       if (start) {
0539         fraTimer = std::clock();
0540       } else {
0541         fraTimeSum += double(std::clock() - fraTimer) / CLOCKS_PER_SEC;
0542         fraCount++;
0543       }
0544     }
0545 
0546     /**
0547        * @brief  Switch on/off efficiency MO processing timer
0548        * @param start timer action (true - start, false - stop) 
0549        * @return 
0550        */
0551     void updateEffTimer(const bool start) {
0552       if (start) {
0553         effTimer = std::clock();
0554       } else {
0555         effTimeSum += double(std::clock() - effTimer) / CLOCKS_PER_SEC;
0556         effCount++;
0557       }
0558     }
0559 
0560     /**
0561        * @brief  Check if MO is not excluded by MO Filter
0562        * @param  name MO name to book
0563        * @return true if MO is not excluded, false - otherwise
0564        */
0565     const bool needBookMO(const std::string name) const {
0566       bool result = true;
0567       for (unsigned int i = 0; i < MOFilterItems.size(); i++) {
0568         const MOFilterItem* filter = &MOFilterItems.at(i);
0569         if (Utility::regexMatch(filter->pattern, name))
0570           result = filter->include;
0571       }
0572       return result;
0573     }
0574 
0575     /**
0576       * Counters section.
0577       */
0578 
0579   public:
0580     /**
0581        * @brief  Reset counters
0582        * @return 
0583        */
0584     void reset() {
0585       nEvents = 0;
0586       nEventsBad = 0;
0587       nEventsGood = 0;
0588       nEventsCSC = 0;
0589       nUnpackedCSC = 0;
0590       fraCount = 0;
0591       effCount = 0;
0592       eventTimeSum = 0.0;
0593       fraTimeSum = 0.0;
0594       effTimeSum = 0.0;
0595     }
0596 
0597     /**
0598        * Getters for Global Counters.
0599        */
0600 
0601     const unsigned long getNEvents() const { return nEvents; }
0602     const unsigned long getNEventsBad() const { return nEventsBad; }
0603     const unsigned long getNEventsGood() const { return nEventsGood; }
0604     const unsigned long getNEventsCSC() const { return nEventsCSC; }
0605     const unsigned long getNUnpackedCSC() const { return nUnpackedCSC; }
0606 
0607     /**
0608        * Increments (by 1) for Global Counters.
0609        */
0610 
0611     void incNEvents() {
0612       nEvents++;
0613       if (getEVENTS_ECHO() > 0) {
0614         if (getNEvents() % getEVENTS_ECHO() == 0) {
0615           LOG_INFO << "(echo) Events processed: " << std::setw(12) << getNEvents();
0616         }
0617       }
0618     }
0619     void incNEventsBad() { nEventsBad++; }
0620     void incNEventsGood() { nEventsGood++; }
0621     void incNEventsCSC() { nEventsCSC++; }
0622     void incNUnpackedCSC() { nUnpackedCSC++; }
0623 
0624     /**
0625        * @brief  Increment Chamber counter by 1
0626        * @param  counter Counter Type
0627        * @param  crateId CSC Crate ID
0628        * @param  dmbId CSC DMB ID
0629        * @return 
0630        */
0631     void incChamberCounter(const ChamberCounterType counter, const HwId crateId, const HwId dmbId) {
0632       setChamberCounterValue(counter, crateId, dmbId, getChamberCounterValue(counter, crateId, dmbId) + 1);
0633     }
0634 
0635     /**
0636        * @brief  Set Chamber counter value
0637        * @param  counter Counter Type
0638        * @param  crateId CSC Crate ID
0639        * @param  dmbId CSC DMB ID
0640        * @param value value to set
0641        * @return 
0642        */
0643     void setChamberCounterValue(const ChamberCounterType counter,
0644                                 const HwId crateId,
0645                                 const HwId dmbId,
0646                                 const uint32_t value) {
0647       ChamberMapCounterMapType::iterator it = chamberCounters.find(boost::make_tuple(crateId, dmbId));
0648       if (it == chamberCounters.end()) {
0649         it = chamberCounters.insert(chamberCounters.end(),
0650                                     ChamberCounterKeyType(crateId, dmbId, ChamberCounterMapType()));
0651       }
0652       ChamberCounterMapType* cs = const_cast<ChamberCounterMapType*>(&it->counters);
0653       ChamberCounterMapType::iterator itc = cs->find(counter);
0654       if (itc == cs->end()) {
0655         cs->insert(std::make_pair(counter, value));
0656       } else {
0657         itc->second = value;
0658       }
0659     }
0660 
0661     /**
0662        * @brief  Copy Chamber counter value from one counter to another
0663        * @param  counter_from Counter Type to copy value from
0664        * @param  counter_to Counter Type to copy value to
0665        * @param  crateId CSC Crate ID
0666        * @param  dmbId CSC DMB ID
0667        * @return 
0668        */
0669     void copyChamberCounterValue(const ChamberCounterType counter_from,
0670                                  const ChamberCounterType counter_to,
0671                                  const HwId crateId,
0672                                  const HwId dmbId) {
0673       setChamberCounterValue(counter_from, crateId, dmbId, getChamberCounterValue(counter_from, crateId, dmbId));
0674     }
0675 
0676     /**
0677        * @brief  Get Chamber counter value
0678        * @param  counter Counter Type
0679        * @param  crateId CSC Crate ID
0680        * @param  dmbId CSC DMB ID
0681        * @return current counter value
0682        */
0683     const uint32_t getChamberCounterValue(const ChamberCounterType counter,
0684                                           const HwId crateId,
0685                                           const HwId dmbId) const {
0686       ChamberMapCounterMapType::iterator it = chamberCounters.find(boost::make_tuple(crateId, dmbId));
0687       if (it == chamberCounters.end())
0688         return 0;
0689       ChamberCounterMapType::const_iterator itc = it->counters.find(counter);
0690       if (itc == it->counters.end())
0691         return 0;
0692       return itc->second;
0693     }
0694 
0695   private:
0696     /**
0697        * Global Counters.
0698        */
0699 
0700     /** Number of events */
0701     unsigned long nEvents;
0702 
0703     /** Number of bad events */
0704     unsigned long nEventsBad;
0705 
0706     /** Number of good events */
0707     unsigned long nEventsGood;
0708 
0709     /** Number of events that have CSC data (used in Global DQM) */
0710     unsigned long nEventsCSC;
0711 
0712     /** number of unpacked chambers */
0713     unsigned long nUnpackedCSC;
0714 
0715     /** Number of Fractional MO updates */
0716     unsigned long fraCount;
0717 
0718     /** Number of Efficiency MO updates */
0719     unsigned long effCount;
0720 
0721     /** Map of chamber counters */
0722     ChamberMapCounterMapType chamberCounters;
0723   };
0724 
0725 }  // namespace cscdqm
0726 
0727 #undef CONFIG_PARAMETERS_SEQ_LEN
0728 #undef CONFIG_PARAMETERS_SEQ
0729 #undef CONFIG_PARAMETER_DEFINE_MACRO
0730 #undef CONFIG_PARAMETER_DEFAULT_MACRO
0731 #undef CONFIG_PARAMETER_GETTER_MACRO
0732 #undef CONFIG_PARAMETER_SETTER_MACRO
0733 #undef CONFIG_PARAMETER_LOADPS_MACRO
0734 #undef CONFIG_PARAMETER_LOADXML_MACRO
0735 #undef CONFIG_PARAMETER_PRINTXML_MACRO
0736 
0737 #endif