Back to home page

sPhenix code displayed by LXR

 
 

    


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

0001 #include "MvtxMonDraw.h"
0002 
0003 #include <onlmon/OnlMonClient.h>
0004 #include <onlmon/OnlMonDB.h>
0005 
0006 #include <TAxis.h>  // for TAxis
0007 #include <TCanvas.h>
0008 #include <TColor.h>
0009 #include <TDatime.h>
0010 #include <TEllipse.h>
0011 #include <TExec.h>
0012 #include <TGaxis.h>
0013 #include <TGraphErrors.h>
0014 #include <TH1.h>
0015 #include <TH2.h>
0016 #include <TH2Poly.h>
0017 #include <TH3.h>
0018 #include <TLatex.h>
0019 #include <TPad.h>
0020 #include <TPaveText.h>
0021 #include <TROOT.h>
0022 #include <TStyle.h>
0023 #include <TSystem.h>
0024 #include <TText.h>
0025 
0026 #include <cstring>  // for memset
0027 #include <ctime>
0028 #include <fstream>
0029 #include <iostream>  // for operator<<, basic_ostream, basic_os...
0030 #include <sstream>
0031 #include <vector>  // for vector
0032 
0033 MvtxMonDraw::MvtxMonDraw(const std::string &name)
0034   : OnlMonDraw(name)
0035 {
0036   // this TimeOffsetTicks is neccessary to get the time axis right
0037   TDatime T0(2003, 01, 01, 00, 00, 00);
0038   TimeOffsetTicks = T0.Convert();
0039   // dbvars = new OnlMonDB(ThisName);
0040   for (int iFelix = 0; iFelix < NFlx; iFelix++)
0041   {
0042     dbvars[iFelix] = new OnlMonDB(Form("MVTXMON_%d", iFelix));
0043   }
0044   return;
0045 }
0046 
0047 int MvtxMonDraw::Init()
0048 {
0049   return 0;
0050 }
0051 
0052 int MvtxMonDraw::MakeCanvas(const std::string &name)
0053 {
0054   OnlMonClient *cl = OnlMonClient::instance();
0055   int xsize = cl->GetDisplaySizeX();
0056   int ysize = cl->GetDisplaySizeY();
0057   /* if (name == "MvtxMon1")
0058    {
0059      // xpos (-1) negative: do not draw menu bar
0060      TC[0] = new TCanvas(name.c_str(), "MvtxMon Example Monitor", -1, 0, xsize / 2, ysize);
0061      // root is pathetic, whenever a new TCanvas is created root piles up
0062      // 6kb worth of X11 events which need to be cleared with
0063      // gSystem->ProcessEvents(), otherwise your process will grow and
0064      // grow and grow but will not show a definitely lost memory leak
0065      gSystem->ProcessEvents();
0066      Pad[0] = new TPad("mvtxpad1", "who needs this?", 0.1, 0.7, 0.9, 0.9, 0);
0067      Pad[1] = new TPad("mvtxpad2", "who needs this?", 0.1, 0.3, 0.9, 0.7, 0);
0068      Pad[2] = new TPad("mvtxpad3", "who needs this?", 0.1, 0.05, 0.9, 0.3, 0);
0069      Pad[0]->Draw();
0070      Pad[1]->Draw();
0071        Pad[2]->Draw();
0072      // this one is used to plot the run number on the canvas
0073      transparent[0] = new TPad("transparent0", "this does not show", 0, 0, 1, 1);
0074      transparent[0]->SetFillStyle(4000);
0075      transparent[0]->Draw();
0076      TC[0]->SetEditable(false);
0077    }
0078    else if (name == "MvtxMon2")
0079    {
0080      // xpos negative: do not draw menu bar
0081      TC[1] = new TCanvas(name.c_str(), "MvtxMon2 Example Monitor", -xsize / 2, 0, xsize / 2, ysize);
0082      gSystem->ProcessEvents();
0083      Pad[3] = new TPad("mvtxpad4", "who needs this?", 0.1, 0.5, 0.9, 0.9, 0);
0084      Pad[4] = new TPad("mvtxpad5", "who needs this?", 0.1, 0.05, 0.9, 0.45, 0);
0085      Pad[3]->Draw();
0086      Pad[4]->Draw();
0087      // this one is used to plot the run number on the canvas
0088      transparent[1] = new TPad("transparent1", "this does not show", 0, 0, 1, 1);
0089      transparent[1]->SetFillStyle(4000);
0090      transparent[1]->Draw();
0091      TC[1]->SetEditable(false);
0092    }
0093    else if (name == "MvtxMon3")
0094    {
0095      TC[2] = new TCanvas(name.c_str(), "MvtxMon3 Example Monitor", xsize / 2, 0, xsize / 2, ysize);
0096      gSystem->ProcessEvents();
0097      Pad[5] = new TPad("mvtxpad6", "who needs this?", 0.1, 0.1, 0.9, 0.9, 0);
0098      //Pad[6] = new TPad("mvtxpad7", "who needs this?", 0.1, 0.05, 0.9, 0.45, 0);
0099      Pad[5]->Draw();
0100      //Pad[6]->Draw();
0101      // this one is used to plot the run number on the canvas
0102      //        transparent[2] = new TPad("transparent2", "this does not show", 0, 0, 1, 1);
0103      //        transparent[2]->SetFillStyle(4000);
0104      //        transparent[2]->Draw();
0105      //      TC[2]->SetEditable(0);
0106    }*/
0107   if (name == "MvtxMon_HitMap")
0108   {
0109     TC[0] = new TCanvas(name.c_str(), "MvtxMon Hitmaps", -1, 0, xsize, ysize);
0110     gSystem->ProcessEvents();
0111     // TC[3]->Divide(2,1/*NSTAVE*/);
0112     Pad[0] = new TPad("mvtxpad0", "who needs this?", 0.05, 0.02, 0.98, 0.92, 0);
0113     Pad[0]->Draw();
0114     // this one is used to plot the run number on the canvas
0115     transparent[0] = new TPad("transparent0", "this does not show", 0, 0, 1, 1);
0116     transparent[0]->SetFillStyle(4000);
0117     transparent[0]->Draw();
0118     TC[0]->SetEditable(false);
0119     TC[0]->SetTopMargin(0.05);
0120     TC[0]->SetBottomMargin(0.05);
0121   }
0122   else if (name == "MvtxMon_General")
0123   {
0124     TC[1] = new TCanvas(name.c_str(), "MVTX Monitoring General", -1, 0, xsize, ysize);
0125     gSystem->ProcessEvents();
0126     TC[1]->cd();
0127     Pad[1] = new TPad("mvtxpad1", "who needs this?", 0., 0.02, 0.98, 0.97, 0);
0128     Pad[1]->Draw();
0129     // Pad[7]->Divide(4,2);
0130     //  this one is used to plot the run number on the canvas
0131     transparent[1] = new TPad("transparent1", "this does not show", 0, 0, 1, 1);
0132     transparent[1]->SetFillStyle(4000);
0133     transparent[1]->Draw();
0134     TC[1]->SetEditable(false);
0135     TC[1]->SetTopMargin(0.05);
0136     TC[1]->SetBottomMargin(0.05);
0137     // Pad[8]->SetRightMargin(0.13);
0138   }
0139   else if (name == "MvtxMon_FEE")
0140   {
0141     TC[2] = new TCanvas(name.c_str(), "MVTX Monitoring FEE Expert", -1, 0, xsize, ysize);
0142     gSystem->ProcessEvents();
0143     Pad[2] = new TPad("mvtxpad2", "who needs this?", 0., 0.02, 0.98, 0.97, 0);
0144     Pad[2]->Draw();
0145 
0146     // this one is used to plot the run number on the canvas
0147     transparent[2] = new TPad("transparent2", "this does not show", 0, 0, 1, 1);
0148     transparent[2]->SetFillStyle(4000);
0149     transparent[2]->Draw();
0150     TC[2]->SetEditable(false);
0151     TC[2]->SetTopMargin(0.05);
0152     TC[2]->SetBottomMargin(0.05);
0153   }
0154   else if (name == "MvtxMon_OCC")
0155   {
0156     TC[3] = new TCanvas(name.c_str(), "MVTX Monitoring Occupancy Expert", -1, 0, xsize, ysize);
0157     gSystem->ProcessEvents();
0158     Pad[3] = new TPad("mvtxpad3", "who needs this?", 0., 0.02, 0.98, 0.97, 0);
0159     Pad[3]->Draw();
0160 
0161     // this one is used to plot the run number on the canvas
0162     transparent[3] = new TPad("transparent3", "this does not show", 0, 0, 1, 1);
0163     transparent[3]->SetFillStyle(4000);
0164     transparent[3]->Draw();
0165     TC[3]->SetEditable(false);
0166     TC[3]->SetTopMargin(0.05);
0167     TC[3]->SetBottomMargin(0.05);
0168   }
0169   else if (name == "MvtxMon_FHR")
0170   {
0171     TC[4] = new TCanvas(name.c_str(), "MVTX Monitoring FHR Expert", -1, 0, xsize, ysize);
0172     gSystem->ProcessEvents();
0173     Pad[4] = new TPad("mvtxpad4", "who needs this?", 0., 0.02, 0.98, 0.97, 0);
0174     Pad[4]->Draw();
0175 
0176     // this one is used to plot the run number on the canvas
0177     transparent[4] = new TPad("transparent4", "this does not show", 0, 0, 1, 1);
0178     transparent[4]->SetFillStyle(4000);
0179     transparent[4]->Draw();
0180     TC[4]->SetEditable(false);
0181     TC[4]->SetTopMargin(0.05);
0182     TC[4]->SetBottomMargin(0.05);
0183   }
0184   else if (name == "MvtxMon3")
0185   {
0186     TC[5] = new TCanvas(name.c_str(), "MvtxMon3 Example Monitor", xsize / 2, 0, xsize / 2, ysize);
0187     gSystem->ProcessEvents();
0188     Pad[5] = new TPad("mvtxpad5", "who needs this?", 0.1, 0.1, 0.9, 0.9, 0);
0189     // Pad[6] = new TPad("mvtxpad7", "who needs this?", 0.1, 0.05, 0.9, 0.45, 0);
0190     Pad[5]->Draw();
0191     transparent[5] = new TPad("transparent5", "this does not show", 0, 0, 1, 1);
0192     transparent[5]->SetFillStyle(4000);
0193     transparent[5]->Draw();
0194     TC[5]->SetEditable(false);
0195     TC[5]->SetTopMargin(0.05);
0196     TC[5]->SetBottomMargin(0.05);
0197     // Pad[6]->Draw();
0198     //  this one is used to plot the run number on the canvas
0199     //         transparent[2] = new TPad("transparent2", "this does not show", 0, 0, 1, 1);
0200     //         transparent[2]->SetFillStyle(4000);
0201     //         transparent[2]->Draw();
0202     //       TC[2]->SetEditable(0);
0203   }
0204   else if (name == "MvtxMonServerStats")
0205   {
0206     TC[6] = new TCanvas(name.c_str(), "MvtxMon Server Stats", -1, 0, xsize, ysize);
0207     gSystem->ProcessEvents();
0208     transparent[6] = new TPad("transparent6", "this does not show", 0, 0, 1, 1);
0209     transparent[6]->SetFillColor(kGray);
0210     transparent[6]->Draw();
0211     TC[6]->SetEditable(false);
0212     TC[6]->SetTopMargin(0.05);
0213     TC[6]->SetBottomMargin(0.05);
0214     // Pad[6]->Draw();
0215     //  this one is used to plot the run number on the canvas
0216     //         transparent[2] = new TPad("transparent2", "this does not show", 0, 0, 1, 1);
0217     //         transparent[2]->SetFillStyle(4000);
0218     //         transparent[2]->Draw();
0219     //       TC[2]->SetEditable(0);
0220   }
0221   return 0;
0222 }
0223 
0224 int MvtxMonDraw::Draw(const std::string &what)
0225 {
0226   int iret = 0;
0227   int idraw = 0;
0228   /*if (what == "ALL" || what == "L0L"|| what == "L0R"|| what == "L1L"|| what == "L1R"|| what == "L2L"|| what == "L2R")
0229   {
0230     iret += DrawHitMap(what);
0231     idraw++;
0232   }*/
0233   if (what == "ALL" || what == "GENERAL")
0234   {
0235     iret += DrawGeneral(what);
0236     idraw++;
0237   }
0238   if (what == "ALL" || what == "FEE")
0239   {
0240     iret += DrawFEE(what);
0241     idraw++;
0242   }
0243   if (what == "ALL" || what == "OCC")
0244   {
0245     iret += DrawOCC(what);
0246     idraw++;
0247   }
0248   if (what == "ALL" || what == "FHR")
0249   {
0250     iret += DrawFHR(what);
0251     idraw++;
0252   }
0253   if (what == "ALL" || what == "SERVERSTATS")
0254   {
0255     iret += DrawServerStats();
0256     idraw++;
0257   }
0258   if (what == "HISTORY")
0259   {
0260     iret += DrawHistory(what);
0261     idraw++;
0262   }
0263   if (!idraw)
0264   {
0265     std::cout << __PRETTY_FUNCTION__ << " Unimplemented Drawing option: " << what << std::endl;
0266     iret = -1;
0267   }
0268   return iret;
0269 }
0270 
0271 int MvtxMonDraw::DrawHitMap(const std::string &what)
0272 {
0273   OnlMonClient *cl = OnlMonClient::instance();
0274 
0275   const int canvasID = 0;
0276   const int padID = 0;
0277   TH3 *mvtxmon_HitMap[NFlx + 1] = {nullptr};
0278   if (!gROOT->FindObject("MvtxMon_HitMap"))
0279   {
0280     MakeCanvas("MvtxMon_HitMap");
0281   }
0282   TC[canvasID]->SetEditable(true);
0283   TC[canvasID]->Clear("D");
0284 
0285   int aLs = 0;
0286   int aLe = 0;
0287   int aSs = 0;
0288   int aSe = 0;
0289   if (what == "L0R" || what == "ALL")
0290   {
0291     aLs = 0;
0292     aLe = 1;
0293     aSs = 0;
0294     aSe = 6;
0295   }
0296   else if (what == "L0L")
0297   {
0298     aLs = 0;
0299     aLe = 1;
0300     aSs = 6;
0301     aSe = 12;
0302   }
0303   else if (what == "L1R")
0304   {
0305     aLs = 1;
0306     aLe = 2;
0307     aSs = 0;
0308     aSe = 8;
0309   }
0310   else if (what == "L1L")
0311   {
0312     aLs = 1;
0313     aLe = 2;
0314     aSs = 8;
0315     aSe = 16;
0316   }
0317   else if (what == "L2R")
0318   {
0319     aLs = 2;
0320     aLe = 3;
0321     aSs = 0;
0322     aSe = 10;
0323   }
0324   else if (what == "L2L")
0325   {
0326     aLs = 2;
0327     aLe = 3;
0328     aSs = 10;
0329     aSe = 20;
0330   }
0331   Pad[padID]->Divide(NCHIP, aSe - aSs /*NSTAVE*/);
0332 
0333   int ipad = 0;
0334   int returnCode = 0;
0335 
0336   for (int iFelix = 0; iFelix < NFlx; iFelix++)
0337   {
0338     mvtxmon_HitMap[iFelix] = dynamic_cast<TH3 *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("MVTXMON_chipHitmapFLX%d", iFelix)));
0339   }
0340   MergeServers<TH3 *>(mvtxmon_HitMap);
0341   if (mvtxmon_HitMap[NFlx])
0342   {
0343     mvtxmon_HitMap[NFlx]->GetXaxis()->CenterTitle();
0344     mvtxmon_HitMap[NFlx]->GetYaxis()->CenterTitle();
0345     mvtxmon_HitMap[NFlx]->GetYaxis()->SetTitleOffset(1.4);
0346     mvtxmon_HitMap[NFlx]->GetXaxis()->SetTitleOffset(0.75);
0347     mvtxmon_HitMap[NFlx]->GetXaxis()->SetTitleSize(0.06);
0348     mvtxmon_HitMap[NFlx]->GetYaxis()->SetTitleOffset(0.75);
0349     mvtxmon_HitMap[NFlx]->GetYaxis()->SetTitleSize(0.06);
0350   }
0351 
0352   for (int aLayer = aLs; aLayer < aLe; aLayer++)
0353   {
0354     for (int aStave = aSs; aStave < aSe; aStave++)
0355     {
0356       for (int iChip = 0; iChip < 9; iChip++)
0357       {
0358         // int stave = aLayer==0?aStave:NStaves[aLayer]+aStave;
0359         TString prefix = Form("%d%d%d", aLayer, aStave, iChip);
0360         mvtxmon_HitMap[NFlx]->GetZaxis()->SetRange(((chipmapoffset[aLayer] + aStave) * 9 + iChip + 1), ((chipmapoffset[aLayer] + aStave) * 9 + iChip + 1));
0361         returnCode += PublishHistogram(Pad[padID], ipad * 9 + iChip + 1, mvtxmon_HitMap[NFlx]->Project3D(prefix + "yx"), "colz");  // publish merged one
0362         gStyle->SetOptStat(0);
0363       }
0364       ipad++;
0365     }
0366   }
0367 
0368   TC[canvasID]->cd();
0369   TPaveText *ptchip[9] = {nullptr};
0370   for (int i = 0; i < 9; i++)
0371   {
0372     ptchip[i] = new TPaveText(0.05 + 0.1033 * i, .92, 0.05 + 0.1033 * (i + 1), 0.97, "blNDC");
0373     ptchip[i]->SetTextSize(0.03);
0374     ptchip[i]->SetFillColor(4000);
0375     ptchip[i]->SetLineColor(0);
0376     ptchip[i]->SetBorderSize(1);
0377     ptchip[i]->AddText(Form("Chip %d", i));
0378     ptchip[i]->Draw();
0379   }
0380 
0381   TPaveText *ptstave[10] = {nullptr};
0382   for (int i = 0; i < aSe - aSs; i++)
0383   {
0384     ptstave[i] = new TPaveText(0.0, 0.93 - ((i + 1) * 0.92 / (aSe - aSs)), 0.05, 0.93 - (i * 0.92 / (aSe - aSs)), "blNDC");
0385     ptstave[i]->SetTextSize(0.02);
0386     ptstave[i]->SetFillColor(4000);
0387     ptstave[i]->SetLineColor(0);
0388     ptstave[i]->SetBorderSize(1);
0389     ptstave[i]->AddText(Form("Stave %d", aSs + i));
0390     ptstave[i]->Draw();
0391   }
0392 
0393   TPaveText *ptlayer = {nullptr};
0394   ptlayer = new TPaveText(0.01, .92, 0.06, 0.97, "blNDC");
0395   ptlayer->SetTextSize(0.035);
0396   ptlayer->SetFillColor(4000);
0397   ptlayer->SetLineColor(0);
0398   ptlayer->SetBorderSize(1);
0399   if (what == "L0R" || what == "L0R" || what == "ALL")
0400   {
0401     ptlayer->AddText("Layer 0");
0402   }
0403   if (what == "L1R" || what == "L1R")
0404   {
0405     ptlayer->AddText("Layer 1");
0406   }
0407   if (what == "L2R" || what == "L2R")
0408   {
0409     ptlayer->AddText("Layer 2");
0410   }
0411   ptlayer->Draw();
0412 
0413   // PublishStatistics(TC[canvasID],cl);
0414   PublishStatistics(canvasID, cl);
0415 
0416   // TC[canvasID]->Modified();
0417   TC[canvasID]->Update();
0418   TC[canvasID]->SetEditable(false);
0419   return returnCode < 0 ? -1 : 0;
0420 }
0421 
0422 int MvtxMonDraw::DrawGeneral(const std::string & /* what */)
0423 {
0424   OnlMonClient *cl = OnlMonClient::instance();
0425   const int canvasID = 1;
0426   const int padID = 1;
0427 
0428   TH2Poly *mvtxmon_LaneStatusOverview[NFlx + 1] = {nullptr};
0429   TH2Poly *mvtxmon_mGeneralOccupancy[NFlx + 1] = {nullptr};
0430   TH2Poly *mGeneralNoisyPixel[NFlx + 1] = {nullptr};
0431   TH1D *mvtxmon_mGeneralErrorPlots[NFlx + 1] = {nullptr};
0432   TH1D *mvtxmon_mGeneralErrorPlotsTime[NFlx + 1] = {nullptr};
0433   TH1I *hChipStrobes[NFlx + 1] = {nullptr};
0434   TH1I *hChipL1[NFlx + 1] = {nullptr};
0435   TH2D *mvtxmon_mGeneralErrorFile[NFlx + 1] = {nullptr};
0436   TH1D *mvtxmon_ChipStave1D[NFlx + 1] = {nullptr};
0437   TH1I *hStrobesDMA[NFlx + 1] = {nullptr};
0438   TH1I *hDMAstatus[NFlx + 1] = {nullptr};
0439 
0440   for (int iFelix = 0; iFelix < NFlx; iFelix++)
0441   {
0442     mvtxmon_LaneStatusOverview[iFelix] = dynamic_cast<TH2Poly *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "FEE_LaneStatus_Overview_FlagPROBLEM"));
0443     mvtxmon_mGeneralOccupancy[iFelix] = dynamic_cast<TH2Poly *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_Occupancy"));
0444     mGeneralNoisyPixel[iFelix] = dynamic_cast<TH2Poly *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_Noisy_Pixel"));
0445     mvtxmon_mGeneralErrorPlots[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_DecErrors"));
0446     mvtxmon_mGeneralErrorPlotsTime[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_DecErrorsTime"));
0447     hChipStrobes[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_hfeeStrobes"));
0448     hChipL1[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_feeL1"));
0449     mvtxmon_mGeneralErrorFile[iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_DecErrorsEndpoint"));
0450     mvtxmon_ChipStave1D[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_ChipStave1D"));
0451     hStrobesDMA[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "hStrobesDMA"));
0452     hDMAstatus[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "hDMAstatus"));
0453   }
0454 
0455   // injecting errors here
0456   // mvtxmon_LaneStatusOverview[0][1] = mvtxmon_LaneStatusOverview[0][0];
0457   // injecting errors done
0458 
0459   int bitset = 0;
0460   int bitsetOR = 0;
0461   int bitsetAND = 63;
0462   bitset = MergeServers<TH2Poly *>(mvtxmon_LaneStatusOverview);
0463   bitsetOR |= bitset;
0464   bitsetAND &= bitset;
0465   bitset = MergeServers<TH2Poly *>(mvtxmon_mGeneralOccupancy);
0466   bitsetOR |= bitset;
0467   bitsetAND &= bitset;
0468   bitset = MergeServers<TH2Poly *>(mGeneralNoisyPixel);
0469   bitsetOR |= bitset;
0470   bitsetAND &= bitset;
0471   bitset = MergeServers<TH1D *>(mvtxmon_mGeneralErrorPlots);
0472   bitsetOR |= bitset;
0473   bitsetAND &= bitset;
0474   bitset = MergeServers<TH1D *>(mvtxmon_mGeneralErrorPlotsTime);
0475   bitsetOR |= bitset;
0476   bitsetAND &= bitset;
0477   bitset = MergeServers<TH1I *>(hChipStrobes);
0478   bitsetOR |= bitset;
0479   bitsetAND &= bitset;
0480   bitset = MergeServers<TH1I *>(hChipL1);
0481   bitsetOR |= bitset;
0482   bitsetAND &= bitset;
0483   bitset = MergeServers<TH2D *>(mvtxmon_mGeneralErrorFile);
0484   bitsetOR |= bitset;
0485   bitsetAND &= bitset;
0486   bitset = MergeServers<TH1D *>(mvtxmon_ChipStave1D);
0487   bitsetOR |= bitset;
0488   bitsetAND &= bitset;
0489   bitset = MergeServers<TH1I *>(hStrobesDMA);
0490   bitsetOR |= bitset;
0491   bitsetAND &= bitset;
0492   bitset = MergeServers<TH1I *>(hDMAstatus);
0493   bitsetOR |= bitset;
0494   bitsetAND &= bitset;
0495 
0496   if (mvtxmon_LaneStatusOverview[NFlx])
0497   {
0498     mvtxmon_LaneStatusOverview[NFlx]->SetStats(false);
0499     mvtxmon_LaneStatusOverview[NFlx]->GetYaxis()->SetTitleOffset(0.6);
0500     mvtxmon_LaneStatusOverview[NFlx]->SetMinimum(0);
0501     mvtxmon_LaneStatusOverview[NFlx]->SetMaximum(1);
0502   }
0503 
0504   if (mvtxmon_mGeneralOccupancy[NFlx])
0505   {
0506     mvtxmon_mGeneralOccupancy[NFlx]->GetYaxis()->SetTitleOffset(0.6);
0507     mvtxmon_mGeneralOccupancy[NFlx]->SetMinimum(0);
0508     //mvtxmon_mGeneralOccupancy[NFlx]->SetMaximum(100E-6);  // Let max value float for pp
0509     mvtxmon_mGeneralOccupancy[NFlx]->SetContour(100);
0510   }
0511 
0512   if (mvtxmon_ChipStave1D[NFlx])
0513   {
0514     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetLabelSize(0.05);
0515     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleSize(0.055);
0516     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleOffset(0.9);
0517     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetLabelSize(0.045);
0518     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleSize(0.05);
0519     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleOffset(1.2);
0520   }
0521 
0522   /*if (mvtxmon_mGeneralErrorFile[NFlx])
0523   {
0524     for (int bin = 1; bin < mvtxmon_mGeneralErrorFile[NFlx]->GetNbinsX() + 1; bin++)
0525     {
0526       if (bin <= 12)
0527       {
0528         mvtxmon_mGeneralErrorFile[NFlx]->GetXaxis()->SetBinLabel(bin, Form("%d", (bin - 1) % 2));
0529       }
0530       else
0531       {
0532         mvtxmon_mGeneralErrorFile[NFlx]->GetXaxis()->SetBinLabel(bin, "");
0533       }
0534     }
0535     mvtxmon_mGeneralErrorFile[NFlx]->GetXaxis()->SetTitleSize(0.045);
0536     mvtxmon_mGeneralErrorFile[NFlx]->GetYaxis()->SetTitleSize(0.045);*/
0537   //}
0538 
0539   if (!gROOT->FindObject("MvtxMon_General"))
0540   {
0541     MakeCanvas("MvtxMon_General");
0542   }
0543 
0544   TC[canvasID]->SetEditable(true);
0545   TC[canvasID]->Clear("D");
0546 
0547   Pad[padID]->Divide(4, 2);
0548   int returnCode = 0;
0549 
0550   // Pad[padID]->cd(1)->SetRightMargin(0.15);
0551   Pad[padID]->cd(3)->SetRightMargin(0.16);
0552   Pad[padID]->cd(4)->SetRightMargin(0.15);
0553   Pad[padID]->cd(4)->SetLeftMargin(0.15);
0554   Pad[padID]->cd(6)->SetLeftMargin(0.16);
0555   Pad[padID]->cd(6)->SetTopMargin(0.16);
0556   Pad[padID]->cd(6)->SetBottomMargin(0.14);
0557 
0558   // injecting errors here
0559   /*  mvtxmon_LaneStatusOverview[1][NFlx]->SetBinContent(5,0.5);
0560     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(11,0.5);
0561     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(12,0.5);
0562     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(13,0.5);
0563     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(14,0.5);
0564     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(15,0.5);
0565     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(16,0.5);
0566     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(17,0.5);
0567     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(18,0.5);
0568     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(19,0.5);
0569     mvtxmon_mGeneralErrorFile[NFlx]->SetBinContent(17,5,20);*/
0570   // injecting errors done
0571 
0572   if (mvtxmon_mGeneralErrorPlots[NFlx])
0573   {
0574     mvtxmon_mGeneralErrorPlots[NFlx]->GetXaxis()->SetTitleSize(0.045);
0575     mvtxmon_mGeneralErrorPlots[NFlx]->GetYaxis()->SetTitleSize(0.045);
0576   }
0577 
0578   if (mvtxmon_mGeneralErrorPlotsTime[NFlx])
0579   {
0580     mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->SetLabelOffset(999);
0581     mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->SetTickLength(0);
0582   }
0583 
0584   if (hChipStrobes[NFlx])
0585   {
0586     hChipStrobes[NFlx]->SetMinimum(0);
0587     hChipStrobes[NFlx]->SetTitle("Strobe & L1 vs Chip");
0588   }
0589 
0590   TPaveText *tlayer[3] = {nullptr};
0591 
0592   for (int i = 0; i < 3; i++)
0593   {
0594     double shift[3] = {0, 0.25, 0.55};
0595     tlayer[i] = new TPaveText(.14 + shift[i], .87, .24 + shift[i], .93, "blNDC");
0596     tlayer[i]->SetTextSize(0.05);
0597     tlayer[i]->SetFillColor(0);
0598     tlayer[i]->SetTextAlign(22);
0599     tlayer[i]->SetLineColor(0);
0600     tlayer[i]->SetBorderSize(1);
0601     tlayer[i]->AddText(Form("Layer %d", i));
0602   }
0603 
0604   Pad[padID]->cd(4)->SetTopMargin(0.16);
0605 
0606   Pad[padID]->cd(6)->SetTopMargin(0.2);
0607   Pad[padID]->cd(6)->SetLeftMargin(0.16);
0608 
0609   Pad[padID]->cd(2)->SetRightMargin(0.16);
0610 
0611   std::vector<MvtxMonDraw::Quality> status;
0612   status = analyseForError(mvtxmon_LaneStatusOverview[NFlx], mGeneralNoisyPixel[NFlx], hChipStrobes[NFlx], mvtxmon_mGeneralErrorFile[NFlx], mvtxmon_mGeneralErrorPlotsTime[NFlx], hDMAstatus[NFlx]);
0613 
0614   returnCode += PublishHistogram(Pad[padID], 1, mvtxmon_LaneStatusOverview[NFlx], "col", 2);
0615   returnCode += PublishHistogram(Pad[padID], 1, mvtxmon_LaneStatusOverview[NFlx], "colz same", 2);
0616   // DrawPave(status, 0);
0617   // returnCode += PublishHistogram(Pad[padID], 2, mvtxmon_mGeneralOccupancy[NFlx]);
0618   returnCode += PublishHistogram(Pad[padID], 2, mvtxmon_mGeneralOccupancy[NFlx], "col", 0);
0619   returnCode += PublishHistogram(Pad[padID], 2, mvtxmon_mGeneralOccupancy[NFlx], "colz same", 0);
0620   returnCode += PublishHistogram(Pad[padID], 3, mGeneralNoisyPixel[NFlx], "colz", 1);
0621   returnCode += PublishHistogram(Pad[padID], 3, mGeneralNoisyPixel[NFlx], "colztext same", 1);
0622   returnCode += PublishHistogram(Pad[padID], 5, mvtxmon_mGeneralErrorPlotsTime[NFlx]);
0623 
0624   if (mvtxmon_mGeneralErrorPlotsTime[NFlx])
0625   {
0626     // Redraw the new axis
0627     gPad->Update();
0628     TGaxis *newaxis = new TGaxis(gPad->GetUxmax(),
0629                                  gPad->GetUymin(),
0630                                  gPad->GetUxmin(),
0631                                  gPad->GetUymin(),
0632                                  mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->GetXmin(),
0633                                  mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->GetXmax(),
0634                                  510, "-");
0635     newaxis->SetLabelOffset(-0.04);
0636     newaxis->SetLabelSize(0.04);
0637     newaxis->Draw();
0638   }
0639   // returnCode += PublishHistogram(Pad[padID], 5, hStrobesDMA[NFlx]);
0640 
0641   returnCode += PublishHistogram(Pad[padID], 4, hChipStrobes[NFlx]);
0642   if (hChipStrobes[NFlx])
0643   {
0644     for (const int &lay : LayerBoundaryFEE)
0645     {
0646       auto l = new TLine(lay, 0, lay, 1.1 * hChipStrobes[NFlx]->GetMaximum());
0647       l->Draw("same");
0648     }
0649   }
0650   Float_t rightmax = 0.1;
0651   if (hChipL1[NFlx] && hChipStrobes[NFlx])
0652   {
0653     rightmax = 2 * hChipL1[NFlx]->GetMaximum();
0654     Float_t scale = hChipStrobes[NFlx]->GetMaximum() / rightmax;
0655     hChipL1[NFlx]->SetLineColor(kRed);
0656     hChipL1[NFlx]->Scale(scale);
0657   }
0658   returnCode += PublishHistogram(Pad[padID], 4, hChipL1[NFlx], "same hist");
0659   if (hChipStrobes[NFlx])
0660   {
0661     TGaxis *axis = new TGaxis(48 * 3, 0, 48 * 3, hChipStrobes[NFlx]->GetMaximum(), 0, rightmax, 510, "+L");
0662     axis->SetLineColor(kRed);
0663     axis->SetLabelColor(kRed);
0664     axis->SetLabelFont(42);
0665     axis->SetTitleFont(42);
0666     axis->SetTitleColor(kRed);
0667     axis->SetTitle("Number of L1 triggers");
0668     axis->Draw();
0669   }
0670   for (auto &i : tlayer)
0671   {
0672     i->Draw();
0673   }
0674 
0675   returnCode += PublishHistogram(Pad[padID], 6, mvtxmon_ChipStave1D[NFlx]);
0676   if (mvtxmon_ChipStave1D[NFlx])
0677   {
0678     for (const int &lay : LayerBoundaryChip)
0679     {
0680       auto ll = new TLine(lay, 0, lay, 1.1 * mvtxmon_ChipStave1D[NFlx]->GetMaximum());
0681       ll->Draw("same");
0682     }
0683   }
0684   for (auto &i : tlayer)
0685   {
0686     i->Draw();
0687   }
0688 
0689   // returnCode += PublishHistogram(Pad[padID], 6, mvtxmon_mGeneralErrorFile[NFlx], "lcol");
0690 
0691   /*TPaveText *ptt5 = new TPaveText(.1, .85, .5, .95, "blNDC");
0692   ptt5->SetTextSize(0.02);
0693   ptt5->SetFillColor(0);
0694   ptt5->SetLineColor(0);
0695   ptt5->SetBorderSize(1);
0696   ptt5->AddText(" FLX 0   FLX 1   FLX 2   FLX 3   FLX 4   FLX 5");
0697   ptt5->Draw();*/
0698 
0699   Pad[padID]->cd(7);
0700 
0701   TPaveText *bulbRed = new TPaveText(0.1, 0.82, 0.9, 0.92, "NDC");
0702   bulbRed->SetName("BulbRed");
0703   formatPaveText(bulbRed, 0.05, kRed, 12, "#color[2]{MVTX has errors}");
0704 
0705   TPaveText *bulbYellow = new TPaveText(0.1, 0.82, 0.9, 0.92, "NDC");
0706   bulbYellow->SetName("BulbYellow");
0707   formatPaveText(bulbYellow, 0.05, kRed, 12, "#color[808]{MVTX has minor errors}");
0708 
0709   TPaveText *bulbGreen = new TPaveText(0.1, 0.82, 0.9, 0.92, "NDC");
0710   bulbGreen->SetName("BulbGreen");
0711   formatPaveText(bulbGreen, 0.05, kGreen, 12, "#color[418]{MVTX is OK}");
0712 
0713   TPaveText *bulb = new TPaveText(0.05, 0.05, 0.95, 0.95, "NDC");
0714 
0715   TPaveText *ptt4 = new TPaveText(.1, .07, .9, .58, "blNDC");
0716   ptt4->SetTextSize(0.04);
0717   ptt4->SetFillColor(0);
0718   ptt4->SetTextAlign(22);
0719   ptt4->SetLineColor(0);
0720   ptt4->SetBorderSize(1);
0721   ptt4->AddText("Alarms:");
0722 
0723   Quality q = Quality::Good;
0724 
0725   for (int i = 0; i < 18; i++)
0726   {
0727     // std::cout<<i<<" "<<status.at(i)<<std::endl;
0728     if (status.at(i) == Quality::Medium) q = Quality::Medium;
0729     if (status.at(i) == Quality::Bad) q = Quality::Bad;
0730   }
0731 
0732   if (q == Quality::Good)
0733   {
0734     bulb->SetFillColor(kGreen);
0735     bulb->Draw();
0736     bulbGreen->Draw("same");
0737   }
0738 
0739   for (int i = 0; i < 18; i++)
0740   {
0741     if (status.at(i) == Quality::Medium) q = Quality::Medium;
0742   }
0743 
0744   if (q == Quality::Medium)
0745   {
0746     if (status.at(0) == Quality::Medium)
0747     {
0748       // ptt4->AddText("#color[808]{Layer 0 Medium}");
0749       ptt4->AddText("#color[808]{Lane error(s) in Layer 0}");
0750     }
0751     if (status.at(1) == Quality::Medium)
0752     {
0753       // ptt4->AddText("#color[808]{QA Layer 1 Medium}");
0754       ptt4->AddText("#color[808]{Lane error(s) in Layer 1}");
0755     }
0756     if (status.at(2) == Quality::Medium)
0757     {
0758       // ptt4->AddText("#color[808]{QA Layer 2 Medium}");
0759       ptt4->AddText("#color[808]{Lane error(s) in Layer 2}");
0760     }
0761     if (status.at(3) == Quality::Medium)
0762     {
0763       ptt4->AddText("#color[808]{Medium level of noisy pixels}");
0764     }
0765     if (status.at(4) == Quality::Medium)
0766     {
0767       ptt4->AddText("#color[808]{Big variation in number of strobes}");
0768     }
0769     if (status.at(5) == Quality::Medium)
0770     {
0771       ptt4->AddText("#color[808]{FELIX 0 DMA 0 Decoder errors detected}");
0772     }
0773     if (status.at(6) == Quality::Medium)
0774     {
0775       ptt4->AddText("#color[808]{FELIX 0 DMA 1 Decoder errors detected}");
0776     }
0777     if (status.at(7) == Quality::Medium)
0778     {
0779       ptt4->AddText("#color[808]{FELIX 1 DMA 0 Decoder errors detected}");
0780     }
0781     if (status.at(8) == Quality::Medium)
0782     {
0783       ptt4->AddText("#color[808]{FELIX 1 DMA 1 Decoder errors detected}");
0784     }
0785     if (status.at(9) == Quality::Medium)
0786     {
0787       ptt4->AddText("#color[808]{FELIX 2 DMA 0 Decoder errors detected}");
0788     }
0789     if (status.at(10) == Quality::Medium)
0790     {
0791       ptt4->AddText("#color[808]{FELIX 2 DMA 1 Decoder errors detected}");
0792     }
0793     if (status.at(11) == Quality::Medium)
0794     {
0795       ptt4->AddText("#color[808]{FELIX 3 DMA 0 Decoder errors detected}");
0796     }
0797     if (status.at(12) == Quality::Medium)
0798     {
0799       ptt4->AddText("#color[808]{FELIX 3 DMA 1 Decoder errors detected}");
0800     }
0801     if (status.at(13) == Quality::Medium)
0802     {
0803       ptt4->AddText("#color[808]{FELIX 4 DMA 0 Decoder errors detected}");
0804     }
0805     if (status.at(14) == Quality::Medium)
0806     {
0807       ptt4->AddText("#color[808]{FELIX 4 DMA 1 Decoder errors detected}");
0808     }
0809     if (status.at(15) == Quality::Medium)
0810     {
0811       ptt4->AddText("#color[808]{FELIX 5 DMA 0 Decoder errors detected}");
0812     }
0813     if (status.at(16) == Quality::Medium)
0814     {
0815       ptt4->AddText("#color[808]{FELIX 5 DMA 1 Decoder errors detected}");
0816     }
0817     if (status.at(17) == Quality::Medium)
0818     {
0819       ptt4->AddText("#color[808]{1 DMA dead check grafana data rate}");
0820       for (int ibin = 1; ibin <= hDMAstatus[NFlx]->GetNbinsX(); ibin++)
0821       {
0822         if (hDMAstatus[NFlx]->GetBinContent(ibin) == 0) ptt4->AddText(Form("#color[808]{FELIX %d DMA %d no data}", (ibin - 1) / 2, (ibin - 1) % 2));
0823       }
0824     }
0825 
0826     bulb->SetFillColor(kYellow);
0827     bulb->Draw();
0828     bulbYellow->Draw("same");
0829   }
0830 
0831   for (int i = 0; i < 18; i++)
0832   {
0833     if (status.at(i) == Quality::Bad) q = Quality::Bad;
0834   }
0835 
0836   if (q == Quality::Bad || (bitsetAND & 0x3F) != 0x3F)
0837   {
0838     if (status.at(0) == Quality::Bad)
0839     {
0840       ptt4->AddText("#color[2]{>1/5 of staves in Layer 0 BAD}");
0841     }
0842     if (status.at(1) == Quality::Bad)
0843     {
0844       ptt4->AddText("#color[2]{>1/5 of staves in Layer 1 BAD}");
0845     }
0846     if (status.at(2) == Quality::Bad)
0847     {
0848       ptt4->AddText("#color[2]{>1/5 of staves in Layer 2 BAD}");
0849     }
0850     if (status.at(3) == Quality::Bad)
0851     {
0852       ptt4->AddText("#color[2]{Too many noisy pixels}");
0853     }
0854     if (status.at(17) == Quality::Bad)
0855     {
0856       ptt4->AddText("#color[2]{2 or more DMA dead check grafana data rate}");
0857       for (int ibin = 1; ibin <= hDMAstatus[NFlx]->GetNbinsX(); ibin++)
0858       {
0859         if (hDMAstatus[NFlx]->GetBinContent(ibin) == 0) ptt4->AddText(Form("#color[2]{FELIX %d DMA %d no data}", (ibin - 1) / 2, (ibin - 1) % 2));
0860       }
0861     }
0862     if (status.at(18) == Quality::Bad)
0863     {
0864       ptt4->AddText("#color[2]{Decoder errors in the last 10 events}");
0865     }
0866     if ((bitsetAND & 0x3F) != 0x3F)
0867     {
0868       ptt4->AddText("#color[2]{Some Servers are Offline or in Error}");
0869     }
0870     bulb->SetFillColor(kRed);
0871     bulb->Draw();
0872     bulbRed->Draw("same");
0873   }
0874 
0875   ptt4->Draw();
0876 
0877   TPaveText *tlegend = new TPaveText(.2, .6, .8, .8, "blNDC");
0878   tlegend->SetTextSize(0.04);
0879   tlegend->SetFillColor(0);
0880   tlegend->SetTextAlign(22);
0881   tlegend->SetLineColor(0);
0882   tlegend->SetBorderSize(1);
0883   tlegend->AddText("Legend:");
0884   tlegend->AddText("#color[418]{Green = QA OK}");
0885   tlegend->AddText("#color[808]{Yellow = QA Medium}");
0886   tlegend->AddText("#color[2]{Red = QA Bad}");
0887   tlegend->Draw();
0888 
0889   bool DMA_error[12] = {false};
0890   if (hStrobesDMA[NFlx])
0891   {
0892     for (int iDMA = 0; iDMA < NFlx * 2; iDMA++)
0893     {
0894       if (lastStrobes[iDMA] > static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA + 1)))
0895       {
0896         lastStrobes[iDMA] = static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA + 1));
0897         DMA_error[iDMA] = false;
0898       }
0899       else if (lastStrobes[iDMA] == static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA + 1)))
0900       {
0901         DMA_error[iDMA] = true;
0902       }
0903       else if (lastStrobes[iDMA] < static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA + 1)))
0904       {
0905         DMA_error[iDMA] = false;
0906         lastStrobes[iDMA] = static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA + 1));
0907       }
0908     }
0909   }
0910 
0911   Pad[padID]->cd(8);
0912   TPaveText *pt = new TPaveText(.05, .1, .95, .8);
0913   pt->AddText("Online Monitoring Server Status");
0914   for (int iFelix = 0; iFelix < NFlx; iFelix++)
0915   {
0916     std::string serverStatus = "OM server " + std::to_string(iFelix);
0917     if ((bitsetOR & (1 << iFelix)) == 1 << iFelix && (bitsetAND & (1 << iFelix)) == 1 << iFelix)
0918     {
0919       serverStatus += " #color[418]{ONLINE} ";
0920       serverStatus += (DMA_error[2 * iFelix]) ? "#color[2]{" : "#color[418]{";
0921       serverStatus += std::to_string(static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(2 * iFelix + 1)));
0922       serverStatus += "}  ";
0923       serverStatus += (DMA_error[2 * iFelix + 1]) ? "#color[2]{" : "#color[418]{";
0924       serverStatus += std::to_string(static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(2 * iFelix + 2)));
0925       serverStatus += "}";
0926     }
0927     if ((bitsetOR & (1 << iFelix)) == 0 && (bitsetAND & (1 << iFelix)) == 0)
0928     {
0929       serverStatus += " #color[2]{OFFLINE}";
0930     }
0931     if ((bitsetOR & (1 << iFelix)) == 1 << iFelix && (bitsetAND & (1 << iFelix)) == 0)
0932     {
0933       serverStatus += " #color[2]{ERROR}";
0934     }
0935     auto text = pt->AddText(serverStatus.c_str());
0936     text->SetTextAlign(12);
0937   }
0938   pt->Draw();
0939   PublishStatistics(canvasID, cl);
0940   TC[canvasID]->SetEditable(false);
0941   return returnCode < 0 ? -1 : 0;
0942 }
0943 
0944 int MvtxMonDraw::DrawFEE(const std::string & /* what */)
0945 {
0946   OnlMonClient *cl = OnlMonClient::instance();
0947   const int canvasID = 2;
0948   const int padID = 2;
0949 
0950   // TH2I *mTriggerVsFeeId[NFlx + 1] = {nullptr};
0951   // TH1I *mTrigger[NFlx + 1] = {nullptr};
0952   TH2I *FHR_ErrorVsFeeid[NFlx + 1] = {nullptr};
0953   TH2I *mLaneStatus[3][NFlx + 1] = {{nullptr}};
0954   TH2I *mLaneStatusCumulative[3][NFlx + 1] = {{nullptr}};
0955   // TH1I *mLaneStatusSummary[3][NFlx + 1] = {{nullptr}};
0956   // TH1I *mLaneStatusSummaryIB[NFlx + 1] = {nullptr};
0957   TH1D *mvtxmon_mGeneralErrorPlots[NFlx + 1] = {nullptr};
0958   TH2D *mvtxmon_mGeneralErrorFile[NFlx + 1] = {nullptr};
0959   TH1I *hRDHErrors[NFlx + 1] = {nullptr};
0960 
0961   for (int iFelix = 0; iFelix < NFlx; iFelix++)
0962   {
0963     // mTriggerVsFeeId[iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_FEE_TriggerVsFeeid"));
0964     // mTrigger[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_FEE_TriggerFlag"));
0965     FHR_ErrorVsFeeid[iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "FHR_ErrorVsFeeid"));
0966     // mLaneStatusSummaryIB[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "FEE_LaneStatusSummary"));
0967     mvtxmon_mGeneralErrorPlots[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_DecErrors"));
0968     mvtxmon_mGeneralErrorFile[iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_DecErrorsEndpoint"));
0969     for (int i = 0; i < 3; i++)
0970     {
0971       mLaneStatus[i][iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FEE_LaneStatus_Flag_%s", mLaneStatusFlag[i].c_str())));
0972       mLaneStatusCumulative[i][iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FEE_LaneStatusFromSOX_Flag_%s", mLaneStatusFlag[i].c_str())));
0973       // mLaneStatusSummary[i][iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FEE_LaneStatusSummary_Layer_%i", i)));
0974     }
0975     hRDHErrors[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "RDHErrors_hfeeRDHErrors"));
0976   }
0977 
0978   for (int i = 0; i < 3; i++)
0979   {
0980     MergeServers<TH2I *>(mLaneStatus[i]);
0981     MergeServers<TH2I *>(mLaneStatusCumulative[i]);
0982     // MergeServers<TH1I *>(mLaneStatusSummary[i]);
0983   }
0984   // MergeServers<TH2I *>(mTriggerVsFeeId);
0985   // MergeServers<TH1I *>(mTrigger);
0986   //  MergeServers<TH2I*>(mLaneInfo);
0987   MergeServers<TH2I *>(FHR_ErrorVsFeeid);
0988   MergeServers<TH1D *>(mvtxmon_mGeneralErrorPlots);
0989   MergeServers<TH2D *>(mvtxmon_mGeneralErrorFile);
0990   MergeServers<TH1I *>(hRDHErrors);
0991 
0992   if (!gROOT->FindObject("MvtxMon_FEE"))
0993   {
0994     MakeCanvas("MvtxMon_FEE");
0995   }
0996 
0997   TC[canvasID]->SetEditable(true);
0998   TC[canvasID]->Clear("D");
0999   Pad[padID]->Divide(4, 3);
1000 
1001   for (int i = 0; i < 3; i++)
1002   {
1003     if (mLaneStatus[i][NFlx])
1004     {
1005       mLaneStatus[i][NFlx]->GetXaxis()->SetTitleSize(0.055);
1006       mLaneStatus[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1007       mLaneStatus[i][NFlx]->GetYaxis()->SetTitleSize(0.06);
1008       mLaneStatus[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1009       mLaneStatus[i][NFlx]->GetYaxis()->SetLabelSize(0.05);
1010     }
1011     if (mLaneStatusCumulative[i][NFlx])
1012     {
1013       mLaneStatusCumulative[i][NFlx]->GetXaxis()->SetTitleSize(0.055);
1014       mLaneStatusCumulative[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1015       mLaneStatusCumulative[i][NFlx]->GetYaxis()->SetTitleSize(0.06);
1016       mLaneStatusCumulative[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1017       mLaneStatusCumulative[i][NFlx]->GetYaxis()->SetLabelSize(0.05);
1018     }
1019   }
1020   /*  if (mLaneStatusSummary[i][NFlx])
1021     {
1022       mLaneStatusSummary[i][NFlx]->GetXaxis()->SetLabelSize(0.07);
1023       mLaneStatusSummary[i][NFlx]->GetYaxis()->SetTitleSize(0.06);
1024       mLaneStatusSummary[i][NFlx]->GetYaxis()->SetLabelSize(0.05);
1025       mLaneStatusSummary[i][NFlx]->GetYaxis()->SetTitleOffset(0.9);
1026     }
1027   }
1028   if (mLaneStatusSummaryIB[NFlx])
1029   {
1030     mLaneStatusSummaryIB[NFlx]->GetXaxis()->SetLabelSize(0.07);
1031     mLaneStatusSummaryIB[NFlx]->GetYaxis()->SetTitleSize(0.06);
1032     mLaneStatusSummaryIB[NFlx]->GetYaxis()->SetLabelSize(0.05);
1033     mLaneStatusSummaryIB[NFlx]->GetYaxis()->SetTitleOffset(0.9);
1034   }*/
1035   /*if (mTriggerVsFeeId[NFlx])
1036   {
1037     mTriggerVsFeeId[NFlx]->GetXaxis()->SetTitleSize(0.055);
1038     mTriggerVsFeeId[NFlx]->GetXaxis()->SetTitleOffset(0.75);
1039     mTriggerVsFeeId[NFlx]->GetYaxis()->SetTitleOffset(1.2);
1040     mTriggerVsFeeId[NFlx]->GetYaxis()->SetTitleSize(0.06);
1041     mTriggerVsFeeId[NFlx]->GetYaxis()->SetLabelSize(0.06);
1042     mTriggerVsFeeId[NFlx]->GetXaxis()->SetLabelSize(0.05);
1043   }
1044   if (mTrigger[NFlx])
1045   {
1046     mTrigger[NFlx]->GetXaxis()->SetTitleSize(0.055);
1047     mTrigger[NFlx]->GetXaxis()->SetTitleOffset(0.85);
1048     mTrigger[NFlx]->GetYaxis()->SetTitleSize(0.06);
1049     mTrigger[NFlx]->GetYaxis()->SetLabelSize(0.06);
1050     mTrigger[NFlx]->GetXaxis()->SetLabelSize(0.05);
1051     mTrigger[NFlx]->GetYaxis()->SetTitleOffset(0.85);
1052   }*/
1053 
1054   TPaveText *tlayer[3] = {nullptr};
1055 
1056   for (int i = 0; i < 3; i++)
1057   {
1058     double shift[3] = {0, 0.25, 0.55};
1059     tlayer[i] = new TPaveText(.14 + shift[i], .87, .24 + shift[i], .93, "blNDC");
1060     tlayer[i]->SetTextSize(0.05);
1061     tlayer[i]->SetFillColor(0);
1062     tlayer[i]->SetTextAlign(22);
1063     tlayer[i]->SetLineColor(0);
1064     tlayer[i]->SetBorderSize(1);
1065     tlayer[i]->AddText(Form("Layer %d", i));
1066   }
1067   /*
1068     Pad[padID]->cd(3)->SetTopMargin(0.16);
1069     Pad[padID]->cd(4)->SetTopMargin(0.16);
1070     Pad[padID]->cd(4)->SetTopMargin(0.145);
1071     Pad[padID]->cd(7)->SetTopMargin(0.16);
1072     Pad[padID]->cd(8)->SetTopMargin(0.16);
1073     Pad[padID]->cd(11)->SetTopMargin(0.16);
1074     Pad[padID]->cd(12)->SetTopMargin(0.16);*/
1075 
1076   int returnCode = 0;
1077   // Pad[padID]->cd(1)->SetLeftMargin(0.16);
1078   returnCode += PublishHistogram(Pad[padID], 9, mvtxmon_mGeneralErrorPlots[NFlx]);
1079   returnCode += PublishHistogram(Pad[padID], 10, mvtxmon_mGeneralErrorFile[NFlx], "lcol");
1080   returnCode += PublishHistogram(Pad[padID], 11, FHR_ErrorVsFeeid[NFlx], "lcol");
1081   returnCode += PublishHistogram(Pad[padID], 12, hRDHErrors[NFlx], "lcol");
1082   // returnCode += PublishHistogram(Pad[padID], 1, mTriggerVsFeeId[NFlx], "lcol");
1083   // returnCode += PublishHistogram(Pad[padID], 5, mTrigger[NFlx]);
1084   //  returnCode += PublishHistogram(Pad[9],3,mLaneInfo[NFlx]);
1085   returnCode += PublishHistogram(Pad[padID], 1, mLaneStatus[0][NFlx], "lcol");
1086   /*for (auto &i : tlayer)
1087   {
1088     i->Draw();
1089   }*/
1090   returnCode += PublishHistogram(Pad[padID], 2, mLaneStatus[1][NFlx], "lcol");
1091   /*for (auto &i : tlayer)
1092   {
1093     i->Draw();
1094   }*/
1095   returnCode += PublishHistogram(Pad[padID], 3, mLaneStatus[2][NFlx], "lcol");
1096   /*for (auto &i : tlayer)
1097   {
1098     i->Draw();
1099   }*/
1100   returnCode += PublishHistogram(Pad[padID], 5, mLaneStatusCumulative[0][NFlx], "lcol");
1101   /*for (auto &i : tlayer)
1102   {
1103     i->Draw();
1104   }*/
1105   returnCode += PublishHistogram(Pad[padID], 6, mLaneStatusCumulative[1][NFlx], "lcol");
1106   /*for (auto &i : tlayer)
1107   {
1108     i->Draw();
1109   }*/
1110   returnCode += PublishHistogram(Pad[padID], 7, mLaneStatusCumulative[2][NFlx], "lcol");
1111   /*for (auto &i : tlayer)
1112   {
1113     i->Draw();
1114   }*/
1115   /*returnCode += PublishHistogram(Pad[padID], 2, mLaneStatusSummary[0][NFlx]);
1116   returnCode += PublishHistogram(Pad[padID], 6, mLaneStatusSummary[1][NFlx]);
1117   returnCode += PublishHistogram(Pad[padID], 10, mLaneStatusSummary[2][NFlx]);
1118   returnCode += PublishHistogram(Pad[padID], 9, mLaneStatusSummaryIB[NFlx]);
1119 */
1120   PublishStatistics(canvasID, cl);
1121   TC[canvasID]->SetEditable(false);
1122   return returnCode < 0 ? -1 : 0;
1123 }
1124 
1125 int MvtxMonDraw::DrawOCC(const std::string & /* what */)
1126 {
1127   OnlMonClient *cl = OnlMonClient::instance();
1128   const int canvasID = 3;
1129   const int padID = 3;
1130 
1131   TH1D *hOccupancyPlot[3][NFlx + 1] = {{nullptr}};
1132   TH2D *hChipStaveOccupancy[3][NFlx + 1] = {{nullptr}};
1133   TH1D *mvtxmon_ChipStave1D[NFlx + 1] = {nullptr};
1134   TH1D *mvtxmon_ChipFiredHis[NFlx + 1] = {nullptr};
1135   TH1I *hChipStrobes[NFlx + 1] = {nullptr};
1136   TH1I *hChipL1[NFlx + 1] = {nullptr};
1137 
1138   for (int aLayer = 0; aLayer < 3; aLayer++)
1139   {
1140     for (int iFelix = 0; iFelix < NFlx; iFelix++)
1141     {
1142       hOccupancyPlot[aLayer][iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("OCC_Occupancy1D_Layer%d", aLayer)));
1143       hChipStaveOccupancy[aLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("OCC_OccupancyChipStave_Layer_%d", aLayer)));
1144     }
1145   }
1146 
1147   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1148   {
1149     mvtxmon_ChipStave1D[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_ChipStave1D"));
1150     mvtxmon_ChipFiredHis[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_ChipFiredFLX"));
1151     hChipStrobes[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_hChipStrobes"));
1152     hChipL1[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_ChipL1"));
1153   }
1154 
1155   for (int i = 0; i < 3; i++)
1156   {
1157     MergeServers<TH1D *>(hOccupancyPlot[i]);
1158     MergeServers<TH2D *>(hChipStaveOccupancy[i]);
1159   }
1160 
1161   TH2D *hChipStaveOccupancy_low[3] = {nullptr};
1162 
1163   for (int i = 0; i < 3; i++)
1164   {
1165     if (hOccupancyPlot[i][NFlx])
1166     {
1167       hOccupancyPlot[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1168       hOccupancyPlot[i][NFlx]->GetXaxis()->SetTitleSize(0.05);
1169       hOccupancyPlot[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1170       hOccupancyPlot[i][NFlx]->GetYaxis()->SetLabelSize(0.045);
1171       hOccupancyPlot[i][NFlx]->GetYaxis()->SetTitleSize(0.05);
1172       hOccupancyPlot[i][NFlx]->GetYaxis()->SetTitleOffset(1);
1173       hChipStaveOccupancy[i][NFlx]->SetMinimum(0);
1174     }
1175     if (hChipStaveOccupancy[i][NFlx])
1176     {
1177       hChipStaveOccupancy[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1178       hChipStaveOccupancy[i][NFlx]->GetXaxis()->SetTitleSize(0.05);
1179       hChipStaveOccupancy[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1180       hChipStaveOccupancy[i][NFlx]->GetYaxis()->SetLabelSize(0.06);
1181       hChipStaveOccupancy[i][NFlx]->GetYaxis()->SetTitleSize(0.05);
1182       hChipStaveOccupancy[i][NFlx]->GetYaxis()->SetTitleOffset(0.7);
1183       hChipStaveOccupancy[i][NFlx]->SetContour(100);
1184 
1185       hChipStaveOccupancy_low[i] = (TH2D *) (hChipStaveOccupancy[i][NFlx])->Clone(Form("hChipStaveOccupancy_low_%d", i));
1186       TString tmp = "Chip Occupancy < 1\%";
1187       hChipStaveOccupancy_low[i]->SetTitle(tmp + Form(" of average occupancy in layer %d", i));
1188     }
1189   }
1190 
1191   MergeServers<TH1D *>(mvtxmon_ChipStave1D);
1192   MergeServers<TH1D *>(mvtxmon_ChipFiredHis);
1193   MergeServers<TH1I *>(hChipStrobes);
1194   MergeServers<TH1I *>(hChipL1);
1195 
1196   if (mvtxmon_ChipStave1D[NFlx])
1197   {
1198     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetLabelSize(0.05);
1199     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleSize(0.055);
1200     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleOffset(0.75);
1201     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetLabelSize(0.045);
1202     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleSize(0.06);
1203     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleOffset(1.2);
1204   }
1205 
1206   if (mvtxmon_ChipFiredHis[NFlx])
1207   {
1208     mvtxmon_ChipFiredHis[NFlx]->GetXaxis()->SetLabelSize(0.05);
1209     mvtxmon_ChipFiredHis[NFlx]->GetXaxis()->SetTitleSize(0.055);
1210     mvtxmon_ChipFiredHis[NFlx]->GetXaxis()->SetTitleOffset(0.75);
1211     mvtxmon_ChipFiredHis[NFlx]->GetYaxis()->SetLabelSize(0.06);
1212     mvtxmon_ChipFiredHis[NFlx]->GetYaxis()->SetTitleSize(0.06);
1213     mvtxmon_ChipFiredHis[NFlx]->GetYaxis()->SetTitleOffset(1.2);
1214   }
1215 
1216   double avr_occ[3] = {0};
1217 
1218   for (int iLayer = 0; iLayer < 3; iLayer++)
1219   {
1220     for (int iStave = 0; iStave < NStaves[iLayer]; iStave++)
1221     {
1222       for (int iChip = 0; iChip < 9; iChip++)
1223       {
1224         // double occ = hChipStaveOccupancy[iLayer][NFlx]->GetBinContent(iChip+1,iStave+1)/(hChipStrobes[NFlx]->GetBinContent((StaveBoundary[iLayer]+iStave)*9+iChip+1)*1024*512);
1225         double occ = hChipStaveOccupancy[iLayer][NFlx]->GetBinContent(iChip + 1, iStave + 1) / (hChipStrobes[NFlx]->GetBinContent((StaveBoundary[iLayer] + iStave) * 9 + iChip + 1) * 1024 * 512);
1226         if (occ > 10e-50)
1227         {
1228           hChipStaveOccupancy[iLayer][NFlx]->SetBinContent(iChip + 1, iStave + 1, occ);
1229         }
1230         if (occ > 10e-50)
1231         {
1232           avr_occ[iLayer] += occ;
1233         }
1234       }
1235     }
1236   }
1237 
1238   for (int iLayer = 0; iLayer < 3; iLayer++)
1239   {
1240     avr_occ[iLayer] /= (NStaves[iLayer] * 9);
1241     for (int iStave = 0; iStave < NStaves[iLayer]; iStave++)
1242     {
1243       for (int iChip = 0; iChip < 9; iChip++)
1244       {
1245         double occ = hChipStaveOccupancy[iLayer][NFlx]->GetBinContent(iChip + 1, iStave + 1);
1246         if (occ < 0.01 * avr_occ[iLayer])
1247         {
1248           hChipStaveOccupancy_low[iLayer]->SetBinContent(iChip + 1, iStave + 1, 1);
1249         }
1250         else
1251         {
1252           hChipStaveOccupancy_low[iLayer]->SetBinContent(iChip + 1, iStave + 1, 0);
1253         }
1254       }
1255     }
1256   }
1257 
1258   if (!gROOT->FindObject("MvtxMon_OCC"))
1259   {
1260     MakeCanvas("MvtxMon_OCC");
1261   }
1262 
1263   TC[canvasID]->SetEditable(true);
1264   TC[canvasID]->Clear("D");
1265   Pad[padID]->Divide(4, 3);
1266   Pad[padID]->cd(1)->SetLogy();
1267   Pad[padID]->cd(2)->SetLogy();
1268   Pad[padID]->cd(3)->SetLogy();
1269   Pad[padID]->cd(5)->SetRightMargin(0.15);
1270   Pad[padID]->cd(6)->SetRightMargin(0.15);
1271   Pad[padID]->cd(7)->SetRightMargin(0.15);
1272 
1273   // Pad[padID]->cd(1)->SetLogx();
1274   //[padID]->cd(2)->SetLogx();
1275   // Pad[padID]->cd(3)->SetLogx();
1276 
1277   hChipStaveOccupancy[0][NFlx]->GetZaxis()->SetTitle("");
1278   hChipStaveOccupancy[1][NFlx]->GetZaxis()->SetTitle("");
1279   hChipStaveOccupancy[2][NFlx]->GetZaxis()->SetTitle("");
1280 
1281   hChipStrobes[NFlx]->SetTitle("Chip Strobes (L1 triggers) vs Chip*Stave");
1282   hChipStrobes[NFlx]->GetYaxis()->SetTitle("Number of strobes");
1283 
1284   int returnCode = 0;
1285   returnCode += PublishHistogram(Pad[padID], 1, hOccupancyPlot[0][NFlx]);
1286   returnCode += PublishHistogram(Pad[padID], 2, hOccupancyPlot[1][NFlx]);
1287   returnCode += PublishHistogram(Pad[padID], 3, hOccupancyPlot[2][NFlx]);
1288   returnCode += PublishHistogram(Pad[padID], 5, hChipStaveOccupancy[0][NFlx], "colz");
1289   returnCode += PublishHistogram(Pad[padID], 6, hChipStaveOccupancy[1][NFlx], "colz");
1290   returnCode += PublishHistogram(Pad[padID], 7, hChipStaveOccupancy[2][NFlx], "colz");
1291   returnCode += PublishHistogram(Pad[padID], 9, hChipStaveOccupancy_low[0], "col");
1292   returnCode += PublishHistogram(Pad[padID], 10, hChipStaveOccupancy_low[1], "col");
1293   returnCode += PublishHistogram(Pad[padID], 11, hChipStaveOccupancy_low[2], "col");
1294   returnCode += PublishHistogram(Pad[padID], 4, mvtxmon_ChipStave1D[NFlx]);
1295   returnCode += PublishHistogram(Pad[padID], 8, mvtxmon_ChipFiredHis[NFlx]);
1296   returnCode += PublishHistogram(Pad[padID], 12, hChipStrobes[NFlx]);
1297 
1298   // for( int i = 1; i<= hChipL1[NFlx]->GetNbinsX();i++) std::cout<<hChipL1[NFlx]->GetBinContent(i)<<" ";
1299 
1300   Float_t rightmax = 2 * hChipL1[NFlx]->GetMaximum();
1301   Float_t scale = hChipStrobes[NFlx]->GetMaximum() / rightmax;
1302   hChipL1[NFlx]->SetLineColor(kRed);
1303   hChipL1[NFlx]->Scale(scale);
1304   // std::cout<<rightmax<<" "<<hChipStrobes[NFlx]->GetMaximum()<<" "<<scale<<std::endl;
1305   returnCode += PublishHistogram(Pad[padID], 12, hChipL1[NFlx], "same hist");
1306 
1307   TGaxis *axis = new TGaxis(48 * 9, 0, 48 * 9, hChipStrobes[NFlx]->GetMaximum(), 0, rightmax, 510, "+L");
1308   axis->SetLineColor(kRed);
1309   axis->SetLabelColor(kRed);
1310   axis->SetLabelFont(42);
1311   axis->SetTitleFont(42);
1312   axis->SetTitleColor(kRed);
1313   axis->SetTitle("Number of L1 triggers");
1314   axis->Draw();
1315 
1316   TPaveText *pt = new TPaveText(6, 12, 8.5, 13);
1317   pt->SetBorderSize(0);
1318   pt->SetFillStyle(0);
1319   TText *t1 = pt->AddText("Not saved in .root");
1320   t1->SetTextColor(kRed);
1321   Pad[padID]->cd(9);
1322   pt->Draw();
1323   Pad[padID]->cd(10);
1324   pt->Draw();
1325   Pad[padID]->cd(11);
1326   pt->Draw();
1327 
1328   PublishStatistics(canvasID, cl);
1329   TC[canvasID]->SetEditable(false);
1330   return returnCode < 0 ? -1 : 0;
1331 }
1332 
1333 int MvtxMonDraw::DrawFHR(const std::string & /* what */)
1334 {
1335   OnlMonClient *cl = OnlMonClient::instance();
1336   const int canvasID = 4;
1337   const int padID = 4;
1338 
1339   TH2D *mDeadChipPos[3][NFlx + 1] = {{nullptr}};
1340   // TH2D *mAliveChipPos[3][NFlx + 1] = {{nullptr}};
1341   //  TH2D* mChipStaveOccupancy[3][NFlx];
1342   // TH1D *mOccupancyPlot[3][NFlx + 1] = {{nullptr}};
1343 
1344   TH2I *mErrorVsFeeid[NFlx + 1] = {nullptr};
1345   TH2Poly *mGeneralOccupancy[NFlx + 1] = {nullptr};
1346   TH2Poly *mGeneralNoisyPixel[NFlx + 1] = {nullptr};
1347   TH2D *mTotalDeadChipPos[NFlx + 1] = {nullptr};
1348   // TH2D *mTotalAliveChipPos[NFlx + 1] = {nullptr};
1349   TH1D *mvtxmon_EvtHitChip[NFlx + 1] = {nullptr};
1350   TH1D *mvtxmon_EvtHitDis[NFlx + 1] = {nullptr};
1351 
1352   TH1I *mRCDAQevt[NFlx + 1] = {nullptr};
1353 
1354   TH2D *mChipStaveNoisy[3][NFlx + 1]{{nullptr}};
1355 
1356   int nFLX[3] = {0};
1357 
1358   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1359   {
1360     mErrorVsFeeid[iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_ErrorVsFeeid"));
1361     mGeneralOccupancy[iFelix] = dynamic_cast<TH2Poly *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_Occupancy"));
1362     mGeneralNoisyPixel[iFelix] = dynamic_cast<TH2Poly *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_Noisy_Pixel"));
1363     mTotalDeadChipPos[iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_Occupancy_TotalDeadChipPos"));
1364     // mTotalAliveChipPos[iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_Occupancy_TotalAliveChipPos"));
1365     mvtxmon_EvtHitChip[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_HitChipPerStrobe"));
1366     mvtxmon_EvtHitDis[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_HitFLXPerStrobe"));
1367     mRCDAQevt[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "RCDAQ_evt"));
1368     for (int mLayer = 0; mLayer < 3; mLayer++)
1369     {
1370       mDeadChipPos[mLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("MVTXMON_Occupancy_Layer%d_Layer%dDeadChipPos", mLayer, mLayer)));
1371       if (mDeadChipPos[mLayer][iFelix])
1372       {
1373         nFLX[mLayer]++;
1374       }
1375       // mAliveChipPos[mLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("MVTXMON_Occupancy_Layer%d_Layer%dAliveChipPos", mLayer, mLayer)));
1376       //  mChipStaveOccupancy[mLayer][iFelix] =  dynamic_cast<TH2D*>(cl->getHisto(Form("MVTXMON/Occupancy/Layer%d/Layer%dChipStaveC", mLayer, mLayer)));
1377 
1378       mChipStaveNoisy[mLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FHR_NoisyChipStave_Layer%d", mLayer)));
1379     }
1380   }
1381 
1382   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1383   {
1384     for (int mLayer = 0; mLayer < 3; mLayer++)
1385     {
1386       // if (mAliveChipPos[mLayer][iFelix] && mRCDAQevt[iFelix])
1387       //{
1388       //   mAliveChipPos[mLayer][iFelix]->Scale(1. / mRCDAQevt[iFelix]->Integral());
1389       // }
1390 
1391       if (mChipStaveNoisy[mLayer][iFelix] && mRCDAQevt[iFelix])
1392       {
1393         mChipStaveNoisy[mLayer][iFelix]->Scale(1. / mRCDAQevt[iFelix]->Integral());
1394       }
1395     }
1396   }
1397 
1398   for (int mLayer = 0; mLayer < 3; mLayer++)
1399   {
1400     MergeServers<TH2D *>(mDeadChipPos[mLayer]);
1401     // MergeServers<TH2D *>(mAliveChipPos[mLayer]);
1402     MergeServers<TH2D *>(mChipStaveNoisy[mLayer]);
1403     if (mDeadChipPos[mLayer][NFlx])
1404     {
1405       mDeadChipPos[mLayer][NFlx]->SetMinimum(0);
1406       mDeadChipPos[mLayer][NFlx]->SetMaximum(1);
1407     }
1408     /*if(mAliveChipPos[mLayer][NFlx]){
1409       mAliveChipPos[mLayer][NFlx]->SetMinimum(0);
1410       mAliveChipPos[mLayer][NFlx]->SetMaximum(1);
1411     }*/
1412   }
1413 
1414   MergeServers<TH2I *>(mErrorVsFeeid);
1415   MergeServers<TH2Poly *>(mGeneralOccupancy);
1416   MergeServers<TH2Poly *>(mGeneralNoisyPixel);
1417   MergeServers<TH2D *>(mTotalDeadChipPos);
1418   // MergeServers<TH2D *>(mTotalAliveChipPos);
1419   MergeServers<TH1D *>(mvtxmon_EvtHitChip);
1420   MergeServers<TH1D *>(mvtxmon_EvtHitDis);
1421   MergeServers<TH1I *>(mRCDAQevt);
1422 
1423   if (mTotalDeadChipPos[NFlx])
1424   {
1425     mTotalDeadChipPos[NFlx]->SetMinimum(0);
1426     mTotalDeadChipPos[NFlx]->SetMaximum(1);
1427   }
1428   /* if(mTotalAliveChipPos[NFlx]){
1429      mTotalAliveChipPos[NFlx]->SetMinimum(0);
1430      mTotalAliveChipPos[NFlx]->SetMaximum(1);
1431    }*/
1432 
1433   for (int mLayer = 0; mLayer < 3; mLayer++)
1434   {
1435     if (mDeadChipPos[mLayer][NFlx])
1436     {
1437       for (int binx = 0; binx < mDeadChipPos[mLayer][NFlx]->GetNbinsX(); binx++)
1438       {
1439         for (int biny = 0; biny < mDeadChipPos[mLayer][NFlx]->GetNbinsY(); biny++)
1440         {
1441           mDeadChipPos[mLayer][NFlx]->SetBinContent(binx + 1, biny + 1, mDeadChipPos[mLayer][NFlx]->GetBinContent(binx + 1, biny + 1) - nFLX[mLayer] + 1);
1442         }
1443       }
1444     }
1445   }
1446 
1447   if (!gROOT->FindObject("MvtxMon_FHR"))
1448   {
1449     MakeCanvas("MvtxMon_FHR");
1450   }
1451 
1452   TC[canvasID]->SetEditable(true);
1453   TC[canvasID]->Clear("D");
1454   Pad[padID]->Divide(3, 3);
1455 
1456   int returnCode = 0;
1457   // returnCode += PublishHistogram(Pad[padID],1,mErrorVsFeeid[0]);
1458   // returnCode += PublishHistogram(Pad[padID],6,mGeneralOccupancy[NFlx],"COLZ");
1459   returnCode += PublishHistogram(Pad[padID], 3, mGeneralNoisyPixel[NFlx], "COLZ", 0);
1460   returnCode += PublishHistogram(Pad[padID], 1, mDeadChipPos[0][NFlx], "COL");
1461   returnCode += PublishHistogram(Pad[padID], 4, mDeadChipPos[1][NFlx], "COL");
1462   returnCode += PublishHistogram(Pad[padID], 7, mDeadChipPos[2][NFlx], "COL");
1463   // returnCode += PublishHistogram(Pad[padID], 2, mAliveChipPos[0][NFlx], "COLZ");
1464   // returnCode += PublishHistogram(Pad[padID], 7, mAliveChipPos[1][NFlx], "COLZ");
1465   // sreturnCode += PublishHistogram(Pad[padID], 12, mAliveChipPos[2][NFlx], "COLZ");
1466   //  returnCode += PublishHistogram<TH2D*>(TC[canvasID],10,mChipStaveOccupancy[0][0]);
1467   //  returnCode += PublishHistogram<TH2D*>(TC[canvasID],11,mChipStaveOccupancy[1][0]);
1468   //   returnCode += PublishHistogram<TH2D*>(TC[canvasID],12,mChipStaveOccupancy[2][0]);
1469   returnCode += PublishHistogram(Pad[padID], 2, mChipStaveNoisy[0][NFlx], "COLZ");
1470   returnCode += PublishHistogram(Pad[padID], 5, mChipStaveNoisy[1][NFlx], "COLZ");
1471   returnCode += PublishHistogram(Pad[padID], 8, mChipStaveNoisy[2][NFlx], "COLZ");
1472   // returnCode += PublishHistogram(Pad[padID], 3, mOccupancyPlot[0][NFlx]);
1473   // returnCode += PublishHistogram(Pad[padID], 7, mOccupancyPlot[1][NFlx]);
1474   // returnCode += PublishHistogram(Pad[padID], 11, mOccupancyPlot[2][NFlx]);
1475 
1476   PublishHistogram(Pad[padID], 6, mvtxmon_EvtHitChip[NFlx]);
1477   PublishHistogram(Pad[padID], 9, mvtxmon_EvtHitDis[NFlx]);
1478 
1479   // returnCode += PublishHistogram(Pad[11],16,mTotalDeadChipPos[NFlx],"COL");
1480   // returnCode += PublishHistogram(Pad[11],17,mTotalAliveChipPos[NFlx],"COL");
1481 
1482   PublishStatistics(canvasID, cl);
1483   TC[canvasID]->SetEditable(false);
1484   return returnCode < 0 ? -1 : 0;
1485 }
1486 
1487 int MvtxMonDraw::SavePlot(const std::string &what, const std::string &type)
1488 {
1489   OnlMonClient *cl = OnlMonClient::instance();
1490   int iret = Draw(what);
1491   if (iret)  // on error no png files please
1492   {
1493     return iret;
1494   }
1495   int icnt = 0;
1496   for (TCanvas *canvas : TC)
1497   {
1498     if (canvas == nullptr)
1499     {
1500       continue;
1501     }
1502     icnt++;
1503     std::string filename = ThisName + "_" + std::to_string(icnt) + "_" +
1504                            std::to_string(cl->RunNumber()) + "." + type;
1505     cl->CanvasToPng(canvas, filename);
1506   }
1507   return 0;
1508 }
1509 
1510 int MvtxMonDraw::MakeHtml(const std::string &what)
1511 {
1512   int iret = Draw(what);
1513   if (iret)  // on error no html output please
1514   {
1515     return iret;
1516   }
1517 
1518   OnlMonClient *cl = OnlMonClient::instance();
1519 
1520   int icnt = 0;
1521   for (TCanvas *canvas : TC)
1522   {
1523     if (canvas == nullptr)
1524     {
1525       continue;
1526     }
1527     icnt++;
1528     // Register the canvas png file to the menu and produces the png file.
1529     std::string pngfile = cl->htmlRegisterPage(*this, canvas->GetTitle(), std::to_string(icnt), "png");
1530     cl->CanvasToPng(canvas, pngfile);
1531   }
1532   // Now register also EXPERTS html pages, under the EXPERTS subfolder.
1533 
1534   // std::string logfile = cl->htmlRegisterPage(*this, "EXPERTS/Log", "log", "html");
1535   // std::ofstream out(logfile.c_str());
1536   // out << "<HTML><HEAD><TITLE>Log file for run " << cl->RunNumber()
1537   //     << "</TITLE></HEAD>" << std::endl;
1538   // out << "<P>Some log file output would go here." << std::endl;
1539   // out.close();
1540 
1541   // std::string status = cl->htmlRegisterPage(*this, "EXPERTS/Status", "status", "html");
1542   // std::ofstream out2(status.c_str());
1543   // out2 << "<HTML><HEAD><TITLE>Status file for run " << cl->RunNumber()
1544   //      << "</TITLE></HEAD>" << std::endl;
1545   // out2 << "<P>Some status output would go here." << std::endl;
1546   // out2.close();
1547   // cl->SaveLogFile(*this);
1548   return 0;
1549 }
1550 
1551 int MvtxMonDraw::DrawHistory(const std::string & /* what */)
1552 {
1553   const int canvasID = 5;
1554   const int padID = 5;
1555 
1556   int iret[NFlx] = {0, 0, 0, 0, 0, 0};
1557   // you need to provide the following vectors
1558   // which are filled from the db
1559   std::vector<float> var[NFlx];
1560   std::vector<float> varerr[NFlx];
1561   std::vector<time_t> timestamp[NFlx];
1562   std::vector<int> runnumber[NFlx];
1563   std::string varname = "n_events";
1564   // this sets the time range from whihc values should be returned
1565   time_t begin = 0;            // begin of time (1.1.1970)
1566   time_t end = time(nullptr);  // current time (right NOW)
1567 
1568   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1569   {
1570     iret[iFelix] = dbvars[iFelix]->GetVar(begin, end, varname, timestamp[iFelix], runnumber[iFelix], var[iFelix], varerr[iFelix]);
1571     if (iret[iFelix])
1572     {
1573       std::cout << __PRETTY_FUNCTION__ << " Error in db access: FELIX " << iFelix << std::endl;
1574       // return iret;
1575     }
1576   }
1577 
1578   if (!gROOT->FindObject("MvtxMon3"))
1579   {
1580     MakeCanvas("MvtxMon3");
1581   }
1582   TC[canvasID]->SetEditable(true);
1583   TC[canvasID]->Clear("D");
1584   Pad[padID]->Divide(3, 2);
1585 
1586   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1587   {
1588     // timestamps come sorted in ascending order
1589     float *x = new float[var[iFelix].size()];
1590     float *y = new float[var[iFelix].size()];
1591     float *ex = new float[var[iFelix].size()];
1592     float *ey = new float[var[iFelix].size()];
1593     int n = var[iFelix].size();
1594     for (unsigned int i = 0; i < var[iFelix].size(); i++)
1595     {
1596       //       std::cout << "timestamp: " << ctime(&timestamp[i])
1597       //       << ", run: " << runnumber[i]
1598       //       << ", var: " << var[i]
1599       //       << ", varerr: " << varerr[i]
1600       //       << std::endl;
1601       x[i] = timestamp[iFelix][i] - TimeOffsetTicks;
1602       y[i] = var[iFelix][i];
1603       ex[i] = 0;
1604       ey[i] = varerr[iFelix][i];
1605     }
1606     Pad[padID]->cd(iFelix + 1);
1607     if (gr[iFelix])
1608     {
1609       delete gr[iFelix];
1610     }
1611     gr[iFelix] = new TGraphErrors(n, x, y, ex, ey);
1612     gr[iFelix]->SetMarkerColor(4);
1613     gr[iFelix]->SetMarkerStyle(21);
1614     gr[iFelix]->Draw("ALP");
1615     gr[iFelix]->GetXaxis()->SetTimeDisplay(1);
1616     gr[iFelix]->GetXaxis()->SetLabelSize(0.03);
1617     // the x axis labeling looks like crap
1618     // please help me with this, the SetNdivisions
1619     // don't do the trick
1620     gr[iFelix]->GetXaxis()->SetNdivisions(-1006);
1621     gr[iFelix]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
1622     gr[iFelix]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
1623     delete[] x;
1624     delete[] y;
1625     delete[] ex;
1626     delete[] ey;
1627   }
1628 
1629   /* varname = "mvtxmoncount";
1630    iret = dbvars->GetVar(begin, end, varname, timestamp, runnumber, var, varerr);
1631    if (iret)
1632    {
1633      std::cout << __PRETTY_FUNCTION__ << " Error in db access" << std::endl;
1634      return iret;
1635    }
1636    x = new float[var.size()];
1637    y = new float[var.size()];
1638    ex = new float[var.size()];
1639    ey = new float[var.size()];
1640    n = var.size();
1641    for (unsigned int i = 0; i < var.size(); i++)
1642    {
1643      //       std::cout << "timestamp: " << ctime(&timestamp[i])
1644      //        << ", run: " << runnumber[i]
1645      //        << ", var: " << var[i]
1646      //        << ", varerr: " << varerr[i]
1647      //        << std::endl;
1648      x[i] = timestamp[i] - TimeOffsetTicks;
1649      y[i] = var[i];
1650      ex[i] = 0;
1651      ey[i] = varerr[i];
1652    }
1653    Pad[6]->cd();
1654    if (gr[1])
1655    {
1656      delete gr[1];
1657    }
1658    gr[1] = new TGraphErrors(n, x, y, ex, ey);
1659    gr[1]->SetMarkerColor(4);
1660    gr[1]->SetMarkerStyle(21);
1661    gr[1]->Draw("ALP");
1662    gr[1]->GetXaxis()->SetTimeDisplay(1);
1663    // TC[2]->Update();
1664    //    h1->GetXaxis()->SetTimeDisplay(1);
1665    //    h1->GetXaxis()->SetLabelSize(0.03);
1666    gr[1]->GetXaxis()->SetLabelSize(0.03);
1667    gr[1]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
1668    gr[1]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
1669    //    h1->Draw();
1670    delete[] x;
1671    delete[] y;
1672    delete[] ex;
1673    delete[] ey;*/
1674 
1675   TC[canvasID]->Update();
1676   TC[canvasID]->SetEditable(false);
1677   return 0;
1678 }
1679 
1680 void MvtxMonDraw::setPalDefault()
1681 {
1682   gStyle->SetPalette(1);
1683 }
1684 
1685 void MvtxMonDraw::setPalUser()
1686 {
1687   const int numColorsUser = 3;
1688   int colorsUser[numColorsUser] = {
1689       TColor::GetColor(0, 255, 0),    // green
1690       TColor::GetColor(255, 255, 0),  // yellow
1691       TColor::GetColor(255, 0, 0)     // red
1692   };
1693 
1694   gStyle->SetPalette(numColorsUser, colorsUser);
1695 }
1696 
1697 // template <typename T>
1698 int MvtxMonDraw::PublishHistogram(TCanvas *c, int pad, TH1 *h, const char *opt, int palettestyle)
1699 {
1700   if (c && pad != 0)
1701   {
1702     c->cd(pad);
1703     // std::cout<<"ups"<<std::endl;
1704   }
1705   if (h)
1706   {
1707     if (palettestyle == 0)
1708     {
1709       h->DrawCopy(opt);
1710       TExec *ex1 = new TExec("ex1", "MvtxMonDraw::setPalDefault();");
1711       ex1->Draw();
1712       h->DrawCopy(opt);
1713     }
1714     else if (palettestyle == 1)
1715     {
1716       h->SetMinimum(-1 / 48);
1717       h->SetMaximum(1200 / 48);
1718       // palette only for noisy pixel
1719       h->DrawCopy(opt);
1720       const int numLevels = 3;
1721       double levels[numLevels] = {0, 200 / 48, 1000 / 48};
1722       h->SetContour(numLevels, levels);
1723       h->SetMarkerSize(2);
1724       TExec *ex1 = new TExec("ex1", "MvtxMonDraw::setPalUser();");
1725       ex1->Draw();
1726       h->DrawCopy(opt);
1727     }
1728     else if (palettestyle == 2)
1729     {
1730       h->SetMinimum(0);
1731       h->SetMaximum(1);
1732       h->DrawCopy(opt);
1733       const int numLevels = 3;
1734       double levels[numLevels] = {0, 0.11, 0.22};
1735       h->SetContour(numLevels, levels);
1736       TExec *ex1 = new TExec("ex1", "MvtxMonDraw::setPalUser();");
1737       ex1->Draw();
1738       h->DrawCopy(opt);
1739     }
1740     else
1741     {
1742       h->DrawCopy(opt);
1743     }
1744     return 0;
1745   }
1746   else
1747   {
1748     // DrawDeadServer(transparent[0]);
1749     return -1;
1750   }
1751 }
1752 
1753 // template <typename T>
1754 int MvtxMonDraw::PublishHistogram(TPad *p, int pad, TH1 *h, const char *opt, int palettestyle)
1755 {
1756   if (p && pad != 0)
1757   {
1758     p->cd(pad);
1759     TCanvas *c = nullptr;
1760     return PublishHistogram(c, 0, h, opt, palettestyle);
1761   }
1762   else
1763   {
1764     return -1;
1765   }
1766 }
1767 
1768 // template <typename T>
1769 int MvtxMonDraw::PublishHistogram(TPad *p, TH1 *h, const char *opt, int palettestyle)
1770 {
1771   if (p)
1772   {
1773     p->cd();
1774     TCanvas *c = nullptr;
1775     return PublishHistogram(c, 0, h, opt, palettestyle);
1776   }
1777 
1778   else
1779   {
1780     return -1;
1781   }
1782 }
1783 
1784 template <typename T>
1785 int MvtxMonDraw::MergeServers(T *h)
1786 {
1787   bool cloned = false;
1788   unsigned int bitset = 0;
1789   for (unsigned int iFelix = 0; iFelix < NFlx; iFelix++)
1790   {
1791     if (cloned == false)
1792     {
1793       if (h[iFelix])
1794       {
1795         h[NFlx] = dynamic_cast<T>(h[iFelix]->Clone());
1796         bitset |= (1U << (iFelix));
1797         cloned = true;
1798       }
1799       else
1800       {
1801         continue;
1802       }
1803     }
1804     else
1805     {
1806       if (h[iFelix])
1807       {
1808         h[NFlx]->Add(h[iFelix], 1.);
1809         bitset |= (1U << (iFelix));
1810       }
1811     }
1812   }
1813   return bitset;
1814 }
1815 
1816 void MvtxMonDraw::PublishStatistics(int canvasID, OnlMonClient *cl)
1817 {
1818   TC[canvasID]->cd();
1819   TText PrintRun;
1820   PrintRun.SetTextFont(62);
1821   PrintRun.SetTextSize(0.04);
1822   PrintRun.SetNDC();          // set to normalized coordinates
1823   PrintRun.SetTextAlign(23);  // center/top alignment
1824   std::ostringstream runnostream;
1825   std::string runstring;
1826   std::pair<time_t, int> evttime = cl->EventTime("CURRENT");
1827   // fill run number and event time into string
1828   runnostream << ThisName << "_1 Run " << cl->RunNumber()
1829               << ", Time: " << ctime(&evttime.first);
1830   runstring = runnostream.str();
1831   transparent[canvasID]->cd();
1832   PrintRun.SetTextColor(evttime.second);
1833   PrintRun.DrawText(0.5, 1., runstring.c_str());
1834   TC[canvasID]->Update();
1835   TC[canvasID]->Show();
1836 }
1837 
1838 void MvtxMonDraw::formatPaveText(TPaveText *aPT, float aTextSize, Color_t aTextColor, short aTextAlign, const char *aText)
1839 {
1840   aPT->SetTextSize(aTextSize);
1841   aPT->SetTextAlign(aTextAlign);
1842   aPT->SetFillColor(0);
1843   aPT->SetTextAlign(22);
1844   aPT->SetTextColor(aTextColor);
1845   aPT->AddText(aText);
1846 }
1847 
1848 std::vector<MvtxMonDraw::Quality> MvtxMonDraw::analyseForError(TH2Poly *lane, TH2Poly *noisy, TH1 *strobes, TH1 *decErr, TH1 *decErrTime, TH1 *DMAstat)
1849 {
1850   std::vector<Quality> result;
1851 
1852   for (int i = 0; i < 19; i++)
1853   {
1854     result.push_back(Quality::Good);
1855   }
1856 
1857   // count dead staves
1858   for (int ilayer = 0; ilayer < NLAYERS; ilayer++)
1859   {
1860     int countStave = 0;
1861     for (int ibin = StaveBoundary[ilayer] + 1; ibin <= StaveBoundary[ilayer + 1]; ++ibin)
1862     {
1863       double bincontent = 0;
1864       if (lane)
1865       {
1866         bincontent = lane->GetBinContent(ibin);
1867       }
1868 
1869       if (bincontent /*hp[iflag][NFlx]->GetBinContent(ibin)*/ >= maxbadchips / 9.)
1870       {
1871         // std::cout<<"bad stave"<<std::endl;
1872         countStave++;
1873         result.at(ilayer) = Quality::Medium;
1874       }
1875     }
1876     if (countStave > 0.2 * NStaves[ilayer])
1877     {
1878       result.at(ilayer) = Quality::Bad;
1879     }
1880   }
1881 
1882   // noisy pixels
1883   double noisypix = 0;
1884 
1885   for (int ilayer = 0; ilayer < NLAYERS; ilayer++)
1886   {
1887     for (int ibin = StaveBoundary[ilayer] + 1; ibin <= StaveBoundary[ilayer + 1]; ++ibin)
1888     {
1889       if (noisy)
1890       {
1891         noisypix = noisy->GetBinContent(ibin);
1892       }
1893     }
1894   }
1895   if (noisypix > 200 && noisypix < 2000)
1896   {
1897     result.at(3) = Quality::Medium;
1898   }
1899   if (noisypix > 2000)
1900   {
1901     result.at(3) = Quality::Bad;
1902   }
1903 
1904   if (strobes)
1905   {
1906     double mins = 100000000;
1907     double avrs = 0;
1908     double maxs = 0;
1909     for (int ibin = 1; ibin <= strobes->GetNbinsX(); ibin++)
1910     {
1911       double binc = static_cast<double>(strobes->GetBinContent(ibin));
1912       if (mins > binc) mins = binc;
1913       if (maxs < binc) maxs = binc;
1914       avrs += binc;
1915     }
1916     if (strobes->GetNbinsX() > 0) avrs = avrs / strobes->GetNbinsX();
1917     if (mins < 0.3 * avrs || maxs > 1.7 * avrs)
1918     {
1919       result.at(4) = Quality::Medium;
1920     }
1921   }
1922 
1923   if (decErr)
1924   {
1925     for (int iflx = 0; iflx < 6; iflx++)
1926     {
1927       if (decErr->Integral(2 * iflx + 1, 2 * iflx + 1) > 0)
1928       {
1929         result.at(5 + 2 * iflx) = Quality::Medium;
1930       }
1931       if (decErr->Integral(2 * iflx + 2, 2 * iflx + 2) > 0)
1932       {
1933         result.at(5 + 2 * iflx + 1) = Quality::Medium;
1934       }
1935     }
1936   }
1937 
1938   if (decErrTime)
1939   {
1940     if (decErrTime->Integral(decErrTime->GetNbinsX() - 10, decErrTime->GetNbinsX()) > 0)
1941     {
1942       result.at(18) = Quality::Bad;
1943     }
1944   }
1945 
1946   if (DMAstat)
1947   {
1948     double integral = DMAstat->Integral();
1949 
1950     if (integral == 11)
1951     {
1952       result.at(17) = Quality::Medium;
1953     }
1954     else if (integral <= 10)
1955     {
1956       result.at(17) = Quality::Bad;
1957     }
1958   }
1959 
1960   return result;
1961 
1962   /* if (mo->getName() == Form("LaneStatus/laneStatusFlag%s", mLaneStatusFlag[iflag].c_str())) {
1963      result = Quality::Good;
1964      auto* h = dynamic_cast<TH2I*>(mo->getObject());
1965      if (h->GetMaximum() > 0) {
1966        result.set(Quality::Bad);
1967      }
1968    }*/
1969   // if (mo->getName() == Form("LaneStatus/laneStatusOverviewFlag%s", mLaneStatusFlag[iflag].c_str())) {
1970   /*   result.at(iflag) = Quality.Good;
1971      auto* hp = dynamic_cast<TH2Poly*>(mo->getObject());
1972      badStave = false;
1973      // Initialization of metaData for IB, ML, OL
1974      for (int ilayer = 0; ilayer < NLAYERS; ilayer++) {
1975        int countStave = 0;
1976        badStaveCount = false;
1977        for (int ibin = StaveBoundary[ilayer] + 1; ibin <= StaveBoundary[ilayer + 1]; ++ibin) {
1978            // Check if there are staves in the IB with lane in Bad (bins are filled with %)
1979            if (hp->GetBinContent(ibin) > maxbadchips / 9.) {
1980              badStave = true;
1981              result.at(iflag) = Quality.Medium;
1982              countStave++;
1983            }
1984        } // end loop bins (staves)
1985        // Initialize metadata for the 7 layers
1986        result.addMetadata(Form("Layer%d", ilayer), "good");
1987        // Check if there are more than 25% staves in Bad per layer
1988        if (countStave > 0.25 * NStaves[ilayer]) {
1989          badStaveCount = true;
1990          result.updateMetadata(Form("Layer%d", ilayer), "bad");
1991        }
1992      } // end loop over layers
1993      if (badStave) {
1994        result.at(iflag) = Quality.Medium;
1995      }
1996      if (badStaveCount) {
1997        result.at(iflag) = Quality.Bad;
1998      }
1999   // } // end lanestatusOverview
2000  }*/
2001 }
2002 
2003 void MvtxMonDraw::DrawPave(std::vector<MvtxMonDraw::Quality> status, int position, const char * /* what*/)
2004 {
2005   TPaveText *pt = new TPaveText(.4, .4, .6, .6, "blNDC");
2006   pt->SetTextSize(0.04);
2007   pt->SetFillColor(0);
2008   pt->SetLineColor(0);
2009   pt->SetBorderSize(1);
2010   if (status.at(position) == Quality::Good && status.at(position + 1) == Quality::Good && status.at(position + 2) == Quality::Good)
2011   {
2012     pt->AddText("#color[418]{QA OK}");
2013   }
2014   if (status.at(position) == Quality::Medium)
2015   {
2016     pt->AddText("#color[808]{QA Layer 0 Medium}");
2017   }
2018   if (status.at(position + 1) == Quality::Medium)
2019   {
2020     pt->AddText("#color[808]{QA Layer 1 Medium}");
2021   }
2022   if (status.at(position + 2) == Quality::Medium)
2023   {
2024     pt->AddText("#color[808]{QA Layer 2 Medium}");
2025   }
2026   if (status.at(position) == Quality::Bad)
2027   {
2028     pt->AddText("#color[2]{QA Layer 0 Bad}");
2029   }
2030   if (status.at(position + 1) == Quality::Bad)
2031   {
2032     pt->AddText("#color[2]{QA Layer 1 Bad}");
2033   }
2034   if (status.at(position + 2) == Quality::Bad)
2035   {
2036     pt->AddText("#color[2]{QA Layer 2 Bad}");
2037   }
2038   pt->Draw();
2039 }
2040 
2041 int MvtxMonDraw::DrawServerStats()
2042 {
2043   OnlMonClient *cl = OnlMonClient::instance();
2044   if (!gROOT->FindObject("MvtxMonServerStats"))
2045   {
2046     MakeCanvas("MvtxMonServerStats");
2047   }
2048   TC[6]->Clear("D");
2049   TC[6]->SetEditable(true);
2050   transparent[6]->cd();
2051   TText PrintRun;
2052   PrintRun.SetTextFont(62);
2053   PrintRun.SetNDC();          // set to normalized coordinates
2054   PrintRun.SetTextAlign(23);  // center/top alignment
2055   PrintRun.SetTextSize(0.04);
2056   PrintRun.SetTextColor(1);
2057   PrintRun.DrawText(0.5, 0.99, "Server Statistics");
2058 
2059   PrintRun.SetTextSize(0.02);
2060   double vdist = 0.05;
2061   double vpos = 0.9;
2062   for (const auto &server : m_ServerSet)
2063   {
2064     std::ostringstream txt;
2065     auto servermapiter = cl->GetServerMap(server);
2066     if (servermapiter == cl->GetServerMapEnd())
2067     {
2068       txt << "Server " << server
2069           << " is dead ";
2070       PrintRun.SetTextColor(kRed);
2071     }
2072     else
2073     {
2074       txt << "Server " << server
2075           << ", run number " << std::get<1>(servermapiter->second)
2076           << ", event count: " << std::get<2>(servermapiter->second)
2077           << ", current time " << ctime(&(std::get<3>(servermapiter->second)));
2078       if (std::get<0>(servermapiter->second))
2079       {
2080         PrintRun.SetTextColor(kGray + 2);
2081       }
2082       else
2083       {
2084         PrintRun.SetTextColor(kRed);
2085       }
2086     }
2087     PrintRun.DrawText(0.5, vpos, txt.str().c_str());
2088     vpos -= vdist;
2089   }
2090   TC[6]->Update();
2091   TC[6]->Show();
2092   TC[6]->SetEditable(false);
2093 
2094   return 0;
2095 }