CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/HLTrigger/Timer/src/FastTimerService.cc

Go to the documentation of this file.
00001 // FIXME
00002 // we are by-passing the ME's when filling the plots, so we might need to call the ME's update() by hand
00003 
00004 
00005 // system headers
00006 #ifdef __linux
00007 #include <time.h>
00008 #else
00009 typedef int clockid_t;
00010 #define CLOCK_REALTIME               0
00011 #define CLOCK_MONOTONIC              1
00012 #define CLOCK_PROCESS_CPUTIME_ID     2
00013 #define CLOCK_THREAD_CPUTIME_ID      3
00014 #endif
00015 
00016 // C++ headers
00017 #include <cmath>
00018 #include <limits>
00019 #include <iostream>
00020 #include <iomanip>
00021 #include <string>
00022 #include <sstream>
00023 #include <tr1/unordered_set>
00024 #include <tr1/unordered_map>
00025 
00026 // boost headers
00027 #include <boost/format.hpp>
00028 
00029 // CMSSW headers
00030 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00031 #include "FWCore/ServiceRegistry/interface/Service.h"
00032 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00033 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00034 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00035 #include "FWCore/Framework/interface/Event.h"
00036 #include "FWCore/Framework/interface/LuminosityBlock.h"
00037 #include "FWCore/Framework/interface/TriggerNamesService.h"
00038 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00039 #include "DataFormats/Common/interface/HLTPathStatus.h"
00040 #include "DataFormats/Provenance/interface/EventID.h"
00041 #include "DataFormats/Provenance/interface/Timestamp.h"
00042 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00043 #include "DataFormats/Scalers/interface/LumiScalers.h"
00044 #include "DQMServices/Core/interface/DQMStore.h"
00045 #include "DQMServices/Core/interface/MonitorElement.h"
00046 #include "HLTrigger/Timer/interface/FastTimerService.h"
00047 #include "HLTrigger/Timer/interface/CPUAffinity.h"
00048 
00049 
00050 // file-static methods to fill a vector of strings with "(dup.) (...)" entries
00051 static
00052 void fill_dups(std::vector<std::string> & dups, unsigned int size) {
00053   dups.reserve(size);
00054   for (unsigned int i = dups.size(); i < size; ++i)
00055     dups.push_back( (boost::format("(dup.) (%d)") % i).str() );
00056 }
00057 
00058 
00059 FastTimerService::FastTimerService(const edm::ParameterSet & config, edm::ActivityRegistry & registry) :
00060   // configuration
00061   m_timer_id(                    config.getUntrackedParameter<bool>(     "useRealTimeClock"         ) ? CLOCK_REALTIME : CLOCK_THREAD_CPUTIME_ID),
00062   m_is_cpu_bound(                false ),
00063   m_enable_timing_paths(         config.getUntrackedParameter<bool>(     "enableTimingPaths"        ) ),
00064   m_enable_timing_modules(       config.getUntrackedParameter<bool>(     "enableTimingModules"      ) ),
00065   m_enable_timing_exclusive(     config.getUntrackedParameter<bool>(     "enableTimingExclusive"    ) ),
00066   m_enable_timing_summary(       config.getUntrackedParameter<bool>(     "enableTimingSummary"      ) ),
00067   m_skip_first_path(             config.getUntrackedParameter<bool>(     "skipFirstPath"            ) ),
00068   // dqm configuration
00069   m_enable_dqm(                  config.getUntrackedParameter<bool>(     "enableDQM"                ) ),
00070   m_enable_dqm_bypath_active(    config.getUntrackedParameter<bool>(     "enableDQMbyPathActive"    ) ),
00071   m_enable_dqm_bypath_total(     config.getUntrackedParameter<bool>(     "enableDQMbyPathTotal"     ) ),
00072   m_enable_dqm_bypath_overhead(  config.getUntrackedParameter<bool>(     "enableDQMbyPathOverhead"  ) ),
00073   m_enable_dqm_bypath_details(   config.getUntrackedParameter<bool>(     "enableDQMbyPathDetails"   ) ),
00074   m_enable_dqm_bypath_counters(  config.getUntrackedParameter<bool>(     "enableDQMbyPathCounters"  ) ),
00075   m_enable_dqm_bypath_exclusive( config.getUntrackedParameter<bool>(     "enableDQMbyPathExclusive" ) ),
00076   m_enable_dqm_bymodule(         config.getUntrackedParameter<bool>(     "enableDQMbyModule"        ) ),
00077   m_enable_dqm_summary(          config.getUntrackedParameter<bool>(     "enableDQMSummary"         ) ),
00078   m_enable_dqm_byluminosity(     config.getUntrackedParameter<bool>(     "enableDQMbyLuminosity"    ) ),   
00079   m_enable_dqm_byls(             config.existsAs<bool>("enableDQMbyLumiSection", false) ? 
00080                                     config.getUntrackedParameter<bool>("enableDQMbyLumiSection") : 
00081                                     ( edm::LogWarning("Configuration") << "enableDQMbyLumi is deprecated, please use enableDQMbyLumiSection instead", config.getUntrackedParameter<bool>("enableDQMbyLumi") ) 
00082                                  ),
00083   m_enable_dqm_bynproc(          config.getUntrackedParameter<bool>(     "enableDQMbyProcesses"     ) ),
00084   m_nproc_enabled(               false ),
00085   m_dqm_eventtime_range(         config.getUntrackedParameter<double>(   "dqmTimeRange"             ) ),            // ms
00086   m_dqm_eventtime_resolution(    config.getUntrackedParameter<double>(   "dqmTimeResolution"        ) ),            // ms
00087   m_dqm_pathtime_range(          config.getUntrackedParameter<double>(   "dqmPathTimeRange"         ) ),            // ms
00088   m_dqm_pathtime_resolution(     config.getUntrackedParameter<double>(   "dqmPathTimeResolution"    ) ),            // ms
00089   m_dqm_moduletime_range(        config.getUntrackedParameter<double>(   "dqmModuleTimeRange"       ) ),            // ms
00090   m_dqm_moduletime_resolution(   config.getUntrackedParameter<double>(   "dqmModuleTimeResolution"  ) ),            // ms
00091   m_dqm_luminosity_range(        config.getUntrackedParameter<double>(   "dqmLuminosityRange"       ) / 1.e30),     // cm-2 s-1
00092   m_dqm_luminosity_resolution(   config.getUntrackedParameter<double>(   "dqmLuminosityResolution"  ) / 1.e30),     // cm-2 s-1
00093   m_dqm_ls_range(                config.getUntrackedParameter<uint32_t>( "dqmLumiSectionsRange"     ) ),            // lumisections
00094   m_dqm_path(                    config.getUntrackedParameter<std::string>("dqmPath" ) ),
00095   m_luminosity_label(            config.getUntrackedParameter<edm::InputTag>("luminosityProduct") ),                // SCAL unpacker
00096   m_supported_processes(         config.getUntrackedParameter<std::vector<unsigned int> >("supportedProcesses") ),  // 8, 24, 32
00097   // caching
00098   m_first_path(0),          // these are initialized at prePathBeginRun(),
00099   m_last_path(0),           // to make sure we cache the correct pointers
00100   m_first_endpath(0),
00101   m_last_endpath(0),
00102   m_is_first_module(false),
00103   // per-event accounting
00104   m_event(0.),
00105   m_source(0.),
00106   m_all_paths(0.),
00107   m_all_endpaths(0.),
00108   m_interpaths(0.),
00109   // per-job summary
00110   m_summary_events(0),
00111   m_summary_event(0.),
00112   m_summary_source(0.),
00113   m_summary_all_paths(0.),
00114   m_summary_all_endpaths(0.),
00115   m_summary_interpaths(0.),
00116   // DQM - these are initialized at postBeginJob(), to make sure the DQM service has been loaded
00117   m_dqms(0),
00118   // event summary plots
00119   m_dqm_event(0),
00120   m_dqm_source(0),
00121   m_dqm_all_paths(0),
00122   m_dqm_all_endpaths(0),
00123   m_dqm_interpaths(0),
00124   // event summary plots - summed over nodes with the same number of processes
00125   m_dqm_nproc_event(0),
00126   m_dqm_nproc_source(0),
00127   m_dqm_nproc_all_paths(0),
00128   m_dqm_nproc_all_endpaths(0),
00129   m_dqm_nproc_interpaths(0),
00130   // plots by path
00131   m_dqm_paths_active_time(0),
00132   m_dqm_paths_total_time(0),
00133   m_dqm_paths_exclusive_time(0),
00134   m_dqm_paths_interpaths(0),
00135   // plots per lumisection
00136   m_dqm_byls_event(0),
00137   m_dqm_byls_source(0),
00138   m_dqm_byls_all_paths(0),
00139   m_dqm_byls_all_endpaths(0),
00140   m_dqm_byls_interpaths(0),
00141   // plots per lumisection - summed over nodes with the same number of processes
00142   m_dqm_nproc_byls_event(0),
00143   m_dqm_nproc_byls_source(0),
00144   m_dqm_nproc_byls_all_paths(0),
00145   m_dqm_nproc_byls_all_endpaths(0),
00146   m_dqm_nproc_byls_interpaths(0),
00147   // plots vs. instantaneous luminosity
00148   m_dqm_byluminosity_event(0),
00149   m_dqm_byluminosity_source(0),
00150   m_dqm_byluminosity_all_paths(0),
00151   m_dqm_byluminosity_all_endpaths(0),
00152   m_dqm_byluminosity_interpaths(0),
00153   // plots vs. instantaneous luminosity - summed over nodes with the same number of processes
00154   m_dqm_nproc_byluminosity_event(0),
00155   m_dqm_nproc_byluminosity_source(0),
00156   m_dqm_nproc_byluminosity_all_paths(0),
00157   m_dqm_nproc_byluminosity_all_endpaths(0),
00158   m_dqm_nproc_byluminosity_interpaths(0),
00159   // per-path and per-module accounting
00160   m_current_path(0),
00161   m_paths(),
00162   m_modules(),
00163   m_cache_paths(),
00164   m_cache_modules()
00165 {
00166   // enable timers if required by DQM plots
00167   m_enable_timing_paths     = m_enable_timing_paths     or m_enable_dqm_bypath_active or m_enable_dqm_bypath_total or m_enable_dqm_bypath_overhead or m_enable_dqm_bypath_details or m_enable_dqm_bypath_counters or m_enable_dqm_bypath_exclusive;
00168   m_enable_timing_modules   = m_enable_timing_modules   or m_enable_dqm_bymodule      or m_enable_dqm_bypath_total or m_enable_dqm_bypath_overhead or m_enable_dqm_bypath_details or m_enable_dqm_bypath_counters or m_enable_dqm_bypath_exclusive;
00169   m_enable_timing_exclusive = m_enable_timing_exclusive or m_enable_dqm_bypath_exclusive;
00170 
00171   registry.watchPreModuleBeginJob( this, & FastTimerService::preModuleBeginJob );
00172   registry.watchPostBeginJob(      this, & FastTimerService::postBeginJob );
00173   registry.watchPostEndJob(        this, & FastTimerService::postEndJob );
00174   registry.watchPrePathBeginRun(   this, & FastTimerService::prePathBeginRun) ;
00175   registry.watchPreProcessEvent(   this, & FastTimerService::preProcessEvent );
00176   registry.watchPostProcessEvent(  this, & FastTimerService::postProcessEvent );
00177   registry.watchPreSource(         this, & FastTimerService::preSource );
00178   registry.watchPostSource(        this, & FastTimerService::postSource );
00179   // watch per-path events
00180   registry.watchPreProcessPath(    this, & FastTimerService::preProcessPath );
00181   registry.watchPostProcessPath(   this, & FastTimerService::postProcessPath );
00182   // watch per-module events if enabled
00183   if (m_enable_timing_modules) {
00184     registry.watchPreModule(         this, & FastTimerService::preModule );
00185     registry.watchPostModule(        this, & FastTimerService::postModule );
00186   }
00187 
00188 #if defined(__APPLE__) || defined (__MACH__)
00189   host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &m_clock_port);
00190 #endif // defined(__APPLE__) || defined(__MACH__)
00191 }
00192 
00193 FastTimerService::~FastTimerService()
00194 {
00195 #if defined(__APPLE__) || defined (__MACH__)
00196   mach_port_deallocate(mach_task_self(), m_clock_port);
00197 #endif // defined(__APPLE__) || defined(__MACH__)
00198 }
00199 
00200 void FastTimerService::postBeginJob() {
00201   //edm::LogImportant("FastTimerService") << __func__ << "()";
00202 
00203   // check if the process is bound to a single CPU.
00204   // otherwise, the results of the CLOCK_THREAD_CPUTIME_ID timer might be inaccurate
00205   m_is_cpu_bound = CPUAffinity::isCpuBound();
00206   if ((m_timer_id != CLOCK_REALTIME) and not m_is_cpu_bound)
00207     // the process is NOT bound to a single CPU
00208     edm::LogError("FastTimerService") << "this process is NOT bound to a single CPU, the results of the FastTimerService may be undefined";
00209 
00210   edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00211   uint32_t size_p = tns.getTrigPaths().size();
00212   uint32_t size_e = tns.getEndPaths().size();
00213   uint32_t size = size_p + size_e;
00214   for (uint32_t i = 0; i < size_p; ++i) {
00215     std::string const & label = tns.getTrigPath(i);
00216     m_paths[label].index = i;
00217   }
00218   for (uint32_t i = 0; i < size_e; ++i) {
00219     std::string const & label = tns.getEndPath(i);
00220     m_paths[label].index = size_p + i;
00221   }
00222 
00223   // cache all pathinfo objects
00224   m_cache_paths.reserve(m_paths.size());
00225   for (auto & keyval: m_paths)
00226     m_cache_paths.push_back(& keyval.second);
00227 
00228   // cache all moduleinfo objects
00229   m_cache_modules.reserve(m_modules.size());
00230   for (auto & keyval: m_modules)
00231     m_cache_modules.push_back(& keyval.second);
00232 
00233   // associate to each path all the modules it contains
00234   for (uint32_t i = 0; i < tns.getTrigPaths().size(); ++i)
00235     fillPathMap( tns.getTrigPath(i), tns.getTrigPathModules(i) );
00236   for (uint32_t i = 0; i < tns.getEndPaths().size(); ++i)
00237     fillPathMap( tns.getEndPath(i), tns.getEndPathModules(i) );
00238 
00239   if (m_enable_dqm)
00240     // load the DQM store
00241     m_dqms = edm::Service<DQMStore>().operator->();
00242 
00243   if (m_dqms) {
00244     // book MonitorElement's
00245     int eventbins  = (int) std::ceil(m_dqm_eventtime_range  / m_dqm_eventtime_resolution);
00246     int pathbins   = (int) std::ceil(m_dqm_pathtime_range   / m_dqm_pathtime_resolution);
00247     int modulebins = (int) std::ceil(m_dqm_moduletime_range / m_dqm_moduletime_resolution);
00248     int lumibins   = (int) std::ceil(m_dqm_luminosity_range / m_dqm_luminosity_resolution);
00249 
00250     // event summary plots
00251     if (m_enable_dqm_summary) {
00252       m_dqms->setCurrentFolder(m_dqm_path);
00253       m_dqm_event         = m_dqms->book1D("event",        "Event processing time",    eventbins, 0., m_dqm_eventtime_range)->getTH1F();
00254       m_dqm_event         ->StatOverflows(true);
00255       m_dqm_event         ->SetXTitle("processing time [ms]");
00256       m_dqm_source        = m_dqms->book1D("source",       "Source processing time",   pathbins,  0., m_dqm_pathtime_range)->getTH1F();
00257       m_dqm_source        ->StatOverflows(true);
00258       m_dqm_source        ->SetXTitle("processing time [ms]");
00259       m_dqm_all_paths     = m_dqms->book1D("all_paths",    "Paths processing time",    eventbins, 0., m_dqm_eventtime_range)->getTH1F();
00260       m_dqm_all_paths     ->StatOverflows(true);
00261       m_dqm_all_paths     ->SetXTitle("processing time [ms]");
00262       m_dqm_all_endpaths  = m_dqms->book1D("all_endpaths", "EndPaths processing time", pathbins,  0., m_dqm_pathtime_range)->getTH1F();
00263       m_dqm_all_endpaths  ->StatOverflows(true);
00264       m_dqm_all_endpaths  ->SetXTitle("processing time [ms]");
00265       m_dqm_interpaths    = m_dqms->book1D("interpaths",   "Time spent between paths", pathbins,  0., m_dqm_eventtime_range)->getTH1F();
00266       m_dqm_interpaths    ->StatOverflows(true);
00267       m_dqm_interpaths    ->SetXTitle("processing time [ms]");
00268     }
00269 
00270     // event summary plots - summed over nodes with the same number of processes
00271     if (m_enable_dqm_summary and m_enable_dqm_bynproc) {
00272       TH1F * plot;
00273       for (int n : m_supported_processes) {
00274         m_dqms->setCurrentFolder( (boost::format("%s/Running %d processes") % m_dqm_path % n).str() );
00275         plot = m_dqms->book1D("event",        "Event processing time",    eventbins, 0., m_dqm_eventtime_range)->getTH1F();
00276         plot->StatOverflows(true);
00277         plot->SetXTitle("processing time [ms]");
00278         plot = m_dqms->book1D("source",       "Source processing time",   pathbins,  0., m_dqm_pathtime_range)->getTH1F();
00279         plot->StatOverflows(true);
00280         plot->SetXTitle("processing time [ms]");
00281         plot = m_dqms->book1D("all_paths",    "Paths processing time",    eventbins, 0., m_dqm_eventtime_range)->getTH1F();
00282         plot->StatOverflows(true);
00283         plot->SetXTitle("processing time [ms]");
00284         plot = m_dqms->book1D("all_endpaths", "EndPaths processing time", pathbins,  0., m_dqm_pathtime_range)->getTH1F();
00285         plot->StatOverflows(true);
00286         plot->SetXTitle("processing time [ms]");
00287         plot = m_dqms->book1D("interpaths",   "Time spent between paths", pathbins,  0., m_dqm_eventtime_range)->getTH1F();
00288         plot->StatOverflows(true);
00289         plot->SetXTitle("processing time [ms]");
00290       }
00291     }
00292 
00293     // plots by path
00294     m_dqms->setCurrentFolder(m_dqm_path);
00295     m_dqm_paths_active_time     = m_dqms->bookProfile("paths_active_time",    "Additional time spent in each path", size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00296     m_dqm_paths_active_time     ->StatOverflows(true);
00297     m_dqm_paths_active_time     ->SetYTitle("processing time [ms]");
00298     m_dqm_paths_total_time      = m_dqms->bookProfile("paths_total_time",     "Total time spent in each path",      size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00299     m_dqm_paths_total_time      ->StatOverflows(true);
00300     m_dqm_paths_total_time      ->SetYTitle("processing time [ms]");
00301     m_dqm_paths_exclusive_time  = m_dqms->bookProfile("paths_exclusive_time", "Exclusive time spent in each path",  size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00302     m_dqm_paths_exclusive_time  ->StatOverflows(true);
00303     m_dqm_paths_exclusive_time  ->SetYTitle("processing time [ms]");
00304     m_dqm_paths_interpaths      = m_dqms->bookProfile("paths_interpaths",     "Time spent between each path",       size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00305     m_dqm_paths_interpaths      ->StatOverflows(true);
00306     m_dqm_paths_interpaths      ->SetYTitle("processing time [ms]");
00307 
00308     for (uint32_t i = 0; i < size_p; ++i) {
00309       std::string const & label = tns.getTrigPath(i);
00310       m_dqm_paths_active_time    ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00311       m_dqm_paths_total_time     ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00312       m_dqm_paths_exclusive_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00313       m_dqm_paths_interpaths     ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00314     }
00315     for (uint32_t i = 0; i < size_e; ++i) {
00316       std::string const & label = tns.getEndPath(i);
00317       m_dqm_paths_active_time    ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00318       m_dqm_paths_total_time     ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00319       m_dqm_paths_exclusive_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00320       m_dqm_paths_interpaths     ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00321     }
00322 
00323     // per-lumisection plots
00324     if (m_enable_dqm_byls) {
00325       m_dqms->setCurrentFolder(m_dqm_path);
00326       m_dqm_byls_event        = m_dqms->bookProfile("event_byls",        "Event processing time, by LumiSection",    m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00327       m_dqm_byls_event        ->StatOverflows(true);
00328       m_dqm_byls_event        ->SetXTitle("lumisection");
00329       m_dqm_byls_event        ->SetYTitle("processing time [ms]");
00330       m_dqm_byls_source       = m_dqms->bookProfile("source_byls",       "Source processing time, by LumiSection",   m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00331       m_dqm_byls_source       ->StatOverflows(true);
00332       m_dqm_byls_source       ->SetXTitle("lumisection");
00333       m_dqm_byls_source       ->SetYTitle("processing time [ms]");
00334       m_dqm_byls_all_paths    = m_dqms->bookProfile("all_paths_byls",    "Paths processing time, by LumiSection",    m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00335       m_dqm_byls_all_paths    ->StatOverflows(true);
00336       m_dqm_byls_all_paths    ->SetXTitle("lumisection");
00337       m_dqm_byls_all_paths    ->SetYTitle("processing time [ms]");
00338       m_dqm_byls_all_endpaths = m_dqms->bookProfile("all_endpaths_byls", "EndPaths processing time, by LumiSection", m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00339       m_dqm_byls_all_endpaths ->StatOverflows(true);
00340       m_dqm_byls_all_endpaths ->SetXTitle("lumisection");
00341       m_dqm_byls_all_endpaths ->SetYTitle("processing time [ms]");
00342       m_dqm_byls_interpaths   = m_dqms->bookProfile("interpaths_byls",   "Time spent between paths, by LumiSection", m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00343       m_dqm_byls_interpaths   ->StatOverflows(true);
00344       m_dqm_byls_interpaths   ->SetXTitle("lumisection");
00345       m_dqm_byls_interpaths   ->SetYTitle("processing time [ms]");
00346     }
00347 
00348     // per-lumisection plots
00349     if (m_enable_dqm_byls and m_enable_dqm_bynproc) {
00350       TProfile * plot;
00351       for (int n : m_supported_processes) {
00352         m_dqms->setCurrentFolder( (boost::format("%s/Running %d processes") % m_dqm_path % n).str() );
00353         plot = m_dqms->bookProfile("event_byls",        "Event processing time, by LumiSection",    m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00354         plot->StatOverflows(true);
00355         plot->SetXTitle("lumisection");
00356         plot->SetYTitle("processing time [ms]");
00357         plot = m_dqms->bookProfile("source_byls",       "Source processing time, by LumiSection",   m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00358         plot->StatOverflows(true);
00359         plot->SetXTitle("lumisection");
00360         plot->SetYTitle("processing time [ms]");
00361         plot = m_dqms->bookProfile("all_paths_byls",    "Paths processing time, by LumiSection",    m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00362         plot->StatOverflows(true);
00363         plot->SetXTitle("lumisection");
00364         plot->SetYTitle("processing time [ms]");
00365         plot = m_dqms->bookProfile("all_endpaths_byls", "EndPaths processing time, by LumiSection", m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00366         plot->StatOverflows(true);
00367         plot->SetXTitle("lumisection");
00368         plot->SetYTitle("processing time [ms]");
00369         plot = m_dqms->bookProfile("interpaths_byls",   "Time spent between paths, by LumiSection", m_dqm_ls_range, 0.5, m_dqm_ls_range+0.5, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00370         plot->StatOverflows(true);
00371         plot->SetXTitle("lumisection");
00372         plot->SetYTitle("processing time [ms]");
00373       }
00374     }
00375 
00376     // plots vs. instantaneous luminosity
00377     if (m_enable_dqm_byluminosity) {
00378       m_dqms->setCurrentFolder(m_dqm_path);
00379       m_dqm_byluminosity_event        = m_dqms->bookProfile("event_byluminosity",        "Event processing time vs. instantaneous luminosity",    lumibins, 0., m_dqm_luminosity_range, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00380       m_dqm_byluminosity_event        ->StatOverflows(true);
00381       m_dqm_byluminosity_event        ->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00382       m_dqm_byluminosity_event        ->SetYTitle("processing time [ms]");
00383       m_dqm_byluminosity_source       = m_dqms->bookProfile("source_byluminosity",       "Source processing time vs. instantaneous luminosity",   lumibins, 0., m_dqm_luminosity_range, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00384       m_dqm_byluminosity_source       ->StatOverflows(true);
00385       m_dqm_byluminosity_source       ->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00386       m_dqm_byluminosity_source       ->SetYTitle("processing time [ms]");
00387       m_dqm_byluminosity_all_paths    = m_dqms->bookProfile("all_paths_byluminosity",    "Paths processing time vs. instantaneous luminosity",    lumibins, 0., m_dqm_luminosity_range, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00388       m_dqm_byluminosity_all_paths    ->StatOverflows(true);
00389       m_dqm_byluminosity_all_paths    ->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00390       m_dqm_byluminosity_all_paths    ->SetYTitle("processing time [ms]");
00391       m_dqm_byluminosity_all_endpaths = m_dqms->bookProfile("all_endpaths_byluminosity", "EndPaths processing time vs. instantaneous luminosity", lumibins, 0., m_dqm_luminosity_range, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00392       m_dqm_byluminosity_all_endpaths ->StatOverflows(true);
00393       m_dqm_byluminosity_all_endpaths ->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00394       m_dqm_byluminosity_all_endpaths ->SetYTitle("processing time [ms]");
00395       m_dqm_byluminosity_interpaths   = m_dqms->bookProfile("interpaths_byluminosity",   "Time spent between paths vs. instantaneous luminosity", lumibins, 0., m_dqm_luminosity_range, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00396       m_dqm_byluminosity_interpaths   ->StatOverflows(true);
00397       m_dqm_byluminosity_interpaths   ->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00398       m_dqm_byluminosity_interpaths   ->SetYTitle("processing time [ms]");
00399     }
00400 
00401     // plots vs. instantaneous luminosity
00402     if (m_enable_dqm_byluminosity and m_enable_dqm_bynproc) {
00403       TProfile * plot;
00404       for (int n : m_supported_processes) {
00405         m_dqms->setCurrentFolder( (boost::format("%s/Running %d processes") % m_dqm_path % n).str() );
00406         plot = m_dqms->bookProfile("event_byluminosity",        "Event processing time vs. instantaneous luminosity",    lumibins, 0., m_dqm_luminosity_range, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00407         plot->StatOverflows(true);
00408         plot->SetYTitle("processing time [ms]");
00409         plot->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00410         plot = m_dqms->bookProfile("source_byluminosity",       "Source processing time vs. instantaneous luminosity",   lumibins, 0., m_dqm_luminosity_range, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00411         plot->StatOverflows(true);
00412         plot->SetYTitle("processing time [ms]");
00413         plot->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00414         plot = m_dqms->bookProfile("all_paths_byluminosity",    "Paths processing time vs. instantaneous luminosity",    lumibins, 0., m_dqm_luminosity_range, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00415         plot->StatOverflows(true);
00416         plot->SetYTitle("processing time [ms]");
00417         plot->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00418         plot = m_dqms->bookProfile("all_endpaths_byluminosity", "EndPaths processing time vs. instantaneous luminosity", lumibins, 0., m_dqm_luminosity_range, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00419         plot->StatOverflows(true);
00420         plot->SetYTitle("processing time [ms]");
00421         plot->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00422         plot = m_dqms->bookProfile("interpaths_byluminosity",   "Time spent between paths vs. instantaneous luminosity", lumibins, 0., m_dqm_luminosity_range, pathbins,  0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00423         plot->StatOverflows(true);
00424         plot->SetYTitle("processing time [ms]");
00425         plot->SetXTitle("instantaneous luminosity [10^{30} cm^{-2}s^{-1}]");
00426       }
00427     }
00428 
00429     // per-path and per-module accounting
00430     if (m_enable_timing_paths) {
00431       m_dqms->setCurrentFolder((m_dqm_path + "/Paths"));
00432       for (auto & keyval: m_paths) {
00433         std::string const & pathname = keyval.first;
00434         PathInfo          & pathinfo = keyval.second;
00435 
00436         if (m_enable_dqm_bypath_active) {
00437           pathinfo.dqm_active       = m_dqms->book1D(pathname + "_active",       pathname + " active time",            pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00438           pathinfo.dqm_active       ->StatOverflows(true);
00439           pathinfo.dqm_active       ->SetXTitle("processing time [ms]");
00440         }
00441 
00442         if (m_enable_dqm_bypath_total) {
00443           pathinfo.dqm_total        = m_dqms->book1D(pathname + "_total",        pathname + " total time",             pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00444           pathinfo.dqm_total        ->StatOverflows(true);
00445           pathinfo.dqm_total        ->SetXTitle("processing time [ms]");
00446         }
00447 
00448         if (m_enable_dqm_bypath_overhead) {
00449           pathinfo.dqm_premodules   = m_dqms->book1D(pathname + "_premodules",   pathname + " pre-modules overhead",   modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00450           pathinfo.dqm_premodules   ->StatOverflows(true);
00451           pathinfo.dqm_premodules   ->SetXTitle("processing time [ms]");
00452           pathinfo.dqm_intermodules = m_dqms->book1D(pathname + "_intermodules", pathname + " inter-modules overhead", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00453           pathinfo.dqm_intermodules ->StatOverflows(true);
00454           pathinfo.dqm_intermodules ->SetXTitle("processing time [ms]");
00455           pathinfo.dqm_postmodules  = m_dqms->book1D(pathname + "_postmodules",  pathname + " post-modules overhead",  modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00456           pathinfo.dqm_postmodules  ->StatOverflows(true);
00457           pathinfo.dqm_postmodules  ->SetXTitle("processing time [ms]");
00458           pathinfo.dqm_overhead     = m_dqms->book1D(pathname + "_overhead",     pathname + " overhead time",          modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00459           pathinfo.dqm_overhead     ->StatOverflows(true);
00460           pathinfo.dqm_overhead     ->SetXTitle("processing time [ms]");
00461         }
00462 
00463         if (m_enable_dqm_bypath_details or m_enable_dqm_bypath_counters) {
00464           // book histograms for modules-in-paths statistics
00465 
00466           // find histograms X-axis labels
00467           uint32_t id;
00468           std::vector<std::string> const & modules = ((id = tns.findTrigPath(pathname)) != tns.getTrigPaths().size()) ? tns.getTrigPathModules(id) :
00469                                                      ((id = tns.findEndPath(pathname))  != tns.getEndPaths().size())  ? tns.getEndPathModules(id)  :
00470                                                      std::vector<std::string>();
00471 
00472           static std::vector<std::string> dup;
00473           if (modules.size() > dup.size())
00474             fill_dups(dup, modules.size());
00475 
00476           std::vector<const char *> labels(modules.size(), nullptr);
00477           for (uint32_t i = 0; i < modules.size(); ++i)
00478             labels[i] = (pathinfo.modules[i]) ? modules[i].c_str() : dup[i].c_str();
00479           
00480           // book counter histograms
00481           if (m_enable_dqm_bypath_counters) {
00482             pathinfo.dqm_module_counter = m_dqms->book1D(pathname + "_module_counter", pathname + " module counter", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00483             // find module labels
00484             for (uint32_t i = 0; i < modules.size(); ++i) {
00485               pathinfo.dqm_module_counter->GetXaxis()->SetBinLabel( i+1, labels[i] );
00486             }
00487           }
00488           // book detailed timing histograms
00489           if (m_enable_dqm_bypath_details) {
00490             pathinfo.dqm_module_active  = m_dqms->book1D(pathname + "_module_active",  pathname + " module active",  modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00491             pathinfo.dqm_module_active  ->SetYTitle("cumulative processing time [ms]");
00492             pathinfo.dqm_module_total   = m_dqms->book1D(pathname + "_module_total",   pathname + " module total",   modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00493             pathinfo.dqm_module_total   ->SetYTitle("cumulative processing time [ms]");
00494             // find module labels
00495             for (uint32_t i = 0; i < modules.size(); ++i) {
00496               pathinfo.dqm_module_active ->GetXaxis()->SetBinLabel( i+1, labels[i] );
00497               pathinfo.dqm_module_total  ->GetXaxis()->SetBinLabel( i+1, labels[i] );
00498             }
00499           }
00500         }
00501 
00502         // book exclusive path time histograms
00503         if (m_enable_dqm_bypath_exclusive) {
00504           pathinfo.dqm_exclusive = m_dqms->book1D(pathname + "_exclusive", pathname + " exclusive time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00505           pathinfo.dqm_exclusive ->StatOverflows(true);
00506           pathinfo.dqm_exclusive ->SetYTitle("processing time [ms]");
00507         }
00508 
00509       }
00510     }
00511    
00512     if (m_enable_dqm_bymodule) {
00513       m_dqms->setCurrentFolder((m_dqm_path + "/Modules"));
00514       for (auto & keyval: m_modules) {
00515         std::string const & label  = keyval.first->moduleLabel();
00516         ModuleInfo        & module = keyval.second;
00517         module.dqm_active = m_dqms->book1D(label, label, modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00518         module.dqm_active->StatOverflows(true);
00519         module.dqm_active->SetYTitle("processing time [ms]");
00520       }
00521     }
00522 
00523   }
00524 }
00525 
00526 void FastTimerService::setNumberOfProcesses(unsigned int procs) {
00527   // the service is not configured to support plots by number of processes
00528   if (not m_enable_dqm or not m_enable_dqm_bynproc)
00529     return;
00530 
00531   // the DQM store has not been configured yet
00532   if (not m_dqms)
00533     return;
00534 
00535   // check if the service is configured to support this number of processes
00536   if (std::find(m_supported_processes.begin(), m_supported_processes.end(), procs) == m_supported_processes.end()) {
00537     m_nproc_enabled = false;
00538     // event summary plots - summed over nodes with the same number of processes
00539     m_dqm_nproc_event                     = 0;
00540     m_dqm_nproc_source                    = 0;
00541     m_dqm_nproc_all_paths                 = 0;
00542     m_dqm_nproc_all_endpaths              = 0;
00543     m_dqm_nproc_interpaths                = 0;
00544     // plots per lumisection - summed over nodes with the same number of processes
00545     m_dqm_nproc_byls_event                = 0;
00546     m_dqm_nproc_byls_source               = 0;
00547     m_dqm_nproc_byls_all_paths            = 0;
00548     m_dqm_nproc_byls_all_endpaths         = 0;
00549     m_dqm_nproc_byls_interpaths           = 0;
00550     // plots vs. instantaneous luminosity - summed over nodes with the same number of processes
00551     m_dqm_nproc_byluminosity_event        = 0;
00552     m_dqm_nproc_byluminosity_source       = 0;
00553     m_dqm_nproc_byluminosity_all_paths    = 0;
00554     m_dqm_nproc_byluminosity_all_endpaths = 0;
00555     m_dqm_nproc_byluminosity_interpaths   = 0;
00556   } else {
00557     m_nproc_enabled = true;
00558     // event summary plots - summed over nodes with the same number of processes
00559     m_dqm_nproc_event                     = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "event"                    ).str() )->getTH1F();
00560     m_dqm_nproc_source                    = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "source"                   ).str() )->getTH1F();
00561     m_dqm_nproc_all_paths                 = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "all_paths"                ).str() )->getTH1F();
00562     m_dqm_nproc_all_endpaths              = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "all_endpaths"             ).str() )->getTH1F();
00563     m_dqm_nproc_interpaths                = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "interpaths"               ).str() )->getTH1F();
00564     // plots per lumisection - summed over nodes with the same number of processes
00565     m_dqm_nproc_byls_event                = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "event_byls"               ).str() )->getTProfile();
00566     m_dqm_nproc_byls_source               = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "source_byls"              ).str() )->getTProfile();
00567     m_dqm_nproc_byls_all_paths            = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "all_paths_byls"           ).str() )->getTProfile();
00568     m_dqm_nproc_byls_all_endpaths         = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "all_endpaths_byls"        ).str() )->getTProfile();
00569     m_dqm_nproc_byls_interpaths           = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "interpaths_byls"          ).str() )->getTProfile();
00570     // plots vs. instantaneous luminosity - summed over nodes with the same number of processes
00571     m_dqm_nproc_byluminosity_event        = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "event_byluminosity"       ).str() )->getTProfile();
00572     m_dqm_nproc_byluminosity_source       = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "source_byluminosity"      ).str() )->getTProfile();
00573     m_dqm_nproc_byluminosity_all_paths    = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "all_paths_byluminosity"   ).str() )->getTProfile();
00574     m_dqm_nproc_byluminosity_all_endpaths = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "all_endpaths_byluminosity").str() )->getTProfile();
00575     m_dqm_nproc_byluminosity_interpaths   = m_dqms->get( (boost::format("%s/Running %d processes/%s") % m_dqm_path % procs % "interpaths_byluminosity"  ).str() )->getTProfile();
00576   }
00577 }
00578 
00579 void FastTimerService::postEndJob() {
00580   //edm::LogImportant("FastTimerService") << __func__ << "()";
00581 
00582   if (m_enable_timing_summary) {
00583     // print a timing sumary for the whle job
00584     edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00585 
00586     std::ostringstream out;
00587     out << std::fixed << std::setprecision(6);
00588     out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time)  ") << '\n';
00589     out << "FastReport              " << std::right << std::setw(10) << m_summary_source       / (double) m_summary_events << "  Source"        << '\n';
00590     out << "FastReport              " << std::right << std::setw(10) << m_summary_event        / (double) m_summary_events << "  Event"         << '\n';
00591     out << "FastReport              " << std::right << std::setw(10) << m_summary_all_paths    / (double) m_summary_events << "  all Paths"     << '\n';
00592     out << "FastReport              " << std::right << std::setw(10) << m_summary_all_endpaths / (double) m_summary_events << "  all EndPaths"  << '\n';
00593     out << "FastReport              " << std::right << std::setw(10) << m_summary_interpaths   / (double) m_summary_events << "  between paths" << '\n';
00594     if (m_enable_timing_modules) {
00595       double modules_total = 0.;
00596       for (auto & keyval: m_modules)
00597         modules_total += keyval.second.summary_active;
00598       out << "FastReport              " << std::right << std::setw(10) << modules_total          / (double) m_summary_events << "  all Modules"   << '\n';
00599     }
00600     out << '\n';
00601     if (m_enable_timing_paths and not m_enable_timing_modules) {
00602       out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time)  ")    << "     Active Path" << '\n';
00603       for (auto const & name: tns.getTrigPaths())
00604         out << "FastReport              "
00605             << std::right << std::setw(10) << m_paths[name].summary_active  / (double) m_summary_events << "  "
00606             << name << '\n';
00607       out << '\n';
00608       out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time)  ")    << "     Active EndPath" << '\n';
00609       for (auto const & name: tns.getEndPaths())
00610         out << "FastReport              "
00611             << std::right << std::setw(10) << m_paths[name].summary_active  / (double) m_summary_events << "  "
00612             << name << '\n';
00613     } else if (m_enable_timing_paths and m_enable_timing_modules) {
00614       out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time)  ")    << "     Active      Pre-    Inter- Post-mods  Overhead     Total  Path" << '\n';
00615       for (auto const & name: tns.getTrigPaths()) {
00616         out << "FastReport              "
00617             << std::right << std::setw(10) << m_paths[name].summary_active        / (double) m_summary_events << " "
00618             << std::right << std::setw(10) << m_paths[name].summary_premodules    / (double) m_summary_events << " "
00619             << std::right << std::setw(10) << m_paths[name].summary_intermodules  / (double) m_summary_events << " "
00620             << std::right << std::setw(10) << m_paths[name].summary_postmodules   / (double) m_summary_events << " "
00621             << std::right << std::setw(10) << m_paths[name].summary_overhead      / (double) m_summary_events << " "
00622             << std::right << std::setw(10) << m_paths[name].summary_total         / (double) m_summary_events << "  "
00623             << name << '\n';
00624       }
00625       out << '\n';
00626       out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time)  ")    << "     Active      Pre-    Inter- Post-mods  Overhead     Total  EndPath" << '\n';
00627       for (auto const & name: tns.getEndPaths()) {
00628         out << "FastReport              "
00629             << std::right << std::setw(10) << m_paths[name].summary_active        / (double) m_summary_events << " "
00630             << std::right << std::setw(10) << m_paths[name].summary_premodules    / (double) m_summary_events << " "
00631             << std::right << std::setw(10) << m_paths[name].summary_intermodules  / (double) m_summary_events << " "
00632             << std::right << std::setw(10) << m_paths[name].summary_postmodules   / (double) m_summary_events << " "
00633             << std::right << std::setw(10) << m_paths[name].summary_overhead      / (double) m_summary_events << " "
00634             << std::right << std::setw(10) << m_paths[name].summary_total         / (double) m_summary_events << "  "
00635             << name << '\n';
00636       }
00637     }
00638     out << '\n';
00639     if (m_enable_timing_modules) {
00640       out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time)  ")    << "     Active  Module" << '\n';
00641       for (auto & keyval: m_modules) {
00642         std::string const & label  = keyval.first->moduleLabel();
00643         ModuleInfo  const & module = keyval.second;
00644         out << "FastReport              " << std::right << std::setw(10) << module.summary_active  / (double) m_summary_events << "  " << label << '\n';
00645       }
00646       out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time)  ")    << "     Active  Module" << '\n';
00647     }
00648     out << '\n';
00649     edm::LogVerbatim("FastReport") << out.str();
00650   }
00651 
00652   // needed for the DAQ when reconfiguring between runs
00653   reset();
00654 }
00655 
00656 void FastTimerService::reset() {
00657   // transient dqm configuration
00658   m_nproc_enabled = false;
00659   // caching
00660   m_first_path = 0;          // these are initialized at prePathBeginRun(),
00661   m_last_path = 0;           // to make sure we cache the correct pointers
00662   m_first_endpath = 0;
00663   m_last_endpath = 0;
00664   m_is_first_module = false;
00665   // per-event accounting
00666   m_event = 0.;
00667   m_source = 0.;
00668   m_all_paths = 0.;
00669   m_all_endpaths = 0.;
00670   m_interpaths = 0.;
00671   // per-job summary
00672   m_summary_events = 0;
00673   m_summary_event = 0.;
00674   m_summary_source = 0.;
00675   m_summary_all_paths = 0.;
00676   m_summary_all_endpaths = 0.;
00677   m_summary_interpaths = 0.;
00678   // DQM - the DAQ destroys and re-creates the DQM and DQMStore services at each reconfigure, so we don't need to clean them up
00679   m_dqms = 0;
00680   // event summary plots
00681   m_dqm_event = 0;
00682   m_dqm_source = 0;
00683   m_dqm_all_paths = 0;
00684   m_dqm_all_endpaths = 0;
00685   m_dqm_interpaths = 0;
00686   // event summary plots - summed over nodes with the same number of processes
00687   m_dqm_nproc_event = 0;
00688   m_dqm_nproc_source = 0;
00689   m_dqm_nproc_all_paths = 0;
00690   m_dqm_nproc_all_endpaths = 0;
00691   m_dqm_nproc_interpaths = 0;
00692   // plots by path
00693   m_dqm_paths_active_time = 0;
00694   m_dqm_paths_total_time = 0;
00695   m_dqm_paths_exclusive_time = 0;
00696   m_dqm_paths_interpaths = 0;
00697   // plots per lumisection
00698   m_dqm_byls_event = 0;
00699   m_dqm_byls_source = 0;
00700   m_dqm_byls_all_paths = 0;
00701   m_dqm_byls_all_endpaths = 0;
00702   m_dqm_byls_interpaths = 0;
00703   // plots per lumisection - summed over nodes with the same number of processes
00704   m_dqm_nproc_byls_event = 0;
00705   m_dqm_nproc_byls_source = 0;
00706   m_dqm_nproc_byls_all_paths = 0;
00707   m_dqm_nproc_byls_all_endpaths = 0;
00708   m_dqm_nproc_byls_interpaths = 0;
00709   // plots vs. instantaneous luminosity
00710   m_dqm_byluminosity_event = 0;
00711   m_dqm_byluminosity_source = 0;
00712   m_dqm_byluminosity_all_paths = 0;
00713   m_dqm_byluminosity_all_endpaths = 0;
00714   m_dqm_byluminosity_interpaths = 0;
00715   // plots vs. instantaneous luminosity - summed over nodes with the same number of processes
00716   m_dqm_nproc_byluminosity_event = 0;
00717   m_dqm_nproc_byluminosity_source = 0;
00718   m_dqm_nproc_byluminosity_all_paths = 0;
00719   m_dqm_nproc_byluminosity_all_endpaths = 0;
00720   m_dqm_nproc_byluminosity_interpaths = 0;
00721   // per-path and per-module accounting
00722   m_current_path = 0;
00723   m_paths.clear();          // this should destroy all PathInfo objects and Reset the associated plots
00724   m_modules.clear();        // this should destroy all ModuleInfo objects and Reset the associated plots
00725   m_cache_paths.clear();
00726   m_cache_modules.clear();
00727 }
00728 
00729 void FastTimerService::preModuleBeginJob(edm::ModuleDescription const & module) {
00730   //edm::LogImportant("FastTimerService") << __func__ << "(" << & module << ")";
00731   //edm::LogImportant("FastTimerService") << "module " << module.moduleLabel() << " @ " << & module;
00732 
00733   // allocate a counter for each module
00734   m_modules[& module];
00735 }
00736 
00737 void FastTimerService::preProcessEvent(edm::EventID const & id, edm::Timestamp const & stamp) {
00738   //edm::LogImportant("FastTimerService") << __func__ << "(...)";
00739 
00740   // new event, reset the per-event counter
00741   start(m_timer_event);
00742 
00743   // clear the event counters
00744   m_event        = 0;
00745   m_all_paths    = 0;
00746   m_all_endpaths = 0;
00747   m_interpaths   = 0;
00748   for (PathInfo * path: m_cache_paths) {
00749     path->time_active       = 0.;
00750     path->time_premodules   = 0.;
00751     path->time_intermodules = 0.;
00752     path->time_postmodules  = 0.;
00753     path->time_total        = 0.;
00754   }
00755   for (ModuleInfo * module: m_cache_modules) {
00756     module->time_active     = 0.;
00757     module->has_just_run    = false;
00758     module->is_exclusive    = false;
00759   }
00760 
00761   // copy the start event timestamp as the end of the previous path
00762   // used by the inter-path overhead measurement
00763   m_timer_path.second = m_timer_event.first;
00764 }
00765 
00766 void FastTimerService::postProcessEvent(edm::Event const & event, edm::EventSetup const & setup) {
00767   //edm::LogImportant("FastTimerService") << __func__ << "(...)";
00768 
00769   if (m_enable_timing_exclusive) {
00770     for (auto & keyval: m_paths) {
00771       PathInfo & pathinfo = keyval.second;
00772       float exclusive = pathinfo.time_overhead;
00773 
00774       for (uint32_t i = 0; i <= pathinfo.last_run; ++i) {
00775         ModuleInfo * module = pathinfo.modules[i];
00776         if (module == 0)
00777           // this is a module occurring more than once in the same path, skip it after the first occurrence
00778           continue;
00779         if (module->is_exclusive)
00780           exclusive += module->time_active;
00781       }
00782       m_dqm_paths_exclusive_time->Fill(pathinfo.index, exclusive * 1000.);
00783       if (m_enable_dqm_bypath_exclusive) {
00784         pathinfo.dqm_exclusive->Fill(exclusive * 1000.);
00785       }
00786     }
00787   }
00788 
00789   // stop the per-event timer, and account event time
00790   stop(m_timer_event);
00791   m_event = delta(m_timer_event);
00792   m_summary_event += m_event;
00793   // the last part of inter-path overhead is the time between the end of the last (end)path and the end of the event processing
00794   double interpaths = delta(m_timer_path.second, m_timer_event.second);
00795   m_interpaths += interpaths;
00796   m_summary_interpaths += m_interpaths;
00797   if (m_dqms) {
00798     m_dqm_paths_interpaths->Fill(m_paths.size(), interpaths * 1000.);
00799     
00800     if (m_enable_dqm_summary) {
00801       m_dqm_event         ->Fill(m_event          * 1000.);
00802       m_dqm_source        ->Fill(m_source         * 1000.);
00803       m_dqm_all_paths     ->Fill(m_all_paths      * 1000.);
00804       m_dqm_all_endpaths  ->Fill(m_all_endpaths   * 1000.);
00805       m_dqm_interpaths    ->Fill(m_interpaths     * 1000.);
00806 
00807       if (m_nproc_enabled) {
00808         m_dqm_nproc_event         ->Fill(m_event          * 1000.);
00809         m_dqm_nproc_source        ->Fill(m_source         * 1000.);
00810         m_dqm_nproc_all_paths     ->Fill(m_all_paths      * 1000.);
00811         m_dqm_nproc_all_endpaths  ->Fill(m_all_endpaths   * 1000.);
00812         m_dqm_nproc_interpaths    ->Fill(m_interpaths     * 1000.);
00813       }
00814     }
00815 
00816     if (m_enable_dqm_byls) {
00817       unsigned int ls = event.getLuminosityBlock().luminosityBlock();
00818       m_dqm_byls_event        ->Fill(ls, m_event        * 1000.);
00819       m_dqm_byls_source       ->Fill(ls, m_source       * 1000.);
00820       m_dqm_byls_all_paths    ->Fill(ls, m_all_paths    * 1000.);
00821       m_dqm_byls_all_endpaths ->Fill(ls, m_all_endpaths * 1000.);
00822       m_dqm_byls_interpaths   ->Fill(ls, m_interpaths   * 1000.);
00823       
00824       if (m_nproc_enabled) {
00825         m_dqm_nproc_byls_event        ->Fill(ls, m_event        * 1000.);
00826         m_dqm_nproc_byls_source       ->Fill(ls, m_source       * 1000.);
00827         m_dqm_nproc_byls_all_paths    ->Fill(ls, m_all_paths    * 1000.);
00828         m_dqm_nproc_byls_all_endpaths ->Fill(ls, m_all_endpaths * 1000.);
00829         m_dqm_nproc_byls_interpaths   ->Fill(ls, m_interpaths   * 1000.);
00830       }
00831     }
00832 
00833     if (m_enable_dqm_byluminosity) {
00834       float luminosity = 0.;
00835       edm::Handle<LumiScalersCollection> h_luminosity;
00836       if (event.getByLabel(m_luminosity_label, h_luminosity) and not h_luminosity->empty())
00837         luminosity = h_luminosity->front().instantLumi();
00838 
00839       m_dqm_byluminosity_event        ->Fill(luminosity, m_event        * 1000.);
00840       m_dqm_byluminosity_source       ->Fill(luminosity, m_source       * 1000.);
00841       m_dqm_byluminosity_all_paths    ->Fill(luminosity, m_all_paths    * 1000.);
00842       m_dqm_byluminosity_all_endpaths ->Fill(luminosity, m_all_endpaths * 1000.);
00843       m_dqm_byluminosity_interpaths   ->Fill(luminosity, m_interpaths   * 1000.);
00844       
00845       if (m_nproc_enabled) {
00846         m_dqm_nproc_byluminosity_event        ->Fill(luminosity, m_event        * 1000.);
00847         m_dqm_nproc_byluminosity_source       ->Fill(luminosity, m_source       * 1000.);
00848         m_dqm_nproc_byluminosity_all_paths    ->Fill(luminosity, m_all_paths    * 1000.);
00849         m_dqm_nproc_byluminosity_all_endpaths ->Fill(luminosity, m_all_endpaths * 1000.);
00850         m_dqm_nproc_byluminosity_interpaths   ->Fill(luminosity, m_interpaths   * 1000.);
00851       }
00852     }
00853   }
00854 }
00855 
00856 void FastTimerService::preSource() {
00857   //edm::LogImportant("FastTimerService") << __func__ << "()";
00858 
00859   start(m_timer_source);
00860 
00861   // clear the event counters
00862   m_source = 0;
00863 
00864   // keep track of the total number of events
00865   ++m_summary_events;
00866 }
00867 
00868 void FastTimerService::postSource() {
00869   //edm::LogImportant("FastTimerService") << __func__ << "()";
00870 
00871   stop(m_timer_source);
00872   m_source = delta(m_timer_source);
00873   m_summary_source += m_source;
00874 }
00875 
00876 void FastTimerService::prePathBeginRun(std::string const & path ) {
00877   //edm::LogImportant("FastTimerService") << __func__ << "(" << path << ")";
00878 
00879   // cache the pointers to the names of the first and last path and endpath
00880   edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00881   if (not m_skip_first_path and not tns.getTrigPaths().empty()) {
00882     if (path == tns.getTrigPaths().front())
00883       m_first_path = & path;
00884     if (path == tns.getTrigPaths().back())
00885       m_last_path = & path;
00886   }
00887   else if (m_skip_first_path and tns.getTrigPaths().size() > 1) {
00888     if (path == tns.getTrigPaths().at(1))
00889       m_first_path = & path;
00890     if (path == tns.getTrigPaths().back())
00891       m_last_path = & path;
00892   }
00893   if (not tns.getEndPaths().empty()) {
00894     if (path == tns.getEndPaths().front())
00895       m_first_endpath = & path;
00896     if (path == tns.getEndPaths().back())
00897       m_last_endpath = & path;
00898   }
00899 }
00900 
00901 void FastTimerService::preProcessPath(std::string const & path ) {
00902   //edm::LogImportant("FastTimerService") << __func__ << "(" << path << ")";
00903 
00904   // prepare to measure the time spent between the beginning of the path and the execution of the first module
00905   m_is_first_module = true;
00906 
00907   PathMap<PathInfo>::iterator keyval = m_paths.find(path);
00908   if (keyval != m_paths.end()) {
00909     m_current_path = & keyval->second;
00910 
00911     if (m_enable_timing_modules) {
00912       // reset the status of this path's modules
00913       for (ModuleInfo * module: m_current_path->modules)
00914         if (module)
00915           module->has_just_run = false;
00916     }
00917   } else {
00918     // should never get here
00919     m_current_path = 0;
00920     edm::LogError("FastTimerService") << "FastTimerService::preProcessPath: unexpected path " << path;
00921   }
00922 
00923   // time each (end)path
00924   start(m_timer_path);
00925 
00926   if (& path == m_first_path) {
00927     // this is the first path, start the "all paths" counter
00928     m_timer_paths.first = m_timer_path.first;
00929   } else if (& path == m_first_endpath) {
00930     // this is the first endpath, start the "all paths" counter
00931     m_timer_endpaths.first = m_timer_path.first;
00932   }
00933 
00934   // measure the inter-path overhead as the time elapsed since the end of preiovus path
00935   // (or the beginning of the event, if this is the first path - see preProcessEvent)
00936   double interpaths = delta(m_timer_path.second,  m_timer_path.first);
00937   m_interpaths += interpaths;
00938   if (m_dqms) {
00939     m_dqm_paths_interpaths->Fill(m_current_path->index, interpaths * 1000.);
00940   }
00941 }
00942 
00943 void FastTimerService::postProcessPath(std::string const & path, edm::HLTPathStatus const & status) {
00944   //edm::LogImportant("FastTimerService") << __func__ << "(" << path << ", ...)";
00945 
00946   // time each (end)path
00947   stop(m_timer_path);
00948 
00949   double active = delta(m_timer_path);
00950 
00951   // if enabled, account each (end)path
00952   if (m_enable_timing_paths) {
00953 
00954     PathInfo & pathinfo = * m_current_path;
00955     pathinfo.time_active = active;
00956     pathinfo.summary_active += active;
00957 
00958     if (m_dqms) {
00959       m_dqm_paths_active_time->Fill(pathinfo.index, active * 1000.);
00960       if (m_enable_dqm_bypath_active) {
00961         pathinfo.dqm_active->Fill(active * 1000.);
00962       }
00963     }
00964 
00965     // measure the time spent between the execution of the last module and the end of the path
00966     if (m_enable_timing_modules) {
00967       double pre      = 0.;                 // time spent before the first active module
00968       double inter    = 0.;                 // time spent between active modules
00969       double post     = 0.;                 // time spent after the last active module
00970       double overhead = 0.;                 // time spent before, between, or after modules
00971       double current  = 0.;                 // time spent in modules active in the current path
00972       double total    = active;             // total per-path time, including modules already run as part of other paths
00973 
00974       // implementation note:
00975       // "active"   has already measured all the time spent in this path
00976       // "current"  will be the sum of the time spent inside each module while running this path, so that
00977       // "overhead" will be active - current
00978       // "total"    will be active + the sum of the time spent in non-active modules
00979 
00980       uint32_t last_run = status.index();     // index of the last module run in this path
00981       for (uint32_t i = 0; i <= last_run; ++i) {
00982         ModuleInfo * module = pathinfo.modules[i];
00983 
00984         // fill counter histograms - also for duplicate modules, to properly extract rejection information
00985         if (m_enable_dqm_bypath_counters) {
00986           pathinfo.dqm_module_counter->Fill(i);
00987         }
00988         
00989         if (module == 0)
00990           // this is a module occurring more than once in the same path, skip it after the first occurrence
00991           continue;
00992 
00993         if (module->has_just_run) {
00994           current += module->time_active;
00995           module->is_exclusive = true;
00996         } else {
00997           total   += module->time_active;
00998           module->is_exclusive = false;
00999         }
01000 
01001         // fill detailed timing histograms
01002         if (m_enable_dqm_bypath_details) {
01003           // fill the total time for all non-duplicate modules
01004           pathinfo.dqm_module_total->Fill(i, module->time_active * 1000.);
01005           if (module->has_just_run) {
01006             // fill the active time only for module actually running in this path
01007             pathinfo.dqm_module_active->Fill(i, module->time_active * 1000.);
01008           }
01009         }
01010 
01011       }
01012 
01013       if (status.accept())
01014         if (m_enable_dqm_bypath_counters) {
01015           pathinfo.dqm_module_counter->Fill(pathinfo.modules.size());
01016         }
01017 
01018       if (m_is_first_module) {
01019         // no modules were active during this path, account all the time as overhead
01020         pre      = 0.;
01021         inter    = 0.;
01022         post     = active;
01023         overhead = active;
01024       } else {
01025         // extract overhead information
01026         pre      = delta(m_timer_path.first,    m_timer_first_module);
01027         post     = delta(m_timer_module.second, m_timer_path.second);
01028         inter    = active - pre - current - post;
01029         // take care of numeric precision and rounding errors - the timer is less precise than nanosecond resolution
01030         if (std::abs(inter) < 1e-9)
01031           inter = 0.;
01032         overhead = active - current;
01033         // take care of numeric precision and rounding errors - the timer is less precise than nanosecond resolution
01034         if (std::abs(overhead) < 1e-9)
01035           overhead = 0.;
01036       }
01037 
01038       pathinfo.time_premodules       = pre;
01039       pathinfo.time_intermodules     = inter;
01040       pathinfo.time_postmodules      = post;
01041       pathinfo.time_overhead         = overhead;
01042       pathinfo.time_total            = total;
01043       pathinfo.summary_premodules   += pre;
01044       pathinfo.summary_intermodules += inter;
01045       pathinfo.summary_postmodules  += post;
01046       pathinfo.summary_overhead     += overhead;
01047       pathinfo.summary_total        += total;
01048       pathinfo.last_run              = last_run;
01049       if (m_dqms) {
01050         if (m_enable_dqm_bypath_overhead) {
01051           pathinfo.dqm_premodules  ->Fill(pre      * 1000.);
01052           pathinfo.dqm_intermodules->Fill(inter    * 1000.);
01053           pathinfo.dqm_postmodules ->Fill(post     * 1000.);
01054           pathinfo.dqm_overhead    ->Fill(overhead * 1000.);
01055         }
01056         m_dqm_paths_total_time->Fill(pathinfo.index, total * 1000.);
01057         if (m_enable_dqm_bypath_total) {
01058           pathinfo.dqm_total       ->Fill(total    * 1000.);
01059         }
01060       }
01061     }
01062   }
01063 
01064   if (& path == m_last_path) {
01065     // this is the last path, stop and account the "all paths" counter
01066     m_timer_paths.second = m_timer_path.second;
01067     m_all_paths = delta(m_timer_paths);
01068     m_summary_all_paths += m_all_paths;
01069   } else if (& path == m_last_endpath) {
01070     // this is the last endpath, stop and account the "all endpaths" counter
01071     m_timer_endpaths.second = m_timer_path.second;
01072     m_all_endpaths = delta(m_timer_endpaths);
01073     m_summary_all_endpaths += m_all_endpaths;
01074   }
01075 
01076 }
01077 
01078 void FastTimerService::preModule(edm::ModuleDescription const & module) {
01079   //edm::LogImportant("FastTimerService") << __func__ << "(" << & module << ")";
01080 
01081   // this is ever called only if m_enable_timing_modules = true
01082   assert(m_enable_timing_modules);
01083 
01084   // time each module
01085   start(m_timer_module);
01086 
01087   if (m_is_first_module) {
01088     m_is_first_module = false;
01089 
01090     // measure the time spent between the beginning of the path and the execution of the first module
01091     m_timer_first_module = m_timer_module.first;
01092   } 
01093 }
01094 
01095 void FastTimerService::postModule(edm::ModuleDescription const & module) {
01096   //edm::LogImportant("FastTimerService") << __func__ << "(" << & module << ")";
01097 
01098   // this is ever called only if m_enable_timing_modules = true
01099   assert(m_enable_timing_modules);
01100 
01101   // time and account each module
01102   stop(m_timer_module);
01103 
01104   ModuleMap<ModuleInfo>::iterator keyval = m_modules.find(& module);
01105   if (keyval != m_modules.end()) {
01106     double time = delta(m_timer_module);
01107     ModuleInfo & module = keyval->second;
01108     module.has_just_run    = true;
01109     module.time_active     = time;
01110     module.summary_active += time;
01111 
01112     if (m_dqms and m_enable_dqm_bymodule) {
01113       module.dqm_active->Fill(time * 1000.);
01114     }
01115   } else {
01116     // should never get here
01117     edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected module " << module.moduleLabel();
01118   }
01119 }
01120 
01121 // find the module description associated to a module, by label
01122 edm::ModuleDescription const * FastTimerService::findModuleDescription(const std::string & label) const {
01123   // no descriptions are associated to an empty label
01124   if (label.empty())
01125     return 0;
01126 
01127   // fix the name of negated or ignored modules
01128   std::string const & target = (label[0] == '!' or label[0] == '-') ? label.substr(1) : label;
01129 
01130   for (auto const & keyval: m_modules) {
01131     if (keyval.first == 0) {
01132       // this should never happen, but it would cause a segmentation fault to insert a null pointer in the path map, se we explicitly check for it and skip it
01133       edm::LogError("FastTimerService") << "FastTimerService::findModuleDescription: invalid entry detected in ModuleMap<ModuleInfo> m_modules, skipping";
01134       continue;
01135     }
01136     if (keyval.first->moduleLabel() == target) {
01137       return keyval.first;
01138     }
01139   }
01140   // not found
01141   return 0;
01142 }
01143 
01144 // associate to a path all the modules it contains
01145 void FastTimerService::fillPathMap(std::string const & name, std::vector<std::string> const & modules) {
01146   std::vector<ModuleInfo *> & pathmap = m_paths[name].modules;
01147   pathmap.reserve( modules.size() );
01148   std::tr1::unordered_set<edm::ModuleDescription const *> pool;        // keep track of inserted modules
01149   for (auto const & module: modules) {
01150     edm::ModuleDescription const * md = findModuleDescription(module);
01151     if (md == 0) {
01152       // no matching module was found
01153       pathmap.push_back( 0 );
01154     } else if (pool.insert(md).second) {
01155       // new module
01156       pathmap.push_back( & m_modules[md] );
01157     } else {
01158       // duplicate module
01159       pathmap.push_back( 0 );
01160     }
01161   }
01162 }
01163 
01164 
01165 // query the current module/path/event
01166 // Note: these functions incur in a "per-call timer overhead" (see above), currently of the order of 340ns
01167 
01168 // return the time spent since the last preModule() event
01169 double FastTimerService::currentModuleTime() const {
01170   struct timespec now;
01171   gettime(now);
01172   return delta(m_timer_module.first, now);
01173 }
01174 
01175 // return the time spent since the last preProcessPath() event
01176 double FastTimerService::currentPathTime() const {
01177   struct timespec now;
01178   gettime(now);
01179   return delta(m_timer_path.first, now);
01180 }
01181 
01182 // return the time spent since the last preProcessEvent() event
01183 double FastTimerService::currentEventTime() const {
01184   struct timespec now;
01185   gettime(now);
01186   return delta(m_timer_event.first, now);
01187 }
01188 
01189 // query the time spent in a module (available after the module has run)
01190 double FastTimerService::queryModuleTime(const edm::ModuleDescription & module) const {
01191   ModuleMap<ModuleInfo>::const_iterator keyval = m_modules.find(& module);
01192   if (keyval != m_modules.end()) {
01193     return keyval->second.time_active;
01194   } else {
01195     edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected module " << module.moduleLabel();
01196     return 0.;
01197   }
01198 }
01199 
01200 // query the time spent in a path (available after the path has run)
01201 double FastTimerService::queryPathActiveTime(const std::string & path) const {
01202   PathMap<PathInfo>::const_iterator keyval = m_paths.find(path);
01203   if (keyval != m_paths.end()) {
01204     return keyval->second.time_active;
01205   } else {
01206     edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected path " << path;
01207     return 0.;
01208   }
01209 }
01210 
01211 // query the total time spent in a path (available after the path has run)
01212 double FastTimerService::queryPathTotalTime(const std::string & path) const {
01213   PathMap<PathInfo>::const_iterator keyval = m_paths.find(path);
01214   if (keyval != m_paths.end()) {
01215     return keyval->second.time_total;
01216   } else {
01217     edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected path " << path;
01218     return 0.;
01219   }
01220 }
01221 
01222 // query the time spent in the current event's source (available during event processing)
01223 double FastTimerService::querySourceTime() const {
01224   return m_source;
01225 }
01226 
01227 // query the time spent in the current event's paths (available during endpaths)
01228 double FastTimerService::queryPathsTime() const {
01229   return m_all_paths;
01230 }
01231 
01232 // query the time spent in the current event's endpaths (available after all endpaths have run)
01233 double FastTimerService::queryEndPathsTime() const {
01234   return m_all_endpaths;
01235 }
01236 
01237 // query the time spent processing the current event (available after the event has been processed)
01238 double FastTimerService::queryEventTime() const {
01239   return m_event;
01240 }
01241 
01242 // describe the module's configuration
01243 void FastTimerService::fillDescriptions(edm::ConfigurationDescriptions & descriptions) {
01244   edm::ParameterSetDescription desc;
01245   desc.addUntracked<bool>(   "useRealTimeClock",         true);
01246   desc.addUntracked<bool>(   "enableTimingPaths",        true);
01247   desc.addUntracked<bool>(   "enableTimingModules",      true);
01248   desc.addUntracked<bool>(   "enableTimingExclusive",    false);
01249   desc.addUntracked<bool>(   "enableTimingSummary",      false);
01250   desc.addUntracked<bool>(   "skipFirstPath",            false), 
01251   desc.addUntracked<bool>(   "enableDQM",                true);
01252   desc.addUntracked<bool>(   "enableDQMbyPathActive",    false);
01253   desc.addUntracked<bool>(   "enableDQMbyPathTotal",     true);
01254   desc.addUntracked<bool>(   "enableDQMbyPathOverhead",  false);
01255   desc.addUntracked<bool>(   "enableDQMbyPathDetails",   false);
01256   desc.addUntracked<bool>(   "enableDQMbyPathCounters",  true);
01257   desc.addUntracked<bool>(   "enableDQMbyPathExclusive", false);
01258   desc.addUntracked<bool>(   "enableDQMbyModule",        false);
01259   desc.addUntracked<bool>(   "enableDQMSummary",         false);
01260   desc.addUntracked<bool>(   "enableDQMbyLuminosity",    false);
01261   desc.addNode(
01262     edm::ParameterDescription<bool>(   "enableDQMbyLumiSection", false, false) or
01263     edm::ParameterDescription<bool>(   "enableDQMbyLumi",        false, false)
01264   );
01265   desc.addUntracked<bool>(   "enableDQMbyProcesses",     false);
01266   desc.addUntracked<double>( "dqmTimeRange",             1000. );   // ms
01267   desc.addUntracked<double>( "dqmTimeResolution",           5. );   // ms
01268   desc.addUntracked<double>( "dqmPathTimeRange",          100. );   // ms
01269   desc.addUntracked<double>( "dqmPathTimeResolution",       0.5);   // ms
01270   desc.addUntracked<double>( "dqmModuleTimeRange",         40. );   // ms
01271   desc.addUntracked<double>( "dqmModuleTimeResolution",     0.2);   // ms
01272   desc.addUntracked<double>( "dqmLuminosityRange",      1.e34  );   // cm-2 s-1
01273   desc.addUntracked<double>( "dqmLuminosityResolution", 1.e31  );   // cm-2 s-1
01274   desc.addUntracked<uint32_t>( "dqmLumiSectionsRange",   2500  );   // ~ 16 hours
01275   desc.addUntracked<std::string>(   "dqmPath",           "HLT/TimerService");
01276   desc.addUntracked<edm::InputTag>( "luminosityProduct", edm::InputTag("hltScalersRawToDigi"));
01277   desc.addUntracked<std::vector<unsigned int> >("supportedProcesses", { 8, 24, 32 });
01278   descriptions.add("FastTimerService", desc);
01279 }