Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-04-04 08:16:09

0001 #include "GL1MonDraw.h"
0002 
0003 #include <onlmon/OnlMonClient.h>
0004 #include <onlmon/RunDBodbc.h>
0005 
0006 #include <TAxis.h>  // for TAxis
0007 #include <TCanvas.h>
0008 #include <TFrame.h>
0009 #include <TGraph.h>
0010 #include <TH1.h>
0011 #include <TH2.h>
0012 #include <TLegend.h>
0013 #include <TLine.h>
0014 #include <TPad.h>
0015 #include <TROOT.h>
0016 #include <TStyle.h>
0017 #include <TSystem.h>
0018 #include <TText.h>
0019 
0020 #include <cstring>  // for memset
0021 #include <ctime>
0022 #include <fstream>
0023 #include <iostream>  // for operator<<, basic_ostream, basic_os...
0024 #include <sstream>
0025 #include <vector>  // for vector
0026 
0027 GL1MonDraw::GL1MonDraw(const std::string &name)
0028   : OnlMonDraw(name)
0029 {
0030   return;
0031 }
0032 
0033 GL1MonDraw::~GL1MonDraw()
0034 {
0035   delete gl1Style;
0036 }
0037 
0038 int GL1MonDraw::Init()
0039 {
0040   TStyle *oldStyle = gStyle;
0041   gl1Style = new TStyle("gl1Style", "gl1Style");
0042   gl1Style->SetFrameBorderMode(0);
0043   gl1Style->SetCanvasColor(0);
0044   gl1Style->SetPadBorderMode(0);
0045   gl1Style->SetPadBottomMargin(0.15);
0046   gl1Style->SetCanvasBorderMode(0);
0047   oldStyle->cd();
0048   m_RunDB = new RunDBodbc();
0049   reject_graph_good.resize(8, nullptr);
0050   reject_graph_bad.resize(8, nullptr);
0051   rejection_limit.resize(8);
0052 
0053 // from /home/repo/Debian/bin/ll1TriggerControl.py
0054 // photon_triggers_rejection_ranges = [[19, 27], [50, 70]]
0055 // self.rej_ranges = [[560,840],[3760,5640],[21440,40160],[70000,130000],[65,85],    [240,360],[1120,1680],[4000,6000]]
0056 
0057   // rejection_limit[0] = std::make_pair(19,27);
0058   // rejection_limit[1] = std::make_pair(50,70);
0059   // rejection_limit[2] = std::make_pair(50,70);
0060   // rejection_limit[3] = std::make_pair(50,70);
0061   // rejection_limit[4] = std::make_pair(50,70);
0062   // rejection_limit[5] = std::make_pair(50,70);
0063   // rejection_limit[6] = std::make_pair(50,70);
0064   // rejection_limit[7] = std::make_pair(50,70);
0065   rejection_limit[0] = std::make_pair(560,840);
0066   rejection_limit[1] = std::make_pair(3760,5640);
0067   rejection_limit[2] = std::make_pair(21440,40160);
0068   rejection_limit[3] = std::make_pair(70000,130000);
0069   rejection_limit[4] = std::make_pair(65,85);
0070   rejection_limit[5] = std::make_pair(240,360);
0071   rejection_limit[6] = std::make_pair(1120,1680);
0072   rejection_limit[7] = std::make_pair(4000,6000);
0073   
0074   return 0;
0075 }
0076 
0077 int GL1MonDraw::MakeCanvas(const std::string &name)
0078 {
0079   OnlMonClient *cl = OnlMonClient::instance();
0080   TStyle *oldStyle = gStyle;
0081 
0082   gl1Style->cd();
0083   int xsize = cl->GetDisplaySizeX();
0084   int ysize = cl->GetDisplaySizeY();
0085   if (name == "GL1MonScaled")
0086   {
0087     // xpos (-1) negative: do not draw menu bar
0088     TC[0] = new TCanvas(name.c_str(), "GL1 Scaled Triggers", -1, 0, xsize, ysize);
0089     // root is pathetic, whenever a new TCanvas is created root piles up
0090     // 6kb worth of X11 events which need to be cleared with
0091     // gSystem->ProcessEvents(), otherwise your process will grow and
0092     // grow and grow but will not show a definitely lost memory leak
0093     gSystem->ProcessEvents();
0094     for (int i = 0; i < 4; i++)
0095     {
0096       double xlow = 0.75 - (0.25 * i);
0097       double xhigh = xlow + 0.25;
0098       for (int j = 0; j < 7; j++)
0099       {
0100         double ylow = 0.0 + (0.13 * j);
0101         double yhigh = ylow + 0.13;
0102         int padindex = 27 - (i + 4 * j);  // make it start from the top of the plot
0103         // std::cout << "idx: " << padindex << " pad: xl: " << xlow << ", xh: " << xhigh
0104         //  << " pad: yl: " << ylow << ", yh: " << yhigh
0105         //        << std::endl;
0106         std::string padname = "gl1pad_" + std::to_string(padindex);
0107         ScalePad[padindex] = new TPad(padname.c_str(), "who needs this?", xlow, ylow, xhigh, yhigh, 0);
0108         ScalePad[padindex]->Draw();
0109       }
0110     }
0111     // this one is used to plot the run number on the canvas
0112     transparent[0] = new TPad("transparent0", "this does not show", 0, 0, 1, 1);
0113     transparent[0]->SetFillStyle(4000);
0114     transparent[0]->Draw();
0115     TC[0]->SetEditable(false);
0116   }
0117   if (name == "GL1MonLive")
0118   {
0119     // xpos (-1) negative: do not draw menu bar
0120     TC[1] = new TCanvas(name.c_str(), "GL1 Live Triggers", -1, 0, xsize, ysize);
0121     // root is pathetic, whenever a new TCanvas is created root piles up
0122     // 6kb worth of X11 events which need to be cleared with
0123     // gSystem->ProcessEvents(), otherwise your process will grow and
0124     // grow and grow but will not show a definitely lost memory leak
0125     gSystem->ProcessEvents();
0126     for (int i = 0; i < 4; i++)
0127     {
0128       double xlow = 0.75 - (0.25 * i);
0129       double xhigh = xlow + 0.25;
0130       for (int j = 0; j < 7; j++)
0131       {
0132         double ylow = 0.0 + (0.13 * j);
0133         double yhigh = ylow + 0.13;
0134         int padindex = 27 - (i + 4 * j);  // make it start from the top of the plot
0135         // std::cout << "idx: " << padindex << "pad: xl: " << xlow << ", xh: " << xhigh
0136         // << "pad: yl: " << ylow << ", yh: " << yhigh
0137         //        << std::endl;
0138         std::string padname = "gl1pad_" + std::to_string(padindex);
0139         LivePad[padindex] = new TPad(padname.c_str(), "who needs this?", xlow, ylow, xhigh, yhigh, 0);
0140         LivePad[padindex]->Draw();
0141       }
0142     }
0143     // this one is used to plot the run number on the canvas
0144     transparent[1] = new TPad("transparent1", "this does not show", 0, 0, 1, 1);
0145     transparent[1]->SetFillStyle(4000);
0146     transparent[1]->Draw();
0147     TC[1]->SetEditable(false);
0148   }
0149   else if (name == "GL1ServerStats")
0150   {
0151     int canvasindex = 2;
0152     TC[canvasindex] = new TCanvas(name.c_str(), "GL1Mon Server Stats", -1, 0, xsize, ysize);
0153     gSystem->ProcessEvents();
0154     // this one is used to plot the run number on the canvas
0155     transparent[canvasindex] = new TPad("transparent2", "this does not show", 0, 0, 1, 1);
0156     transparent[canvasindex]->Draw();
0157     transparent[canvasindex]->SetFillColor(kGray);
0158     TC[canvasindex]->SetEditable(false);
0159   }
0160   if (name == "GL1MonRejection")
0161   {
0162     int canvasindex = 3;
0163     // xpos (-1) negative: do not draw menu bar
0164     TC[canvasindex] = new TCanvas(name.c_str(), "GL1 Rejection", -1, 0, xsize, ysize);
0165     // root is pathetic, whenever a new TCanvas is created root piles up
0166     // 6kb worth of X11 events which need to be cleared with
0167     // gSystem->ProcessEvents(), otherwise your process will grow and
0168     // grow and grow but will not show a definitely lost memory leak
0169     gSystem->ProcessEvents();
0170     for (int i = 0; i < 2; i++)
0171     {
0172       double xlow = 0.5 - (0.5 *i);
0173       double xhigh = xlow + 0.5;
0174       for (int j = 0; j < 4; j++)
0175       {
0176     double ylow = 0.0 + (0.23 * j);
0177     double yhigh = ylow + 0.23;
0178     int padindex = 7 -  (i + 2 * j);  // make it start from the top of the plot
0179     // std::cout << "idx: " << padindex << "pad: xl: " << xlow << ", xh: " << xhigh
0180     //    << "pad: yl: " << ylow << ", yh: " << yhigh
0181     //    << std::endl;
0182     std::string padname = "gl1pad_" + std::to_string(padindex);
0183     RejPad[padindex] = new TPad(padname.c_str(), "who needs this?", xlow, ylow, xhigh, yhigh, 0);
0184     RejPad[padindex]->Draw();
0185       }
0186     }
0187     // this one is used to plot the run number on the canvas
0188     transparent[canvasindex] = new TPad("transparent3", "this does not show", 0, 0, 1, 1);
0189     transparent[canvasindex]->SetFillStyle(4000);
0190     transparent[canvasindex]->Draw();
0191     TC[canvasindex]->SetEditable(false);
0192   }
0193   if (name == "GL1MonTimeToLastEvent")
0194   {
0195     int canvasindex = 4;
0196     // xpos (-1) negative: do not draw menu bar
0197     TC[canvasindex] = new TCanvas(name.c_str(), "Time To Last Event", -1, 0, xsize, ysize);
0198     // root is pathetic, whenever a new TCanvas is created root piles up
0199     // 6kb worth of X11 events which need to be cleared with
0200     // gSystem->ProcessEvents(), otherwise your process will grow and
0201     // grow and grow but will not show a definitely lost memory leak
0202     gSystem->ProcessEvents();
0203     for (int i = 0; i < 2; i++)
0204     {
0205       double xlow = 0;
0206       double xhigh = 1.;
0207       double ylow = 0 + (0.45 *i);
0208       double yhigh = ylow + 0.45;
0209       std::string padname = "gl1pad_ttl" + std::to_string(i);
0210       ttlPad[i] = new TPad(padname.c_str(), "who needs this?", xlow, ylow, xhigh, yhigh, 0);
0211       ttlPad[i]->Draw();
0212     }
0213     // this one is used to plot the run number on the canvas
0214     transparent[canvasindex] = new TPad("transparent4", "this does not show", 0, 0, 1, 1);
0215     transparent[canvasindex]->SetFillStyle(4000);
0216     transparent[canvasindex]->Draw();
0217     TC[canvasindex]->SetEditable(false);
0218   }
0219   oldStyle->cd();
0220   return 0;
0221 }
0222 
0223 int GL1MonDraw::Draw(const std::string &what)
0224 {
0225   int iret = 0;
0226   int idraw = 0;
0227   OnlMonClient *cl = OnlMonClient::instance();
0228   if (m_CurrentRunnumber != cl->RunNumber())
0229   {
0230     m_CurrentRunnumber = cl->RunNumber();
0231     FetchTriggerNames();
0232   }
0233   if (what == "ALL" || what == "SCALED")
0234   {
0235     iret += DrawScaled(what);
0236     idraw++;
0237   }
0238   if (what == "ALL" || what == "LIVE")
0239   {
0240     iret += DrawLive(what);
0241     idraw++;
0242   }
0243   if (what == "ALL" || what == "REJECTION")
0244   {
0245     iret += DrawRejection();
0246     idraw++;
0247   }
0248   if (what == "ALL" || what == "TIMETOLASTEVENT")
0249   {
0250     iret += DrawTimeToLastEvent();
0251     idraw++;
0252   }
0253   if (what == "ALL" || what == "SERVERSTATS")
0254   {
0255     iret += DrawServerStats();
0256     idraw++;
0257   }
0258   if (!idraw)
0259   {
0260     std::cout << __PRETTY_FUNCTION__ << " Unimplemented Drawing option: " << what << std::endl;
0261     iret = -1;
0262   }
0263   return iret;
0264 }
0265 
0266 int GL1MonDraw::DrawScaled(const std::string & /* what */)
0267 {
0268   OnlMonClient *cl = OnlMonClient::instance();
0269   if (!gROOT->FindObject("GL1MonScaled"))
0270   {
0271     MakeCanvas("GL1MonScaled");
0272   }
0273   TC[0]->SetEditable(true);
0274   TC[0]->Clear("D");
0275   TText title;
0276   title.SetNDC();
0277   title.SetTextAlign(23);
0278   title.SetTextColor(4);
0279   title.SetTextSize(0.1);
0280   TText agap;
0281   agap.SetTextAlign(21);
0282   agap.SetTextSize(0.055);
0283   TLine *line = new TLine();
0284 
0285   int ipad = 0;
0286   for (int i = 0; i < 64; i++)
0287   {
0288     
0289     std::string hname = "gl1_scaledtrigger_" + std::to_string(i);
0290     TH1 *hist1 = cl->getHisto("GL1MON_0", hname);
0291     if (!hist1)
0292     {
0293       DrawDeadServer(transparent[0]);
0294       TC[0]->SetEditable(false);
0295       return -1;
0296     }
0297     if (hist1->GetMaximum() > 0)
0298     {
0299       // std::cout << "ipad: " << ipad << " trigger no: " << i << " trigger: "
0300       //          << m_TrignameArray[i] << std::endl;
0301       if (ipad > 27)
0302       {
0303     std::cout << "ipad: " << ipad << " trigger: "
0304           << m_TrignameArray[i] << std::endl;
0305     ipad++;
0306     continue;
0307       }
0308       TH1 *abortgap = (TH1 *) hist1->Clone();
0309       TH1 *forbidden = (TH1 *) hist1->Clone();
0310       abortgap->SetFillColor(6);
0311       forbidden->SetFillColor(2);
0312       for (int j = 0; j < 112; j++)
0313       {
0314         abortgap->SetBinContent(j, 0);
0315         forbidden->SetBinContent(j, 0);
0316       }
0317       for (int j = 112; j < 121; j++)
0318       {
0319         forbidden->SetBinContent(j, 0);
0320       }
0321       for (int j = 121; j < 130; j++)
0322       {
0323         abortgap->SetBinContent(j, 0);
0324       }
0325       ScalePad[ipad]->cd();
0326       ScalePad[ipad]->SetLogy();
0327       hist1->SetStats(0);
0328       std::string htitle = m_TrignameArray[i];
0329       //      std::cout << "index " << i << " title: " << htitle << std::endl;
0330       hist1->SetFillColor(3);
0331       hist1->SetXTitle("Bunch Crossing");
0332       hist1->SetYTitle("Events");
0333       hist1->GetXaxis()->SetLabelSize(0.06);
0334       hist1->GetXaxis()->SetTitleSize(0.055);
0335       hist1->GetXaxis()->SetTitleOffset(1.1);
0336 
0337       hist1->GetYaxis()->SetLabelSize(0.06);
0338       hist1->GetYaxis()->SetTitleSize(0.06);
0339       hist1->GetYaxis()->SetTitleOffset(0.4);
0340       hist1->SetTitle("");
0341       hist1->DrawCopy();
0342       if (htitle.find("Clock") == std::string::npos)
0343       {
0344         abortgap->DrawCopy("same");
0345       }
0346       forbidden->DrawCopy("same");
0347       title.SetTextColor(4);
0348       title.SetTextSize(0.1);
0349       title.DrawText(0.5, 0.99, htitle.c_str());
0350       delete abortgap;
0351       delete forbidden;
0352       line->SetLineColor(6);
0353       line->SetLineWidth(2);
0354       line->SetLineStyle(2);  // dashed
0355       ScalePad[ipad]->Update();
0356       // whoopee - this is how to get the top of the pad in a log y scale
0357       // only after the TPad::Update() where the Pad figures out its dimensions
0358       line->DrawLine(119.5, std::pow(10, ScalePad[ipad]->GetFrame()->GetY1()), 119.5, std::pow(10, ScalePad[ipad]->GetFrame()->GetY2()));
0359       if (htitle.find("Clock") == std::string::npos)
0360       {
0361         line->DrawLine(110.5, std::pow(10, ScalePad[ipad]->GetFrame()->GetY1()), 110.5, std::pow(10, ScalePad[ipad]->GetFrame()->GetY2()));
0362         agap.DrawText(115, std::pow(10, ScalePad[ipad]->GetFrame()->GetY2()), "Abort Gap");
0363       }
0364       agap.DrawText(125, std::pow(10, ScalePad[ipad]->GetFrame()->GetY2()), "Forbidden");
0365       ipad++;
0366     }
0367   }
0368   delete line;
0369   // else
0370   TText PrintRun;
0371   PrintRun.SetTextFont(62);
0372   PrintRun.SetTextSize(0.04);
0373   PrintRun.SetNDC();          // set to normalized coordinates
0374   PrintRun.SetTextAlign(23);  // center/top alignment
0375   std::ostringstream runnostream;
0376   std::string runstring;
0377   std::pair<time_t, int> evttime = cl->EventTime("CURRENT");
0378   // fill run number and event time into string
0379   runnostream << "GL1 Scaled Trigger Run:" << cl->RunNumber()
0380               << ", Time: " << ctime(&evttime.first);
0381   runstring = runnostream.str();
0382   transparent[0]->cd();
0383   PrintRun.SetTextColor(evttime.second);
0384   PrintRun.DrawText(0.5, 1., runstring.c_str());
0385   TC[0]->Update();
0386   TC[0]->Show();
0387   TC[0]->SetEditable(false);
0388   return 0;
0389 }
0390 
0391 int GL1MonDraw::DrawLive(const std::string & /* what */)
0392 {
0393   OnlMonClient *cl = OnlMonClient::instance();
0394   if (!gROOT->FindObject("GL1MonLive"))
0395   {
0396     MakeCanvas("GL1MonLive");
0397   }
0398   TC[1]->SetEditable(true);
0399   TC[1]->Clear("D");
0400   TText title;
0401   title.SetNDC();
0402   title.SetTextAlign(23);
0403   title.SetTextColor(4);
0404   title.SetTextSize(0.1);
0405   TText agap;
0406   agap.SetTextAlign(21);
0407   agap.SetTextSize(0.055);
0408 
0409   TLine *line = new TLine();
0410   int ipad = 0;
0411   int icnt = 0;
0412   for (int i = 0; i < 64; i++)
0413   {
0414     std::string hname = "gl1_livetrigger_" + std::to_string(i);
0415     TH1 *hist1 = cl->getHisto("GL1MON_0", hname);
0416     if (!hist1)
0417     {
0418       DrawDeadServer(transparent[1]);
0419       TC[1]->SetEditable(false);
0420       return -1;
0421     }
0422     if (i != 0
0423     && i != 1
0424     && i != 12
0425     && i != 14
0426     && i != 16
0427     && i != 17
0428     && i != 18
0429     && i != 19
0430     && i != 20
0431     && i != 21
0432     && i != 22
0433     && i != 23
0434     && i != 24
0435     && i != 25
0436     && i != 26
0437     && i != 27
0438     && i != 28
0439     && i != 29
0440     && i != 30
0441     && i != 31
0442     && i != 32
0443     && i != 33
0444     && i != 34
0445     && i != 35
0446     && i != 36
0447     && i != 37
0448     && i != 38)
0449     {
0450       continue;
0451     }
0452     if (hist1->GetMaximum() > 0 && ipad < 28)
0453     {
0454       // std::cout << "ipad: " << ipad << " trigger no: " << i << " trigger: "
0455       //          << m_TrignameArray[i] << std::endl;
0456       icnt++;
0457       TH1 *abortgap = (TH1 *) hist1->Clone();
0458       TH1 *forbidden = (TH1 *) hist1->Clone();
0459       abortgap->SetFillColor(6);
0460       forbidden->SetFillColor(2);
0461       for (int j = 0; j < 112; j++)
0462       {
0463         abortgap->SetBinContent(j, 0);
0464         forbidden->SetBinContent(j, 0);
0465       }
0466       for (int j = 112; j < 121; j++)
0467       {
0468         forbidden->SetBinContent(j, 0);
0469       }
0470       for (int j = 121; j < 130; j++)
0471       {
0472         abortgap->SetBinContent(j, 0);
0473       }
0474       LivePad[ipad]->cd();
0475       LivePad[ipad]->SetLogy();
0476       hist1->SetStats(0);
0477       std::string htitle = m_TrignameArray[i];
0478       //      std::cout << "index " << i << " title: " << htitle << std::endl;
0479       hist1->SetFillColor(3);
0480       hist1->SetXTitle("Bunch Crossing");
0481       hist1->SetYTitle("Events");
0482       hist1->GetXaxis()->SetLabelSize(0.06);
0483       hist1->GetXaxis()->SetTitleSize(0.055);
0484       hist1->GetXaxis()->SetTitleOffset(1.1);
0485 
0486       hist1->GetYaxis()->SetLabelSize(0.06);
0487       hist1->GetYaxis()->SetTitleSize(0.06);
0488       hist1->GetYaxis()->SetTitleOffset(0.4);
0489       hist1->SetTitle("");
0490       hist1->DrawCopy();
0491       if (htitle.find("Clock") == std::string::npos)
0492       {
0493         abortgap->DrawCopy("same");
0494       }
0495       forbidden->DrawCopy("same");
0496       title.SetTextColor(4);
0497       title.SetTextSize(0.1);
0498       title.DrawText(0.5, 0.99, htitle.c_str());
0499       delete abortgap;
0500       delete forbidden;
0501       line->SetLineColor(6);
0502       line->SetLineWidth(2);
0503       line->SetLineStyle(2);  // dashed
0504       LivePad[ipad]->Update();
0505       // whoopee - this is how to get the top of the pad in a log y scale
0506       // only after the TPad::Update() where the Pad figures out its dimensions
0507       line->DrawLine(119.5, std::pow(10, LivePad[ipad]->GetFrame()->GetY1()), 119.5, std::pow(10, LivePad[ipad]->GetFrame()->GetY2()));
0508       if (htitle.find("Clock") == std::string::npos)
0509       {
0510         line->DrawLine(110.5, std::pow(10, LivePad[ipad]->GetFrame()->GetY1()), 110.5, std::pow(10, LivePad[ipad]->GetFrame()->GetY2()));
0511         agap.DrawText(115, std::pow(10, LivePad[ipad]->GetFrame()->GetY2()), "Abort Gap");
0512       }
0513       agap.DrawText(125, std::pow(10, LivePad[ipad]->GetFrame()->GetY2()), "Forbidden");
0514       ipad++;
0515     }
0516   }
0517   delete line;
0518   TText PrintRun;
0519   PrintRun.SetTextFont(62);
0520   PrintRun.SetTextSize(0.04);
0521   PrintRun.SetNDC();          // set to normalized coordinates
0522   PrintRun.SetTextAlign(23);  // center/top alignment
0523   std::ostringstream runnostream;
0524   std::string runstring;
0525   std::pair<time_t, int> evttime = cl->EventTime("CURRENT");
0526   // fill run number and event time into string
0527   runnostream << "GL1 Live Trigger Run:" << cl->RunNumber()
0528               << ", Time: " << ctime(&evttime.first);
0529   runstring = runnostream.str();
0530   transparent[1]->cd();
0531   PrintRun.SetTextColor(evttime.second);
0532   PrintRun.DrawText(0.5, 1., runstring.c_str());
0533   TC[1]->Update();
0534   TC[1]->Show();
0535   TC[1]->SetEditable(false);
0536   return 0;
0537 }
0538 
0539 int GL1MonDraw::DrawRejection()
0540 {
0541   OnlMonClient *cl = OnlMonClient::instance();
0542   if (!gROOT->FindObject("GL1MonRejection"))
0543   {
0544     MakeCanvas("GL1MonRejection");
0545   }
0546   TC[3]->SetEditable(true);
0547   TC[3]->Clear("D");
0548   TText title;
0549   title.SetNDC();
0550   title.SetTextAlign(23);
0551   title.SetTextColor(4);
0552   title.SetTextSize(0.1);
0553   TLine *tl = new TLine();
0554   tl->SetLineWidth(4);
0555   tl->SetLineColor(7);
0556   tl->SetLineStyle(2);
0557   std::vector<int> remap_draw_idx = {0,2,4,6,1,3,5,7};
0558   for (int i = 0; i < 8; i++)
0559   {
0560     std::string hname = "gl1_reject_" + std::to_string(i);
0561     TH1 *hist1 = cl->getHisto("GL1MON_0", hname);
0562     int trigno = std::stoi(hist1->GetTitle());
0563     if (!hist1)
0564     {
0565       DrawDeadServer(transparent[3]);
0566       TC[3]->SetEditable(false);
0567       return -1;
0568     }
0569     int ipad = remap_draw_idx[i];
0570     int nEntries = hist1->GetEntries();
0571     if (nEntries > 0)
0572     {
0573       RejPad[ipad]->cd();
0574       RejPad[ipad]->SetGridy();
0575       float *x_good = new float[nEntries];
0576       float *y_good = new float[nEntries];
0577       float *x_bad = new float[nEntries];
0578       float *y_bad = new float[nEntries];
0579       int igood_bin = 0;
0580       int ibad_bin = 0;
0581       float xmax {0.};
0582       float ymax {0.};
0583       float ymin {1000000.};
0584       for (int ibin = 1; ibin <= nEntries; ibin++)
0585       {
0586         float y = hist1->GetBinContent(ibin);
0587         if (y >= rejection_limit[i].first && y <= rejection_limit[i].second)
0588         {
0589           x_good[igood_bin] = hist1->GetBinError(ibin);
0590           y_good[igood_bin] = y;
0591           xmax = std::max(xmax,x_good[igood_bin]);
0592           ymax = std::max(ymax,y_good[igood_bin]);
0593           ymin = std::min(ymin,y_good[igood_bin]);
0594           igood_bin++;
0595         }
0596         else
0597         {
0598           x_bad[ibad_bin] = hist1->GetBinError(ibin);
0599           y_bad[ibad_bin] = y;
0600           xmax = std::max(xmax,x_bad[ibad_bin]);
0601           ymax = std::max(ymax,y_bad[ibad_bin]);
0602           ymin = std::min(ymin,y_bad[ibad_bin]);
0603           ibad_bin++;
0604     }
0605       }
0606       delete reject_graph_good[i];
0607       delete reject_graph_bad[i];
0608       reject_graph_good[i] = nullptr;
0609       reject_graph_bad[i] = nullptr;
0610       if (igood_bin > 0)
0611       {
0612     reject_graph_good[i] = new TGraph(igood_bin, x_good, y_good);
0613       }
0614       if (ibad_bin > 0)
0615       {
0616     reject_graph_bad[i] = new TGraph(ibad_bin, x_bad, y_bad);
0617       }
0618       TH2 *h2 = new TH2F("h2", Form("%s (%d)" , m_TrignameArray[trigno].c_str(), trigno ) , 1, 0, xmax + 50, 1, 0, ymax+ymax/5.);
0619       h2->SetStats(0);
0620       h2->SetXTitle("time in Run");
0621       h2->SetYTitle("Rejection over MB");
0622       h2->GetXaxis()->SetLabelSize(0.06);
0623       h2->GetXaxis()->SetTitleSize(0.055);
0624       h2->GetXaxis()->SetTitleOffset(1.1);
0625 
0626       h2->GetYaxis()->SetLabelSize(0.06);
0627       h2->GetYaxis()->SetTitleSize(0.06);
0628       h2->GetYaxis()->SetTitleOffset(0.45);
0629       h2->SetTitle("");
0630       h2->DrawCopy();
0631       if (reject_graph_good[i])
0632       {
0633         reject_graph_good[i]->SetMarkerStyle(20);
0634         reject_graph_good[i]->SetMarkerSize(2.);
0635         reject_graph_good[i]->SetMarkerColor(3);
0636 
0637         reject_graph_good[i]->Draw("p same");
0638       }
0639       if (reject_graph_bad[i])
0640       {
0641         reject_graph_bad[i]->SetMarkerStyle(20);
0642         reject_graph_bad[i]->SetMarkerSize(2.);
0643         reject_graph_bad[i]->SetMarkerColor(2);
0644         reject_graph_bad[i]->SetMarkerColor(3);
0645 
0646         reject_graph_bad[i]->Draw("p same");
0647       }
0648       // tl->DrawLine(0,rejection_limit[i].first, xmax + 50,rejection_limit[i].first);
0649       // tl->DrawLine(0,rejection_limit[i].second, xmax + 50,rejection_limit[i].second);
0650       tl->DrawLine(0,ymin-ymin/10., xmax + 50,ymin-ymin/10.);
0651       tl->DrawLine(0,ymax+ymax/10., xmax + 50,ymax+ymax/10.);
0652       delete[] x_good;
0653       delete[] y_good;
0654       delete[] x_bad;
0655       delete[] y_bad;
0656       delete h2;
0657       title.SetTextColor(4);
0658       title.SetTextSize(0.1);
0659       title.DrawText(0.5, 0.99, Form("%s", m_TrignameArray[trigno].c_str()));
0660     }
0661   }
0662   delete tl;
0663   TText PrintRun;
0664   PrintRun.SetTextFont(62);
0665   PrintRun.SetTextSize(0.04);
0666   PrintRun.SetNDC();          // set to normalized coordinates
0667   PrintRun.SetTextAlign(23);  // center/top alignment
0668   std::ostringstream runnostream;
0669   std::string runstring;
0670   std::pair<time_t, int> evttime = cl->EventTime("CURRENT");
0671   // fill run number and event time into string
0672   runnostream << "GL1 Trigger Rejection Run:" << cl->RunNumber()
0673               << ", Time: " << ctime(&evttime.first);
0674   runstring = runnostream.str();
0675   transparent[3]->cd();
0676   PrintRun.SetTextColor(evttime.second);
0677   PrintRun.DrawText(0.5, 1., runstring.c_str());
0678   TC[3]->Update();
0679   TC[3]->Show();
0680   TC[3]->SetEditable(false);
0681   return 0;
0682 }
0683 
0684 int GL1MonDraw::DrawTimeToLastEvent()
0685 {
0686   OnlMonClient *cl = OnlMonClient::instance();
0687   if (!gROOT->FindObject("GL1MonTimeToLastEvent"))
0688   {
0689     MakeCanvas("GL1MonTimeToLastEvent");
0690   }
0691   TC[4]->SetEditable(true);
0692   TC[4]->Clear("D");
0693   TText title;
0694   title.SetNDC();
0695   title.SetTextAlign(23);
0696   title.SetTextColor(4);
0697   title.SetTextSize(0.1);
0698   TH1 *hist1 = cl->getHisto("GL1MON_0","gl1_timetolastevent0");
0699   ttlPad[1]->cd();
0700   hist1->SetStats(0);
0701   hist1->SetTitle("");
0702   hist1->SetXTitle("Ticks");
0703   hist1->SetYTitle("Events");
0704   hist1->GetXaxis()->SetLabelSize(0.06);
0705   hist1->GetXaxis()->SetTitleSize(0.055);
0706   hist1->GetXaxis()->SetTitleOffset(1.1);
0707 
0708   hist1->GetYaxis()->SetLabelSize(0.06);
0709   hist1->GetYaxis()->SetTitleSize(0.06);
0710   hist1->GetYaxis()->SetTitleOffset(0.5);
0711   hist1->DrawCopy();
0712   title.SetTextColor(4);
0713   title.SetTextSize(0.1);
0714   title.DrawText(0.5, 0.99, "Ticks to previous Event");
0715 
0716   ttlPad[0]->cd();
0717   int colors[5] = {7,1,2,3,4};
0718   std::string legentry[5] = {"none","prev evt","prev-1 evt","prev-2 evt", "prev-3 evt"};
0719   double ymax = 0.;
0720   for (int i = 4; i > 0; i--)
0721   {
0722     std::string hname = "gl1_timetolastevent" + std::to_string(i);
0723     hist1 = cl->getHisto("GL1MON_0", hname);
0724     ymax = std::max(ymax,hist1->GetMaximum());
0725   }
0726   ymax = ymax + ymax/10.; // add 10%
0727   TLegend* leg = new TLegend(0.68,0.68,0.88,0.88);
0728   for (int i = 1; i < 5; i++)
0729   {
0730     std::string hname = "gl1_timetolastevent" + std::to_string(i);
0731     hist1 = cl->getHisto("GL1MON_0", hname);
0732     if (!hist1)
0733     {
0734       DrawDeadServer(transparent[4]);
0735       TC[4]->SetEditable(false);
0736       return -1;
0737     }
0738     hist1->SetMaximum(ymax);
0739     hist1->SetStats(0);
0740     hist1->SetXTitle("Ticks");
0741     hist1->SetYTitle("Events");
0742     hist1->GetXaxis()->SetLabelSize(0.06);
0743     hist1->GetXaxis()->SetTitleSize(0.055);
0744     hist1->GetXaxis()->SetTitleOffset(1.1);
0745 
0746     hist1->GetYaxis()->SetLabelSize(0.06);
0747     hist1->GetYaxis()->SetTitleSize(0.06);
0748     hist1->GetYaxis()->SetTitleOffset(0.45);
0749     hist1->SetTitle("");
0750     hist1->SetLineColor(colors[i]);
0751     leg->AddEntry(hist1, legentry[i].c_str(),"l");
0752     if (i>1)
0753     {
0754       hist1->DrawCopy("same");
0755     }
0756     else
0757     {
0758       hist1->DrawCopy();
0759     }
0760   }
0761   title.SetTextColor(4);
0762   title.SetTextSize(0.1);
0763   title.DrawText(0.5, 0.99, "Ticks to last Event");
0764 //  leg->AddEntry(h_adc_north,"North","l");
0765   leg->SetFillStyle(0);
0766   leg->Draw();
0767 
0768   // else
0769   TText PrintRun;
0770   PrintRun.SetTextFont(62);
0771   PrintRun.SetTextSize(0.04);
0772   PrintRun.SetNDC();          // set to normalized coordinates
0773   PrintRun.SetTextAlign(23);  // center/top alignment
0774   std::ostringstream runnostream;
0775   std::string runstring;
0776   std::pair<time_t, int> evttime = cl->EventTime("CURRENT");
0777   // fill run number and event time into string
0778   runnostream << "GL1 Scaled Trigger Run:" << cl->RunNumber()
0779               << ", Time: " << ctime(&evttime.first);
0780   runstring = runnostream.str();
0781   transparent[4]->cd();
0782   PrintRun.SetTextColor(evttime.second);
0783   PrintRun.DrawText(0.5, 1., runstring.c_str());
0784   TC[4]->Update();
0785   TC[4]->Show();
0786   TC[4]->SetEditable(false);
0787   return 0;
0788 }
0789 
0790 int GL1MonDraw::SavePlot(const std::string &what, const std::string &type)
0791 {
0792   OnlMonClient *cl = OnlMonClient::instance();
0793   int iret = Draw(what);
0794   if (iret)  // on error no png files please
0795   {
0796     return iret;
0797   }
0798   int icnt = 0;
0799   for (TCanvas *canvas : TC)
0800   {
0801     if (canvas == nullptr)
0802     {
0803       continue;
0804     }
0805     icnt++;
0806     std::string filename = ThisName + "_" + std::to_string(icnt) + "_" +
0807       std::to_string(cl->RunNumber()) + "." + type;
0808     cl->CanvasToPng(canvas, filename);
0809   }
0810   return 0;
0811 }
0812 
0813 int GL1MonDraw::MakeHtml(const std::string &what)
0814 {
0815   int iret = Draw(what);
0816   if (iret)  // on error no html output please
0817   {
0818     return iret;
0819   }
0820 
0821   OnlMonClient *cl = OnlMonClient::instance();
0822 
0823   int icnt = 0;
0824   for (TCanvas *canvas : TC)
0825   {
0826     if (canvas == nullptr)
0827     {
0828       continue;
0829     }
0830     icnt++;
0831     // Register the canvas png file to the menu and produces the png file.
0832     std::string pngfile = cl->htmlRegisterPage(*this, canvas->GetTitle(), std::to_string(icnt), "png");
0833     cl->CanvasToPng(canvas, pngfile);
0834   }
0835 
0836   // Now register also EXPERTS html pages, under the EXPERTS subfolder.
0837 
0838   // std::string logfile = cl->htmlRegisterPage(*this, "EXPERTS/Log", "log", "html");
0839   // std::ofstream out(logfile.c_str());
0840   // out << "<HTML><HEAD><TITLE>Log file for run " << cl->RunNumber()
0841   //     << "</TITLE></HEAD>" << std::endl;
0842   // out << "<P>Some log file output would go here." << std::endl;
0843   // out.close();
0844 
0845   // std::string status = cl->htmlRegisterPage(*this, "EXPERTS/Status", "status", "html");
0846   // std::ofstream out2(status.c_str());
0847   // out2 << "<HTML><HEAD><TITLE>Status file for run " << cl->RunNumber()
0848   //      << "</TITLE></HEAD>" << std::endl;
0849   // out2 << "<P>Some status output would go here." << std::endl;
0850   // out2.close();
0851   // cl->SaveLogFile(*this);
0852   return 0;
0853 }
0854 
0855 int GL1MonDraw::FetchTriggerNames()
0856 {
0857   m_TrignameArray.fill("");
0858   m_RunDB->GetTriggerNames(m_TrignameArray, m_CurrentRunnumber);
0859   return 0;
0860 }
0861 
0862 int GL1MonDraw::DrawServerStats()
0863 {
0864   int canvasindex = 2;
0865   OnlMonClient *cl = OnlMonClient::instance();
0866   if (!gROOT->FindObject("GL1ServerStats"))
0867   {
0868     MakeCanvas("GL1ServerStats");
0869   }
0870   TC[canvasindex]->Clear("D");
0871   TC[canvasindex]->SetEditable(true);
0872   transparent[canvasindex]->cd();
0873   TText PrintRun;
0874   PrintRun.SetTextFont(62);
0875   PrintRun.SetNDC();          // set to normalized coordinates
0876   PrintRun.SetTextAlign(23);  // center/top alignment
0877   PrintRun.SetTextSize(0.04);
0878   PrintRun.SetTextColor(1);
0879   PrintRun.DrawText(0.5, 0.99, "Server Statistics");
0880 
0881   PrintRun.SetTextSize(0.02);
0882   double vdist = 0.05;
0883   double vpos = 0.9;
0884   time_t clienttime = time(nullptr);
0885   for (const auto &server : m_ServerSet)
0886   {
0887     std::ostringstream txt;
0888     auto servermapiter = cl->GetServerMap(server);
0889     if (servermapiter == cl->GetServerMapEnd())
0890     {
0891       txt << "Server " << server
0892           << " is dead ";
0893       PrintRun.SetTextColor(kRed);
0894     }
0895     else
0896     {
0897       int errorcounts = -1;
0898       TH1 *gl1_stats = cl->getHisto("GL1MON_0", "gl1_stats");
0899       if (gl1_stats)
0900       {
0901         errorcounts = gl1_stats->GetBinContent(1);
0902       }
0903       int gl1counts = std::get<4>(servermapiter->second);
0904       time_t currtime = std::get<3>(servermapiter->second);
0905       txt << "Server " << server
0906           << ", run number: " << std::get<1>(servermapiter->second)
0907           << ", event count: " << std::get<2>(servermapiter->second);
0908       if (gl1counts >= 0)
0909       {
0910         txt << ", gl1 count: " << gl1counts;
0911       }
0912       txt << ", errors: " << errorcounts;
0913       txt << ", current Event time: " << ctime(&currtime);
0914       if (isHtml())
0915       {
0916         clienttime = currtime;  // just prevent the font from getting red
0917       }
0918       else  // print time diff only for live display
0919       {
0920         txt << ", minutes since last evt: " << (clienttime - currtime) / 60;
0921       }
0922       if (std::get<0>(servermapiter->second) && ((clienttime - currtime) / 60) < 10)
0923       {
0924         PrintRun.SetTextColor(kGray + 2);
0925       }
0926       else
0927       {
0928         PrintRun.SetTextColor(kRed);
0929       }
0930       if (errorcounts > 0)
0931       {
0932         PrintRun.SetTextColor(kRed);
0933       }
0934     }
0935     PrintRun.DrawText(0.5, vpos, txt.str().c_str());
0936     vpos -= vdist;
0937   }
0938   TC[canvasindex]->Update();
0939   TC[canvasindex]->Show();
0940   TC[canvasindex]->SetEditable(false);
0941 
0942   return 0;
0943 }