13#include "GaudiKernel/DirSearchPath.h"
14#include "GaudiKernel/IIncidentSvc.h"
15#include "Gaudi/Interfaces/IOptionsSvc.h"
16#include "eformat/DetectorMask.h"
17#include "eformat/SourceIdentifier.h"
26 std::string folder2HistName(
const std::string& folder)
28 std::string
s(folder);
29 if (
s.front() ==
'/')
s.erase(0, 1);
30 std::replace(
s.begin(),
s.end(),
'/',
'_');
35 StatusCode readReleaseData(
const std::string&
file, std::map<std::string, std::string>&
result)
38 f.open(
file.c_str(), std::ifstream::in);
39 if (!
f.is_open())
return StatusCode::FAILURE;
42 while (getline(f, line)) {
44 std::string::size_type loc =
line.find(
':');
45 if (loc == std::string::npos || loc == 0)
continue;
49 return StatusCode::SUCCESS;
55 base_class(name, pSvcLocator),
56 m_histPath(
"/EXPERT/HLTFramework/" + name +
"/")
68 return StatusCode::SUCCESS;
89 return StatusCode::SUCCESS;
95 [[maybe_unused]]
const static bool once = [&]() {
101 const EventContext& ctx = getContext();
112 return StatusCode::SUCCESS;
121 m_iovChangeHist =
new TH2I(
"CoolFolderUpdate_LB",
"COOL folder updates;Lumiblock;", 1, 0, 1, 1, 0, 1);
124 m_magFieldHist =
new TH2I(
"MagneticFieldSettings",
"Magnetic field settings", 2, 0, 2, 2, 0, 2);
130 m_releaseHist =
new TH1I(
"GeneralOpInfo",
"General operational info;;Applications", 1, 0, 1);
132 m_mtConfigHist =
new TH2I(
"MTConfig",
"Multi-threading configuration", 2, 0, 2, 10, 0, 10);
137 m_workersHist =
new TH1I(
"MPWorkers",
"Worker IDs;Worker ID;Number of workers", 10, 0, 10);
140 m_subdetHist =
new TH2I(
"Subdetectors",
"State of subdetectors", 1, 0, 1, 3, 0, 3);
146 m_lumiHist =
new TProfile(
"Luminosity",
"Luminosity;Lumiblock;Luminosity [10^{33} cm^{-2}s^{-1}]",
156 for (TH1*
h : hist) {
160 return StatusCode::SUCCESS;
177 std::vector<std::string> keyList;
181 TH2I* IOVDbRunHist =
new TH2I(
"IOVDbRunRange",
"IOVDb Run Range", 1, 0, 1, 1, 0, 1);
182 TH2I* IOVDbTimeHist =
new TH2I(
"IOVDbTimeRange",
"IOVDb Time Range", 1, 0, 1, 1, 0, 1);
183 TProfile* IOVDbBytesReadHist =
new TProfile(
"IOVDbBytesRead",
"Folder data read", 1, 0, 1);
184 IOVDbBytesReadHist->SetYTitle(
"Data read [bytes]");
185 TProfile* IOVDbReadTimeHist =
new TProfile(
"IOVDbReadTime",
"Folder update time", 1, 0, 1);
186 IOVDbReadTimeHist->SetYTitle(
"Update time [ms]");
190 for (
const std::string& key : keyList) {
192 if (
m_IOVDbSvc->getKeyInfo(key, info) && info.retrieved) {
197 IOVTime stop(info.range.stop());
200 if (
start.isRunEvent()) {
201 IOVDbRunHist->Fill(std::to_string(
start.run()).c_str(), info.folderName.c_str(), 1.0);
205 if (
start.isTimestamp()) {
206 IOVDbTimeHist->Fill(std::to_string(
start.timestamp()).c_str(), info.folderName.c_str(), 1.0);
210 if (stop.isRunEvent()) {
212 IOVDbRunHist->Fill(
"infinity", info.folderName.c_str(), 1.0);
215 IOVDbRunHist->Fill(std::to_string(stop.run()).c_str(), info.folderName.c_str(), 1.0);
220 if (stop.isTimestamp()) {
222 IOVDbTimeHist->Fill(
"infinity", info.folderName.c_str(), 1.0);
225 IOVDbTimeHist->Fill(std::to_string(stop.timestamp()).c_str(), info.folderName.c_str(), 1.0);
230 IOVDbBytesReadHist->Fill(info.folderName.c_str(), info.bytesRead, 1.0);
231 IOVDbReadTimeHist->Fill(info.folderName.c_str(), info.readTime * 1000, 1.0);
236 IOVDbRunHist->LabelsDeflate(
"X");
237 IOVDbRunHist->LabelsDeflate(
"Y");
238 IOVDbRunHist->GetYaxis()->LabelsOption(
"a");
240 IOVDbTimeHist->LabelsDeflate(
"X");
241 IOVDbTimeHist->LabelsDeflate(
"Y");
242 IOVDbTimeHist->GetYaxis()->LabelsOption(
"a");
244 IOVDbBytesReadHist->LabelsDeflate(
"X");
245 IOVDbReadTimeHist->LabelsDeflate(
"X");
248 TH1* hist[] = {IOVDbRunHist, IOVDbTimeHist, IOVDbBytesReadHist, IOVDbReadTimeHist};
249 for (TH1*
h : hist) {
256 std::vector<std::string> keys;
261 for (
const std::string& k : keys) {
263 if (not
m_IOVDbSvc->getKeyInfo(k, info))
continue;
264 if (not info.retrieved)
continue;
273 if (info.range != curIOV->second) {
274 ATH_MSG_INFO(
"IOV of " << k <<
" changed from " << curIOV->second <<
" to " << info.range
275 <<
" on event: " << ctx.eventID());
280 m_iovChangeHist->Fill(std::to_string(ctx.eventID().lumi_block()).c_str(), info.folderName.c_str(),
290 std::string name(folder2HistName(info.folderName));
293 fh->second.h_time =
new TH1F((name +
"_ReadTime").c_str(),
294 (
"Update time for " + info.folderName +
";Time [ms];Entries").c_str(),
297 fh->second.h_bytes =
new TH1F(
298 (name +
"_BytesRead").c_str(),
299 (
"Bytes read for " + info.folderName +
";Data [bytes];Entries").c_str(), 100, 0, 1000);
301 for (TH1*
h : {fh->second.h_time, fh->second.h_bytes}) {
307 fh->second.h_time->Fill(info.readTime * 1000 -
m_folderHist[info.folderName].total_time);
308 fh->second.total_time += info.readTime * 1000;
310 fh->second.h_bytes->Fill(info.bytesRead -
m_folderHist[info.folderName].total_bytes);
311 fh->second.total_bytes += info.bytesRead;
323 m_lumiHist->Fill(ctx.eventID().lumi_block(), lumiData->lbAverageLuminosity());
324 m_muHist->Fill(ctx.eventID().lumi_block(), lumiData->lbAverageInteractionsPerCrossing());
330 const char* ld_lib_path = getenv(
"LD_LIBRARY_PATH");
331 if (ld_lib_path ==
nullptr) {
332 ATH_MSG_WARNING(
"LD_LIBRARY_PATH is not defined. Will not fill release histogram.");
337 std::list<DirSearchPath::path> file_list = DirSearchPath(ld_lib_path,
":").find_all(
m_releaseData.value());
339 if (file_list.empty()) {
341 <<
" in LD_LIBRARY_PATH");
346 for (
const auto& f : file_list) {
348 std::map<std::string, std::string>
result;
349 if (readReleaseData(f.string(),
result).isFailure()) {
370 auto getIntProp = [
this](std::string_view name,
const std::string& prop) -> std::optional<int> {
371 IProperty* svc = serviceLocator()->service(name).as<IProperty>();
372 if (svc ==
nullptr)
return std::nullopt;
374 return std::stoi(svc->getProperty(prop).toString());
381 const std::optional<int> numThreads = getIntProp(
"AvalancheSchedulerSvc",
"ThreadPoolSize");
382 if (numThreads.has_value()) {
386 ATH_MSG_WARNING(
"Could not retrieve the number of threads to fill the monitoring histogram");
389 const std::optional<int> numSlots = getIntProp(
"EventDataSvc",
"NSlots");
390 if (numSlots.has_value()) {
394 ATH_MSG_WARNING(
"Could not retrieve the number of slots to fill the monitoring histogram");
402 auto jobOptionsSvc = service<Gaudi::Interfaces::IOptionsSvc>(
"JobOptionsSvc",
false);
403 if (!jobOptionsSvc.isValid()) {
404 ATH_MSG_WARNING(
"Could not retrieve JobOptionsSvc, will not fill SubDetectors histogram");
408 Gaudi::Property<std::vector<uint32_t>> enabledROBsProp(
"EnabledROBs",{});
409 std::set<uint32_t> enabledROBs;
410 if (enabledROBsProp.fromString(jobOptionsSvc->get(
"DataFlowConfig.DF_Enabled_ROB_IDs",
"[]")).isSuccess()) {
411 enabledROBs.insert(enabledROBsProp.value().begin(), enabledROBsProp.value().end());
413 <<
" ROBs from DataFlowConfig.DF_Enabled_ROB_IDs");
416 ATH_MSG_ERROR(
"Could not parse DataFlowConfig.DF_Enabled_ROB_IDs from JobOptionsSvc");
420 SmartIF<StoreGateSvc> inputMetaDataStore = service<StoreGateSvc>(
"InputMetaDataStore",
false);
421 if (!inputMetaDataStore.isValid()) {
422 ATH_MSG_WARNING(
"Could not retrieve InputMetaDataStore, will not fill SubDetectors histogram");
426 if (inputMetaDataStore->retrieve(metadatacont,
"ByteStreamMetadata").isFailure()) {
427 ATH_MSG_WARNING(
"Could not retrieve ByteStreamMetadata, will not fill SubDetectors histogram");
432 uint64_t detMaskLeast = metadata->getDetectorMask();
433 uint64_t detMaskMost = metadata->getDetectorMask2();
436 std::vector<eformat::SubDetector> subDetOn;
437 std::vector<eformat::SubDetector> subDetOff;
438 std::vector<eformat::SubDetector> subDetAll;
439 eformat::helper::DetectorMask(detMaskLeast, detMaskMost).sub_detectors(subDetOn);
440 eformat::helper::DetectorMask(~detMaskLeast, ~detMaskMost).sub_detectors(subDetOff);
441 eformat::helper::DetectorMask(~std::bitset<128>()).sub_detectors(subDetAll);
444 for (
const eformat::SubDetector sd : subDetAll) {
445 m_subdetHist->GetXaxis()->FindBin(eformat::helper::SubDetectorDictionary.
string(sd).
data());
450 for (
const eformat::SubDetector sd : subDetOn) {
451 m_subdetHist->Fill(eformat::helper::SubDetectorDictionary.
string(sd).
data(),
"on", 1.0);
455 for (
const eformat::SubDetector sd : subDetOff) {
456 m_subdetHist->Fill(eformat::helper::SubDetectorDictionary.
string(sd).
data(),
"off", 1.0);
460 for (
const uint32_t robid : enabledROBs) {
461 const std::string sdname = eformat::helper::SourceIdentifier(robid).human_detector();
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
char data[hepevt_bytes_allocation_ATLAS]
OH histogram lock header file.
Online operations monitoring.
Header file for AthHistogramAlgorithm.
static const std::string & type()
Incident type.
int workerID() const
assigned worker ID from processing unit
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Basic time unit for IOVSvc.
static constexpr uint64_t MAXTIMESTAMP
static constexpr uint32_t MAXRUN
bool solenoidOn() const
status of the magnets
void fillProcThreadHist(int workerID)
std::string m_histPath
histogram booking path
std::unordered_map< std::string, IOVRange > m_currentIOVs
current IOVs managed by IOVDbSvc
ServiceHandle< ITHistSvc > m_histSvc
ServiceHandle< IIncidentSvc > m_incidentSvc
virtual StatusCode initialize() override
void fillReleaseDataHist()
virtual StatusCode execute() override
TrigOpMonitor(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_detailedHists
virtual StatusCode start() override
void fillIOVDbChangeHist(const EventContext &ctx)
Gaudi::Property< unsigned short int > m_maxLB
Gaudi::Property< std::string > m_releaseData
SG::ReadCondHandleKey< AtlasFieldMapCondObj > m_fieldMapKey
virtual void handle(const Incident &incident) override
std::unordered_map< std::string, FolderHist > m_folderHist
histograms for COOL folders
SG::ReadCondHandleKey< LuminosityCondData > m_lumiDataKey
void fillLumiHist(const EventContext &ctx)
EventIDBase::number_type m_previousLB
LB of previous event.
SmartIF< IIOVDbSvc > m_IOVDbSvc
Scoped lock to be used for threaded histogram operations.
Filled by IIOVDbSvc::getKeyInfo.
Histograms for COOL folders.