Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-06-10 02:54:01

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