24 #include <TCollection.h>
30 #include <TMathBase.h>
33 #include <TPaveText.h>
35 #include <TStopwatch.h>
42 FairMonitor::FairMonitor()
43 : TNamed(
"FairMonitor",
"Monitor for FairRoot")
50 , fHistList(new TList())
64 FairMonitor::~FairMonitor() {}
79 TString tempString = Form(
"timer_%p_%s_%s", tTask, tTask->GetName(), identStr);
81 auto itt = fTimerMap.find(tempString);
82 if (itt == fTimerMap.end()) {
83 fTimerMap.insert(std::pair<TString, TStopwatch>(tempString, TStopwatch()));
84 itt = fTimerMap.find(tempString);
86 fTimerMap[tempString].Start();
94 TString tempString = Form(
"timer_%p_%s_%s", tTask, tTask->GetName(), identStr);
96 auto itt = fTimerMap.find(tempString);
97 if (itt == fTimerMap.end()) {
98 LOG(info) <<
"FairMonitor::StopTimer() called without matching StartTimer()";
102 fTimerMap[tempString].Stop();
104 Double_t time = fTimerMap[tempString].RealTime();
105 RecordInfo(tTask, Form(
"%s_TIM", identStr), time);
107 if (tempString.EndsWith(
"_EXEC"))
118 TString memMon = Form(
"mem_%p_%s_%s", tTask, tTask->GetName(), identStr);
120 auto iti = fMemoryMap.find(memMon);
121 if (iti == fMemoryMap.end())
122 fMemoryMap.insert(std::pair<TString, Int_t>(memMon, memoryAtStart));
124 iti->second = memoryAtStart;
134 TString memMon = Form(
"mem_%p_%s_%s", tTask, tTask->GetName(), identStr);
136 auto iti = fMemoryMap.find(memMon);
137 if (iti == fMemoryMap.end())
138 LOG(warn) <<
"FairMonitor::StopMemoryMonitor() Could not find corresponding entry for \"" << memMon.Data()
141 RecordInfo(tTask, Form(
"%s_MEM", identStr), memoryAtEnd - iti->second);
143 if (memMon.EndsWith(
"_EXEC"))
144 fRunMem += memoryAtEnd - iti->second;
153 TString tempString = Form(
"hist_%p_%s_%s", tTask, tTask->GetName(), identStr);
155 Int_t nofHists = fHistList->GetEntries();
157 for (ihist = 0; ihist < nofHists; ++ihist) {
158 if (!tempString.CompareTo(fHistList->At(ihist)->GetName())) {
162 if (ihist == nofHists) {
163 TString titleString = Form(
"Histogram %s for %s", identStr, tTask->GetName());
164 fHistList->Add(
new TH1F(tempString, titleString, 1000, 0, 1000));
166 TH1F* tempHist = (
static_cast<TH1F*
>((fHistList->At(ihist))));
167 Int_t nofEntries = tempHist->GetEntries();
168 if (nofEntries > tempHist->GetNbinsX())
169 tempHist->SetBins(tempHist->GetNbinsX() * 10, 0, tempHist->GetXaxis()->GetXmax() * 10);
171 tempHist->SetBinContent(nofEntries + 1, value);
179 LOG(debug) <<
"*** FM::RecordRegister(" << name <<
", " << folderName << (toFile ?
", kTRUE)" :
", kFALSE")
180 <<
" for task >>" << fCurrentTask <<
"<< (" << (fCurrentTask ? fCurrentTask->GetName() :
"") <<
")";
181 if (fCurrentTask == 0) {
183 LOG(info) <<
"*** FM::RecordRegister(" << name <<
", " << folderName << (toFile ?
", kTRUE)" :
", kFALSE")
187 TString tempString = Form(
"%p_%s", fCurrentTask, fCurrentTask->GetName());
189 fTaskCreated.insert(std::pair<TString, TString>(tempString, TString(name)));
191 fTaskCreatedTemp.insert(std::pair<TString, TString>(tempString, TString(name)));
200 LOG(debug) <<
"*** FM::RecordGetting(" << name <<
") for task >>" << fCurrentTask <<
"<< ("
201 << (fCurrentTask ? fCurrentTask->GetName() :
"") <<
")";
203 if (fCurrentTask == 0) {
207 TString tempString = Form(
"%p_%s", fCurrentTask, fCurrentTask->GetName());
208 fTaskRequired.insert(std::pair<TString, TString>(tempString, TString(name)));
216 Int_t nofHists = fHistList->GetEntries();
217 TString tempString =
"";
219 Double_t timInt = -1.;
220 Double_t timEnt = 0.;
223 char byteChar[4] = {
'B',
'k',
'M',
'G'};
225 for (Int_t ihist = 0; ihist < nofHists; ihist++) {
226 tempString = Form(
"%s", fHistList->At(ihist)->GetName());
227 if (tempString.Contains(Form(
"%p", tempTask))) {
228 if (tempString.Contains(
"EXEC_TIM")) {
229 timInt = (
static_cast<TH1F*
>(fHistList->At(ihist))->Integral());
230 timEnt = (
static_cast<TH1F*
>(fHistList->At(ihist))->GetEntries());
232 if (tempString.Contains(
"EXEC_MEM")) {
233 memInt = (
static_cast<TH1F*
>(fHistList->At(ihist))->Integral());
238 LOG(warn) <<
"FairMonitor::PrintTask(), task \"" << tempTask->GetName() <<
"\" not found!";
242 TString printString = Form(
"%f", timInt / timEnt);
243 for (Int_t itemp = printString.Length(); itemp < 10; itemp++)
244 printString.Insert(0,
' ');
245 if (printString.Length() > 10)
246 printString.Remove(11, 100);
247 printString +=
" s/ev |";
248 Double_t timePerc = 100. * timInt / fRunTime;
253 tempString = Form(
"%f", timePerc);
254 for (Int_t itemp = tempString.Length(); itemp < 8; itemp++)
256 printString += tempString;
257 printString.Remove(27, 100);
259 while (memInt > 1024) {
260 memInt = memInt / 1024;
263 tempString = Form(
"%4d", memInt);
264 printString +=
" % ] ";
266 printString +=
"- - -";
268 printString += tempString;
269 printString += byteChar[byteIdent];
271 printString +=
" \"";
272 for (Int_t ilev = 0; ilev < taskLevel; ilev++)
274 printString += tempTask->GetName();
275 if (printString.Length() > 80)
276 printString.Remove(80, 100);
278 Int_t timeFrac =
static_cast<Int_t
>((timePerc / 100. * 30.));
280 printString.Insert(37,
"\033[0m");
283 printString.Insert(32,
"\033[42m");
286 printString.Insert(32,
"\033[43m");
289 printString.Insert(32,
"\033[41m");
292 printString.Insert(timeFrac,
"\033[0m");
294 printString.Insert(0,
"[\033[42m");
295 else if (timePerc < 90)
296 printString.Insert(0,
"[\033[43m");
298 printString.Insert(0,
"[\033[41m");
299 LOG(
INFO) << printString.Data();
302 TList* subTaskList = tempTask->GetListOfTasks();
305 for (Int_t itask = 0; itask < subTaskList->GetEntries(); itask++) {
306 TTask* subTask =
static_cast<TTask*
>(subTaskList->At(itask));
315 LOG(warn) <<
"FairMonitor was disabled. Nothing to print!";
319 LOG(info) <<
"- Total Run Time: " << fRunTime <<
" s ---------------------------------------------------------";
320 TTask* mainFairTask =
static_cast<TTask*
>((gROOT->GetListOfBrowsables()->FindObject(
"FairTaskList")));
323 LOG(info) <<
"-------------------------------------------------------------------------------------";
329 LOG(warn) <<
"FairMonitor was disabled. Nothing to print!";
333 TString unitString =
"";
335 Int_t nofHists = fHistList->GetEntries();
336 for (Int_t ihist = 0; ihist < nofHists; ihist++) {
337 TString histString = Form(
"%s", fHistList->At(ihist)->GetName());
338 if (histString.Contains(specString)) {
339 histString.Replace(0, histString.First(
'_') + 1,
"");
340 histString.Replace(0, histString.First(
'_') + 1,
"");
341 Double_t integral = (
static_cast<TH1F*
>((fHistList->At(ihist)))->Integral());
342 Double_t entries = (
static_cast<TH1F*
>((fHistList->At(ihist)))->GetEntries());
344 if (histString.EndsWith(
"_TIM"))
346 if (histString.EndsWith(
"_MEM"))
348 LOG(info) << histString.Data() <<
" >>>>> " << integral << unitString.Data() <<
" / " << entries
349 <<
" ent = " << integral / entries << unitString.Data() <<
" / ent";
357 LOG(warn) <<
"FairMonitor was disabled. Nothing to print!";
361 typedef std::map<TString, Int_t>::iterator tiMapIter;
364 TTask* mainFairTask =
static_cast<TTask*
>((gROOT->GetListOfBrowsables()->FindObject(
"FairTaskList")));
368 GetTaskMap(mainFairTask);
370 for (
auto itb = fTaskRequired.begin(); itb != fTaskRequired.end(); ++itb) {
371 iti = fTaskMap.find(itb->first);
372 if (iti == fTaskMap.end())
373 fTaskMap.insert(std::pair<TString, Int_t>(itb->first, 0));
374 iti = fObjectMap.find(itb->second);
375 if (iti == fObjectMap.end())
376 fObjectMap.insert(std::pair<TString, Int_t>(itb->second, 0));
378 for (
auto itb = fTaskCreated.begin(); itb != fTaskCreated.end(); ++itb) {
379 iti = fTaskMap.find(itb->first);
380 if (iti == fTaskMap.end())
381 fTaskMap.insert(std::pair<TString, Int_t>(itb->first, 0));
382 iti = fObjectMap.find(itb->second);
383 if (iti == fObjectMap.end())
384 fObjectMap.insert(std::pair<TString, Int_t>(itb->second, 0));
386 for (
auto itb = fTaskCreatedTemp.begin(); itb != fTaskCreatedTemp.end(); ++itb) {
387 iti = fTaskMap.find(itb->first);
388 if (iti == fTaskMap.end())
389 fTaskMap.insert(std::pair<TString, Int_t>(itb->first, 0));
390 iti = fObjectMap.find(itb->second);
391 if (iti == fObjectMap.end())
392 fObjectMap.insert(std::pair<TString, Int_t>(itb->second, 0));
395 AnalyzeObjectMap(mainFairTask);
397 Int_t maxHierarchyNumber = 0;
398 for (iti = fObjectMap.begin(); iti != fObjectMap.end(); ++iti) {
399 if (maxHierarchyNumber < iti->second)
400 maxHierarchyNumber = iti->second;
403 LOG(debug) <<
"Max hierarchy number is " << maxHierarchyNumber;
405 fCanvas =
new TCanvas(
"MonitorCanvas",
"Fair Monitor", 10, 10, 960, 600);
408 fCanvas->SetFillStyle(4000);
409 fCanvas->Range(0, 0, 960, 800);
410 fCanvas->SetFillColor(0);
411 fCanvas->SetBorderSize(0);
412 fCanvas->SetBorderMode(0);
413 fCanvas->SetFrameFillColor(0);
415 for (Int_t ihier = 0; ihier < maxHierarchyNumber + 1; ++ihier) {
417 for (iti = fTaskMap.begin(); iti != fTaskMap.end(); ++iti) {
418 if (iti->second == ihier) {
422 LOG(debug) <<
"There are " << nofHier <<
" tasks on level " << ihier <<
".";
426 for (iti = fTaskMap.begin(); iti != fTaskMap.end(); ++iti) {
427 if (iti->second == ihier) {
428 std::pair<Double_t, Double_t> tempPos(50, 600 - iObj * 40);
429 fTaskPos.insert(std::pair<TString, std::pair<Double_t, Double_t>>(iti->first, tempPos));
436 Int_t secLineEven = 0;
439 if (nofHier % 2 == 0)
442 Int_t startingPosition = 575 - nofHier / (1 + secLine) * 45 - secLine * (1 - secLineEven) * 45;
446 - 800. * (2. *
static_cast<Double_t
>(ihier) - 0.5) / (
static_cast<Double_t
>(2 * maxHierarchyNumber + 1))
448 LOG(debug) <<
"for level " << ihier <<
" will put top edge at " << topEdge <<
". "
449 << (secLineEven ?
"Two lines" :
"One line") << (secLineEven ?
" with offset" :
"");
450 for (iti = fTaskMap.begin(); iti != fTaskMap.end(); ++iti) {
451 if (iti->second == ihier) {
452 std::pair<Double_t, Double_t> tempPos(startingPosition + iObj * 90 / (1 + secLine)
453 - secLineEven * (iObj % 2) * 45,
454 topEdge - 15 - secLine * (iObj % 2) * 35);
455 fTaskPos.insert(std::pair<TString, std::pair<Double_t, Double_t>>(iti->first, tempPos));
462 for (iti = fObjectMap.begin(); iti != fObjectMap.end(); ++iti) {
463 if (TMath::Abs(iti->second) == ihier) {
467 LOG(debug) <<
"There are " << nofHier <<
" objects on level " << ihier <<
".";
471 Int_t secLineEven = 0;
474 if (nofHier % 2 == 0)
477 Int_t startingPosition = 575 - nofHier / (1 + secLine) * 45 - secLine * (1 - secLineEven) * 45;
481 - 800. * (2. *
static_cast<Double_t
>(ihier) + 0.5) / (
static_cast<Double_t
>(2 * maxHierarchyNumber + 1))
483 LOG(debug) <<
"for level " << ihier <<
" will put top edge at " << topEdge <<
". "
484 << (secLineEven ?
"Two lines" :
"One line") << (secLineEven ?
" with offset" :
"");
485 for (iti = fObjectMap.begin(); iti != fObjectMap.end(); ++iti) {
486 if (TMath::Abs(iti->second) == ihier) {
487 std::pair<Double_t, Double_t> tempPos(startingPosition + iObj * 90 / (1 + secLine)
488 - secLineEven * (iObj % 2) * 45,
489 topEdge - 15 - secLine * (iObj % 2) * 35);
490 fObjectPos.insert(std::pair<TString, std::pair<Double_t, Double_t>>(iti->first, tempPos));
496 typedef std::map<TString, std::pair<Double_t, Double_t>>::iterator tddMapIter;
500 for (
auto itb = fTaskRequired.begin(); itb != fTaskRequired.end(); ++itb) {
501 itt = fTaskPos.find(itb->first);
502 ito = fObjectPos.find(itb->second);
503 if (itt != fTaskPos.end() && ito != fObjectPos.end()) {
504 std::pair<Double_t, Double_t> taskPos = itt->second;
505 std::pair<Double_t, Double_t> objectPos = ito->second;
507 new TArrow(objectPos.first, objectPos.second - 15, taskPos.first, taskPos.second + 15, 0.01,
"|>");
511 for (
auto itb = fTaskCreated.begin(); itb != fTaskCreated.end(); ++itb) {
512 itt = fTaskPos.find(itb->first);
513 ito = fObjectPos.find(itb->second);
514 if (itt != fTaskPos.end() && ito != fObjectPos.end()) {
515 std::pair<Double_t, Double_t> taskPos = itt->second;
516 std::pair<Double_t, Double_t> objectPos = ito->second;
518 new TArrow(taskPos.first, taskPos.second - 15, objectPos.first, objectPos.second + 15, 0.01,
"|>");
522 for (
auto itb = fTaskCreatedTemp.begin(); itb != fTaskCreatedTemp.end(); ++itb) {
523 itt = fTaskPos.find(itb->first);
524 ito = fObjectPos.find(itb->second);
525 if (itt != fTaskPos.end() && ito != fObjectPos.end()) {
526 std::pair<Double_t, Double_t> taskPos = itt->second;
527 std::pair<Double_t, Double_t> objectPos = ito->second;
529 new TArrow(taskPos.first, taskPos.second - 15, objectPos.first, objectPos.second + 15, 0.01,
"|>");
534 for (itt = fTaskPos.begin(); itt != fTaskPos.end(); ++itt) {
535 std::pair<Double_t, Double_t> taskPos = itt->second;
536 TBox* bkgBox =
new TBox(taskPos.first - 40, taskPos.second - 15, taskPos.first + 40, taskPos.second + 15);
537 bkgBox->SetFillColor(kGreen - 9);
540 TString tempString = Form(
"hist_%s_%s", itt->first.Data(),
"EXEC_TIM");
541 Int_t nofHists = fHistList->GetEntries();
542 for (Int_t ihist = 0; ihist < nofHists; ++ihist) {
543 if (!tempString.CompareTo(fHistList->At(ihist)->GetName())) {
544 Double_t timeInt = (
static_cast<TH1F*
>(fHistList->At(ihist))->Integral());
545 Double_t timeFrac = 80. * timeInt / fRunTime;
546 TBox* barBox =
new TBox(
547 taskPos.first - 40, taskPos.second - 15, taskPos.first - 40 + timeFrac, taskPos.second + 15);
548 barBox->SetFillColor(kRed);
553 tempString = itt->first;
554 tempString.Replace(0, tempString.First(
'_') + 1,
"");
555 if (tempString.Length() > 16)
556 tempString.Replace(16, tempString.Length(),
"");
557 TLatex* taskText =
new TLatex(taskPos.first, taskPos.second, tempString.Data());
558 taskText->SetTextAlign(22);
559 taskText->SetTextSize(0.015);
563 for (ito = fObjectPos.begin(); ito != fObjectPos.end(); ++ito) {
564 std::pair<Double_t, Double_t> objectPos = ito->second;
565 iti = fObjectMap.find(ito->first);
566 TPaveText* paveText =
new TPaveText(
567 objectPos.first - 40, objectPos.second - 15, objectPos.first + 40, objectPos.second + 15,
"nb");
568 paveText->SetFillColor(kMagenta - 9);
569 if (iti != fObjectMap.end())
571 paveText->SetFillColor(kGray);
572 paveText->SetShadowColor(0);
573 paveText->SetTextSize(0.015);
574 TString tempString = ito->first;
575 if (tempString.Length() > 16)
576 tempString.Replace(16, tempString.Length(),
"");
577 paveText->AddText(tempString);
585 LOG(warn) <<
"FairMonitor was disabled. Nothing to draw!";
589 Int_t nofHists = fHistList->GetEntries();
591 TString drawStr =
"P";
593 TLegend* tempLeg =
new TLegend(0.0, 0.5, 0.5, 0.9);
595 Double_t histMax = 0.;
596 for (Int_t ihist = 0; ihist < nofHists; ihist++) {
597 TString histString = Form(
"%s", fHistList->At(ihist)->GetName());
598 if (histString.Contains(specString)) {
599 TH1F* tempHist = (
static_cast<TH1F*
>((fHistList->At(ihist))));
600 if (histMax < tempHist->GetMaximum())
601 histMax = tempHist->GetMaximum();
605 for (Int_t ihist = 0; ihist < nofHists; ihist++) {
606 TString histString = Form(
"%s", fHistList->At(ihist)->GetName());
607 if (histString.Contains(specString)) {
608 TH1F* tempHist = (
static_cast<TH1F*
>((fHistList->At(ihist))));
609 if (tempHist->GetXaxis()->GetXmax() > tempHist->GetEntries())
610 tempHist->SetBins(tempHist->GetEntries(), 0, tempHist->GetEntries());
611 tempHist->SetMarkerColor(nofDraws % 6 + 2);
612 tempHist->SetMarkerStyle(nofDraws % 4 + 20);
613 tempHist->SetAxisRange(0., histMax * 1.1,
"Y");
614 tempHist->Draw(drawStr);
615 TString tempName = tempHist->GetName();
616 tempName.Remove(0, tempName.First(
'_') + 1);
617 tempName.Remove(0, tempName.First(
'_') + 1);
618 tempLeg->AddEntry(tempHist, tempName,
"p");
632 Bool_t wasBatch = gROOT->IsBatch();
633 if (!fDrawCanvas && !wasBatch)
634 gROOT->SetBatch(kTRUE);
636 if (!fDrawCanvas && !wasBatch)
637 gROOT->SetBatch(kFALSE);
639 TFile* histoFile = sinkFile;
640 if (fOutputFileName.Length() > 1 && fOutputFileName != sinkFile->GetName()) {
641 histoFile = TFile::Open(fOutputFileName,
"recreate");
644 histoFile->mkdir(
"MonitorResults");
645 histoFile->cd(
"MonitorResults");
646 TIter next(fHistList);
647 while (TH1* thist = (static_cast<TH1*>(next()))) {
648 thist->SetBins(thist->GetEntries(), 0, thist->GetEntries());
655 if (histoFile != sinkFile) {
662 void FairMonitor::GetTaskMap(TTask* tempTask)
664 TString tempString = Form(
"%p_%s", tempTask, tempTask->GetName());
665 fTaskMap.insert(std::pair<TString, Int_t>(tempString, 0));
667 TList* subTaskList = tempTask->GetListOfTasks();
670 for (Int_t itask = 0; itask < subTaskList->GetEntries(); itask++) {
671 TTask* subTask =
static_cast<TTask*
>(subTaskList->At(itask));
684 void FairMonitor::AnalyzeObjectMap(TTask* tempTask)
686 TString tempString = Form(
"%p_%s", tempTask, tempTask->GetName());
688 Int_t hierarchyNumber = 0;
690 typedef std::map<TString, Int_t>::iterator tiMapIter;
693 LOG(debug) <<
"TASK \"" << tempTask->GetName() <<
"\" NEEDS:";
694 for (
auto itb = fTaskRequired.begin(); itb != fTaskRequired.end(); ++itb) {
695 if (itb->first != tempString)
697 LOG(debug) <<
" \"" << itb->second.Data() <<
"\"";
698 iti = fObjectMap.find(itb->second);
699 if (iti == fObjectMap.end())
701 if (hierarchyNumber <= TMath::Abs(iti->second))
702 hierarchyNumber = TMath::Abs(iti->second) + 1;
707 LOG(debug) <<
"WILL GET hierarchyNumber = " << hierarchyNumber;
709 iti = fTaskMap.find(tempString);
710 if (iti != fTaskMap.end())
711 iti->second = hierarchyNumber;
713 LOG(debug) <<
" \"" << tempTask->GetName() <<
"\" CREATES:";
714 for (
auto itb = fTaskCreated.begin(); itb != fTaskCreated.end(); ++itb) {
715 if (itb->first != tempString)
717 LOG(debug) <<
" + \"" << itb->second.Data() <<
"\"";
718 iti = fObjectMap.find(itb->second);
719 if (iti == fObjectMap.end())
721 iti->second = hierarchyNumber;
724 for (
auto itb = fTaskCreatedTemp.begin(); itb != fTaskCreatedTemp.end(); ++itb) {
725 if (itb->first != tempString)
727 LOG(debug) <<
" - \"" << itb->second.Data() <<
"\"";
728 iti = fObjectMap.find(itb->second);
729 if (iti == fObjectMap.end())
731 iti->second = -hierarchyNumber;
734 TList* subTaskList = tempTask->GetListOfTasks();
737 for (Int_t itask = 0; itask < subTaskList->GetEntries(); itask++) {
738 TTask* subTask =
static_cast<TTask*
>(subTaskList->At(itask));
740 AnalyzeObjectMap(subTask);
void RecordInfo(const TTask *tTask, const char *identStr, Double_t value)
virtual void Print(Option_t *option="") const
void DrawHist(TString specString)
void StartMemoryMonitor(const TTask *tTask, const char *identStr)
void StopTimer(const TTask *tTask, const char *identStr)
static FairMonitor * GetMonitor()
ClassImp(FairEventBuilder)
void RecordGetting(const char *name)
void StopMemoryMonitor(const TTask *tTask, const char *identStr)
void RecordRegister(const char *name, const char *folderName, Bool_t toFile)
void StartTimer(const TTask *tTask, const char *identStr)
virtual void Draw(Option_t *option="")
size_t GetCurrentMemory()
void StoreHistograms(TFile *sinkFile)
void PrintTask(TString specString) const