Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-05-03 04:04:20

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, DDU_CHECK_MASK, 0xFFFFFFFF, "mask for cumulative EmuFileReader DDU error flags (EventProcessor)"))( \
0096       (unsigned int, DDU_BINCHECK_MASK, 0x02080016, "mask for DDU level examiner errors (CSCDCCExaminer)"))(            \
0097       (unsigned int, BINCHECK_MASK, 0xFFFFFFFF, "mask for chamber level examiner errors (CSCDCCExaminer)"))(            \
0098       (unsigned int,                                                                                                    \
0099        FRAEFF_AUTO_UPDATE_START,                                                                                        \
0100        5,                                                                                                               \
0101        "event number to start automatic fractional and efficiency histogram updates from (Dispatcer)"))(                \
0102       (unsigned int,                                                                                                    \
0103        FRAEFF_AUTO_UPDATE_FREQ,                                                                                         \
0104        1,                                                                                                               \
0105        "frequency in events to perform automatic fractional and efficiency histogram updates (Dispatcher)"))((          \
0106       double, EFF_COLD_THRESHOLD, 0.1, "threshold in fraction to check for cold (not reporting) HW (EventProcessor)"))( \
0107       (double, EFF_COLD_SIGFAIL, 5.0, "statistical significance for cold (not reporting) HW (EventProcessor)"))(        \
0108       (double, EFF_HOT_THRESHOLD, 0.1, "threshold in fraction to check for hot HW (EventProcessor)"))(                  \
0109       (double, EFF_HOT_SIGFAIL, 5.0, "statistical significance for hot HW (EventProcessor)"))(                          \
0110       (double, EFF_ERR_THRESHOLD, 0.1, "threshold in fraction to check for errors in HW (EventProcessor)"))(            \
0111       (double, EFF_ERR_SIGFAIL, 5.0, "statistical significance for errors in HW (EventProcessor)"))(                    \
0112       (double,                                                                                                          \
0113        EFF_NODATA_THRESHOLD,                                                                                            \
0114        0.1,                                                                                                             \
0115        "threshold in fraction to check for not reporting elements in HW (EventProcessor)"))(                            \
0116       (double, EFF_NODATA_SIGFAIL, 5.0, "statistical significance for not reportingelements in HW (EventProcessor)"))(  \
0117       (unsigned int, EVENTS_ECHO, 1000, "frequency in events to print echo message (EventProcessor)"))(                 \
0118       (std::string, FOLDER_FED, "", "root file folder name to be used for FED histograms (EventProcessor)"))(           \
0119       (bool, PREBOOK_ALL_HISTOS, true, "pre-book all FED, DDU, CSC histogragrams before run begins"))
0120 
0121 /**
0122  * Global Parameter Manipulation macros.
0123  */
0124 
0125 /** Parameter as class property definition */
0126 #define CONFIG_PARAMETER_DEFINE_MACRO(r, data, i, elem) \
0127   BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem) BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem);
0128 
0129 /** Parameter Default value definition (in constructor) */
0130 #define CONFIG_PARAMETER_DEFAULT_MACRO(r, data, i, elem) \
0131   BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem) = BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 2, elem);
0132 
0133 /** Parameter Getter method */
0134 #define CONFIG_PARAMETER_GETTER_MACRO(r, data, i, elem)                                    \
0135   const BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem)                            \
0136       BOOST_PP_CAT(get, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))() const { \
0137     return BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem);                        \
0138   }
0139 
0140 /** Parameter Setter method */
0141 #define CONFIG_PARAMETER_SETTER_MACRO(r, data, i, elem)                            \
0142   void BOOST_PP_CAT(set, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))( \
0143       BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem) p) {                 \
0144     BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem) = p;                   \
0145   }
0146 
0147 #ifdef DQMGLOBAL
0148 
0149 /** Load parameter from parameters set line (Global DQM) */
0150 #define CONFIG_PARAMETER_LOADPS_MACRO(r, data, i, elem)                               \
0151   BOOST_PP_CAT(set, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))          \
0152   (ps.getUntrackedParameter<BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 0, elem)>( \
0153       BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem)),    \
0154                          BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 2, elem)));
0155 
0156 #endif
0157 
0158 #ifdef DQMLOCAL
0159 
0160 /** Load parameter from XML node line (Local DQM) */
0161 #define CONFIG_PARAMETER_LOADXML_MACRO(r, data, i, elem)                                                    \
0162   if (nodeName.compare(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))) == 0) { \
0163     stm >> BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem);                                         \
0164     continue;                                                                                               \
0165   }
0166 
0167 /** Include parameter into XML stream for printing */
0168 #define CONFIG_PARAMETER_PRINTXML_MACRO(r, data, i, elem)                                                              \
0169   {                                                                                                                    \
0170     DOMComment* comment =                                                                                              \
0171         doc->createComment(XERCES_TRANSCODE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 3, elem)));                 \
0172     DOMElement* el = doc->createElement(                                                                               \
0173         XERCES_TRANSCODE(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))));                \
0174     std::string value = toString(config.BOOST_PP_CAT(get, BOOST_PP_TUPLE_ELEM(CONFIG_PARAMETERS_SEQ_LEN, 1, elem))()); \
0175     DOMText* tdata = doc->createTextNode(XERCES_TRANSCODE(value.c_str()));                                             \
0176     el->appendChild(tdata);                                                                                            \
0177     rootElem->appendChild(comment);                                                                                    \
0178     rootElem->appendChild(el);                                                                                         \
0179   }
0180 
0181 #endif
0182 
0183 namespace cscdqm {
0184 
0185   /** @brief MO filter Item definition (loaded from XML/PSet) */
0186   struct MOFilterItem {
0187     /** Regexp filter pattern */
0188     TPRegexp pattern;
0189     /** Include filtered item or not */
0190     bool include;
0191     /** Constructor */
0192     MOFilterItem(const std::string pattern_, const bool include_) : pattern(pattern_.c_str()), include(include_) {}
0193   };
0194 
0195   /** @brief Chamber level counter types */
0196   enum ChamberCounterType {
0197     DMB_EVENTS,
0198     BAD_EVENTS,
0199     DMB_TRIGGERS,
0200     ALCT_TRIGGERS,
0201     CLCT_TRIGGERS,
0202     CFEB_TRIGGERS,
0203     EVENT_DISPLAY_PLOT
0204   };
0205 
0206   /** Single Chamber counters type */
0207   typedef std::map<ChamberCounterType, uint32_t> ChamberCounterMapType;
0208 
0209   /** @brief Chamber Counters key type */
0210   struct ChamberCounterKeyType {
0211     HwId crateId;
0212     HwId dmbId;
0213     ChamberCounterMapType counters;
0214     ChamberCounterKeyType(const HwId& crateId_, const HwId& dmbId_, const ChamberCounterMapType& c_)
0215         : crateId(crateId_), dmbId(dmbId_), counters(c_) {}
0216   };
0217 
0218   /** Map of Chamber Counters Type */
0219   typedef boost::multi_index_container<
0220       ChamberCounterKeyType,
0221       boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::composite_key<
0222           ChamberCounterKeyType,
0223           boost::multi_index::member<ChamberCounterKeyType, HwId, &ChamberCounterKeyType::crateId>,
0224           boost::multi_index::member<ChamberCounterKeyType, HwId, &ChamberCounterKeyType::dmbId> > > > >
0225       ChamberMapCounterMapType;
0226 
0227   /**
0228    * @class Configuration
0229    * @brief CSCDQM Framework Global Configuration
0230    */
0231   class Configuration {
0232   private:
0233     unsigned short printStatsLocal;
0234 
0235     /** Map of MO Filters */
0236     std::vector<MOFilterItem> MOFilterItems;
0237 
0238     /** Define parameters */
0239     BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_DEFINE_MACRO, _, CONFIG_PARAMETERS_SEQ)
0240 
0241     /**
0242        * @brief  Initialize parameter values and reset counters (used by constructors)
0243        * @return 
0244        */
0245     void init() {
0246       /** Assign default values to parameters */
0247       BOOST_PP_SEQ_FOR_EACH_I(CONFIG_PARAMETER_DEFAULT_MACRO, _, CONFIG_PARAMETERS_SEQ)
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     boost::timer globalTimer;
0425 
0426     /** Event processing Timer */
0427     boost::timer eventTimer;
0428 
0429     /** Fractional MO update Timer */
0430     boost::timer fraTimer;
0431 
0432     /** Efficiency MO update Timer */
0433     boost::timer 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 = globalTimer.elapsed();
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.restart();
0527       } else {
0528         eventTimeSum += eventTimer.elapsed();
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.restart();
0540       } else {
0541         fraTimeSum += fraTimer.elapsed();
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.restart();
0554       } else {
0555         effTimeSum += effTimer.elapsed();
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