Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:20:28

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 <TGaxis.h>
0012 #include <TGraphErrors.h>
0013 #include <TH1.h>
0014 #include <TH2.h>
0015 #include <TH2Poly.h>
0016 #include <TH3.h>
0017 #include <TLatex.h>
0018 #include <TPad.h>
0019 #include <TPaveText.h>
0020 #include <TROOT.h>
0021 #include <TStyle.h>
0022 #include <TSystem.h>
0023 #include <TText.h>
0024 #include <TExec.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 
0456 
0457   // injecting errors here
0458   // mvtxmon_LaneStatusOverview[0][1] = mvtxmon_LaneStatusOverview[0][0];
0459   // injecting errors done
0460 
0461   int bitset = 0;
0462   int bitsetOR = 0;
0463   int bitsetAND = 63;
0464   bitset = MergeServers<TH2Poly *>(mvtxmon_LaneStatusOverview);
0465   bitsetOR |= bitset;
0466   bitsetAND &= bitset;
0467   bitset = MergeServers<TH2Poly *>(mvtxmon_mGeneralOccupancy);
0468   bitsetOR |= bitset;
0469   bitsetAND &= bitset;
0470   bitset = MergeServers<TH2Poly *>(mGeneralNoisyPixel);
0471   bitsetOR |= bitset;
0472   bitsetAND &= bitset;
0473   bitset = MergeServers<TH1D *>(mvtxmon_mGeneralErrorPlots);
0474   bitsetOR |= bitset;
0475   bitsetAND &= bitset;
0476   bitset = MergeServers<TH1D *>(mvtxmon_mGeneralErrorPlotsTime);
0477   bitsetOR |= bitset;
0478   bitsetAND &= bitset;
0479   bitset = MergeServers<TH1I *>(hChipStrobes);
0480   bitsetOR |= bitset;
0481   bitsetAND &= bitset;
0482   bitset = MergeServers<TH1I *>(hChipL1);
0483   bitsetOR |= bitset;
0484   bitsetAND &= bitset;
0485   bitset = MergeServers<TH2D *>(mvtxmon_mGeneralErrorFile);
0486   bitsetOR |= bitset;
0487   bitsetAND &= bitset;
0488   bitset = MergeServers<TH1D *>(mvtxmon_ChipStave1D);
0489   bitsetOR |= bitset;
0490   bitsetAND &= bitset;
0491   bitset = MergeServers<TH1I *>(hStrobesDMA);
0492   bitsetOR |= bitset;
0493   bitsetAND &= bitset;
0494   bitset = MergeServers<TH1I *>(hDMAstatus);
0495   bitsetOR |= bitset;
0496   bitsetAND &= bitset;
0497 
0498   if (mvtxmon_LaneStatusOverview[NFlx])
0499   {
0500     mvtxmon_LaneStatusOverview[NFlx]->SetStats(false);
0501     mvtxmon_LaneStatusOverview[NFlx]->GetYaxis()->SetTitleOffset(0.6);
0502     mvtxmon_LaneStatusOverview[NFlx]->SetMinimum(0);
0503     mvtxmon_LaneStatusOverview[NFlx]->SetMaximum(1);
0504   }
0505 
0506   if (mvtxmon_mGeneralOccupancy[NFlx])
0507   {
0508     mvtxmon_mGeneralOccupancy[NFlx]->GetYaxis()->SetTitleOffset(0.6);
0509     mvtxmon_mGeneralOccupancy[NFlx]->SetMinimum(0);
0510     mvtxmon_mGeneralOccupancy[NFlx]->SetMaximum(100E-6); // set a fixed max value 
0511     mvtxmon_mGeneralOccupancy[NFlx]->SetContour(100);
0512   }
0513 
0514    if (mvtxmon_ChipStave1D[NFlx])
0515   {
0516     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetLabelSize(0.05);
0517     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleSize(0.055);
0518     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleOffset(0.9);
0519     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetLabelSize(0.045);
0520     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleSize(0.05);
0521     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleOffset(1.2);
0522   }
0523 
0524   /*if (mvtxmon_mGeneralErrorFile[NFlx])
0525   {
0526     for (int bin = 1; bin < mvtxmon_mGeneralErrorFile[NFlx]->GetNbinsX() + 1; bin++)
0527     {
0528       if (bin <= 12)
0529       {
0530         mvtxmon_mGeneralErrorFile[NFlx]->GetXaxis()->SetBinLabel(bin, Form("%d", (bin - 1) % 2));
0531       }
0532       else
0533       {
0534         mvtxmon_mGeneralErrorFile[NFlx]->GetXaxis()->SetBinLabel(bin, "");
0535       }
0536     }
0537     mvtxmon_mGeneralErrorFile[NFlx]->GetXaxis()->SetTitleSize(0.045);
0538     mvtxmon_mGeneralErrorFile[NFlx]->GetYaxis()->SetTitleSize(0.045);*/
0539   //}
0540 
0541   if (!gROOT->FindObject("MvtxMon_General"))
0542   {
0543     MakeCanvas("MvtxMon_General");
0544   }
0545 
0546   TC[canvasID]->SetEditable(true);
0547   TC[canvasID]->Clear("D");
0548 
0549   Pad[padID]->Divide(4, 2);
0550   int returnCode = 0;
0551 
0552   // Pad[padID]->cd(1)->SetRightMargin(0.15);
0553   Pad[padID]->cd(3)->SetRightMargin(0.16);
0554   Pad[padID]->cd(4)->SetRightMargin(0.15);
0555   Pad[padID]->cd(4)->SetLeftMargin(0.15);
0556   Pad[padID]->cd(6)->SetLeftMargin(0.16);
0557   Pad[padID]->cd(6)->SetTopMargin(0.16);
0558   Pad[padID]->cd(6)->SetBottomMargin(0.14);
0559 
0560   // injecting errors here
0561   /*  mvtxmon_LaneStatusOverview[1][NFlx]->SetBinContent(5,0.5);
0562     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(11,0.5);
0563     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(12,0.5);
0564     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(13,0.5);
0565     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(14,0.5);
0566     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(15,0.5);
0567     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(16,0.5);
0568     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(17,0.5);
0569     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(18,0.5);
0570     mvtxmon_LaneStatusOverview[2][NFlx]->SetBinContent(19,0.5);
0571     mvtxmon_mGeneralErrorFile[NFlx]->SetBinContent(17,5,20);*/
0572   // injecting errors done
0573 
0574   if (mvtxmon_mGeneralErrorPlots[NFlx])
0575   {
0576     mvtxmon_mGeneralErrorPlots[NFlx]->GetXaxis()->SetTitleSize(0.045);
0577     mvtxmon_mGeneralErrorPlots[NFlx]->GetYaxis()->SetTitleSize(0.045);
0578   }
0579 
0580    if (mvtxmon_mGeneralErrorPlotsTime[NFlx])
0581   {
0582     mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->SetLabelOffset(999);
0583     mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->SetTickLength(0);
0584   }
0585 
0586  if(hChipStrobes[NFlx])
0587   {
0588     hChipStrobes[NFlx]->SetMinimum(0);
0589     hChipStrobes[NFlx]->SetTitle("Strobe & L1 vs Chip");
0590   }
0591 
0592     TPaveText *tlayer[3] = {nullptr};
0593 
0594   for (int i = 0; i < 3; i++)
0595   {
0596     double shift[3] = {0, 0.25, 0.55};
0597     tlayer[i] = new TPaveText(.14 + shift[i], .87, .24 + shift[i], .93, "blNDC");
0598     tlayer[i]->SetTextSize(0.05);
0599     tlayer[i]->SetFillColor(0);
0600     tlayer[i]->SetTextAlign(22);
0601     tlayer[i]->SetLineColor(0);
0602     tlayer[i]->SetBorderSize(1);
0603     tlayer[i]->AddText(Form("Layer %d", i));
0604   }
0605 
0606     Pad[padID]->cd(4)->SetTopMargin(0.16);
0607 
0608    Pad[padID]->cd(6)->SetTopMargin(0.2);
0609    Pad[padID]->cd(6)->SetLeftMargin(0.16);
0610 
0611    Pad[padID]->cd(2)->SetRightMargin(0.16);
0612 
0613   std::vector<MvtxMonDraw::Quality> status;
0614   status = analyseForError(mvtxmon_LaneStatusOverview[NFlx], mGeneralNoisyPixel[NFlx], hChipStrobes[NFlx], mvtxmon_mGeneralErrorFile[NFlx], mvtxmon_mGeneralErrorPlotsTime[NFlx],hDMAstatus[NFlx]);
0615 
0616   returnCode += PublishHistogram(Pad[padID], 1, mvtxmon_LaneStatusOverview[NFlx], "col", 2);
0617   returnCode += PublishHistogram(Pad[padID], 1, mvtxmon_LaneStatusOverview[NFlx], "colz same", 2);
0618   //DrawPave(status, 0);
0619   //returnCode += PublishHistogram(Pad[padID], 2, mvtxmon_mGeneralOccupancy[NFlx]);
0620   returnCode += PublishHistogram(Pad[padID], 2, mvtxmon_mGeneralOccupancy[NFlx], "col", 0);
0621   returnCode += PublishHistogram(Pad[padID], 2, mvtxmon_mGeneralOccupancy[NFlx], "colz same", 0);
0622   returnCode += PublishHistogram(Pad[padID], 3, mGeneralNoisyPixel[NFlx], "colz", 1);
0623   returnCode += PublishHistogram(Pad[padID], 3, mGeneralNoisyPixel[NFlx], "colztext same", 1);
0624   returnCode += PublishHistogram(Pad[padID], 5, mvtxmon_mGeneralErrorPlotsTime[NFlx]);
0625 
0626   if (mvtxmon_mGeneralErrorPlotsTime[NFlx])
0627   {
0628     // Redraw the new axis
0629     gPad->Update();
0630     TGaxis *newaxis = new TGaxis(gPad->GetUxmax(),
0631                                   gPad->GetUymin(),
0632                                   gPad->GetUxmin(),
0633                                   gPad->GetUymin(),
0634                                   mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->GetXmin(),
0635                                   mvtxmon_mGeneralErrorPlotsTime[NFlx]->GetXaxis()->GetXmax(),
0636                                   510,"-");
0637     newaxis->SetLabelOffset(-0.04);
0638     newaxis->SetLabelSize(0.04);
0639     newaxis->Draw();
0640   }
0641   //returnCode += PublishHistogram(Pad[padID], 5, hStrobesDMA[NFlx]);
0642   
0643   returnCode += PublishHistogram(Pad[padID], 4, hChipStrobes[NFlx]);
0644 if(hChipStrobes[NFlx]){
0645   for (const int& lay : LayerBoundaryFEE)
0646     {
0647       auto l = new TLine(lay, 0, lay, 1.1*hChipStrobes[NFlx]->GetMaximum());
0648       l->Draw("same");
0649     }
0650 }
0651 Float_t rightmax = 0.1;
0652 if(hChipL1[NFlx] && hChipStrobes[NFlx]){
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   TGaxis *axis = new TGaxis(48 * 3, 0, 48 * 3, hChipStrobes[NFlx]->GetMaximum(), 0, rightmax, 510, "+L");
0661   axis->SetLineColor(kRed);
0662   axis->SetLabelColor(kRed);
0663   axis->SetLabelFont(42);
0664   axis->SetTitleFont(42);
0665   axis->SetTitleColor(kRed);
0666   axis->SetTitle("Number of L1 triggers");
0667   axis->Draw();
0668 }
0669   for (auto &i : tlayer)
0670   {
0671     i->Draw();
0672   }
0673 
0674 
0675 
0676 
0677 
0678    
0679 
0680   returnCode += PublishHistogram(Pad[padID], 6, mvtxmon_ChipStave1D[NFlx]);
0681 if(mvtxmon_ChipStave1D[NFlx]){
0682   for (const int& lay : LayerBoundaryChip)
0683     {
0684       auto ll = new TLine(lay, 0, lay, 1.1* mvtxmon_ChipStave1D[NFlx]->GetMaximum());
0685       ll->Draw("same");
0686     }
0687 }
0688     for (auto &i : tlayer)
0689   {
0690     i->Draw();
0691   }
0692 
0693   
0694   
0695 
0696  
0697 
0698 
0699   //returnCode += PublishHistogram(Pad[padID], 6, mvtxmon_mGeneralErrorFile[NFlx], "lcol");
0700 
0701   /*TPaveText *ptt5 = new TPaveText(.1, .85, .5, .95, "blNDC");
0702   ptt5->SetTextSize(0.02);
0703   ptt5->SetFillColor(0);
0704   ptt5->SetLineColor(0);
0705   ptt5->SetBorderSize(1);
0706   ptt5->AddText(" FLX 0   FLX 1   FLX 2   FLX 3   FLX 4   FLX 5");
0707   ptt5->Draw();*/
0708 
0709   Pad[padID]->cd(7);
0710 
0711   TPaveText *bulbRed = new TPaveText(0.1, 0.82, 0.9, 0.92, "NDC");
0712   bulbRed->SetName("BulbRed");
0713   formatPaveText(bulbRed, 0.05, kRed, 12, "#color[2]{MVTX has errors}");
0714 
0715   TPaveText *bulbYellow = new TPaveText(0.1, 0.82, 0.9, 0.92, "NDC");
0716   bulbYellow->SetName("BulbYellow");
0717   formatPaveText(bulbYellow, 0.05, kRed, 12, "#color[808]{MVTX has minor errors}");
0718 
0719   TPaveText *bulbGreen = new TPaveText(0.1, 0.82, 0.9, 0.92, "NDC");
0720   bulbGreen->SetName("BulbGreen");
0721   formatPaveText(bulbGreen, 0.05, kGreen, 12, "#color[418]{MVTX is OK}");
0722 
0723   TPaveText *bulb = new TPaveText(0.05, 0.05, 0.95, 0.95, "NDC");
0724 
0725   TPaveText *ptt4 = new TPaveText(.1, .07, .9, .58, "blNDC");
0726   ptt4->SetTextSize(0.04);
0727   ptt4->SetFillColor(0);
0728   ptt4->SetTextAlign(22);
0729   ptt4->SetLineColor(0);
0730   ptt4->SetBorderSize(1);
0731   ptt4->AddText("Alarms:");
0732 
0733   Quality q = Quality::Good;
0734 
0735    for (int i = 0 ; i < 18 ; i++){
0736     //std::cout<<i<<" "<<status.at(i)<<std::endl;
0737     if(status.at(i) == Quality::Medium) q = Quality::Medium;
0738     if(status.at(i) == Quality::Bad) q = Quality::Bad;
0739   }
0740 
0741   if (q == Quality::Good)
0742   {
0743     bulb->SetFillColor(kGreen);
0744     bulb->Draw();
0745     bulbGreen->Draw("same");
0746   }
0747   
0748   
0749  for (int i = 0 ; i < 18 ; i++){
0750     if(status.at(i) == Quality::Medium) q = Quality::Medium;
0751   }
0752 
0753   if (q == Quality::Medium)
0754   {
0755     if (status.at(0) == Quality::Medium)
0756     {
0757       // ptt4->AddText("#color[808]{Layer 0 Medium}");
0758       ptt4->AddText("#color[808]{Lane error(s) in Layer 0}");
0759     }
0760     if (status.at(1) == Quality::Medium)
0761     {
0762       // ptt4->AddText("#color[808]{QA Layer 1 Medium}");
0763       ptt4->AddText("#color[808]{Lane error(s) in Layer 1}");
0764     }
0765     if (status.at(2) == Quality::Medium)
0766     {
0767       // ptt4->AddText("#color[808]{QA Layer 2 Medium}");
0768       ptt4->AddText("#color[808]{Lane error(s) in Layer 2}");
0769     }
0770     if (status.at(3) == Quality::Medium)
0771     {
0772       ptt4->AddText("#color[808]{Medium level of noisy pixels}");
0773     }
0774     if (status.at(4) == Quality::Medium)
0775     {
0776       ptt4->AddText("#color[808]{Big variation in number of strobes}");
0777     }
0778     if (status.at(5) == Quality::Medium)
0779     {
0780       ptt4->AddText("#color[808]{FELIX 0 DMA 0 Decoder errors detected}");
0781     }
0782     if (status.at(6) == Quality::Medium)
0783     {
0784        ptt4->AddText("#color[808]{FELIX 0 DMA 1 Decoder errors detected}");
0785     }
0786     if (status.at(7) == Quality::Medium)
0787     {
0788       ptt4->AddText("#color[808]{FELIX 1 DMA 0 Decoder errors detected}");
0789     }
0790     if (status.at(8) == Quality::Medium)
0791     {
0792        ptt4->AddText("#color[808]{FELIX 1 DMA 1 Decoder errors detected}");
0793     }
0794     if (status.at(9) == Quality::Medium)
0795     {
0796       ptt4->AddText("#color[808]{FELIX 2 DMA 0 Decoder errors detected}");
0797     }
0798     if (status.at(10) == Quality::Medium)
0799     {
0800        ptt4->AddText("#color[808]{FELIX 2 DMA 1 Decoder errors detected}");
0801     }
0802     if (status.at(11) == Quality::Medium)
0803     {
0804       ptt4->AddText("#color[808]{FELIX 3 DMA 0 Decoder errors detected}");
0805     }
0806     if (status.at(12) == Quality::Medium)
0807     {
0808        ptt4->AddText("#color[808]{FELIX 3 DMA 1 Decoder errors detected}");
0809     }
0810     if (status.at(13) == Quality::Medium)
0811     {
0812       ptt4->AddText("#color[808]{FELIX 4 DMA 0 Decoder errors detected}");
0813     }
0814     if (status.at(14) == Quality::Medium)
0815     {
0816        ptt4->AddText("#color[808]{FELIX 4 DMA 1 Decoder errors detected}");
0817     }
0818     if (status.at(15) == Quality::Medium)
0819     {
0820       ptt4->AddText("#color[808]{FELIX 5 DMA 0 Decoder errors detected}");
0821     }
0822     if (status.at(16) == Quality::Medium)
0823     {
0824        ptt4->AddText("#color[808]{FELIX 5 DMA 1 Decoder errors detected}");
0825     }
0826     if (status.at(17) == Quality::Medium)
0827     {
0828        ptt4->AddText("#color[808]{1 DMA dead check grafana data rate}");
0829        for(int ibin = 1; ibin <= hDMAstatus[NFlx]->GetNbinsX(); ibin++)
0830        {
0831          if(hDMAstatus[NFlx]->GetBinContent(ibin) == 0) ptt4->AddText(Form("#color[808]{FELIX %d DMA %d no data}",(ibin-1)/2,(ibin-1)%2));
0832        }
0833     }
0834     
0835 
0836     bulb->SetFillColor(kYellow);
0837     bulb->Draw();
0838     bulbYellow->Draw("same");
0839   }
0840 
0841    for (int i = 0 ; i < 18 ; i++){
0842     if(status.at(i) == Quality::Bad) q = Quality::Bad;
0843   }
0844 
0845   if (q == Quality::Bad || (bitsetAND & 0x3F) != 0x3F)
0846   {
0847     if (status.at(0) == Quality::Bad)
0848     {
0849       ptt4->AddText("#color[2]{>1/5 of staves in Layer 0 BAD}");
0850     }
0851     if (status.at(1) == Quality::Bad)
0852     {
0853       ptt4->AddText("#color[2]{>1/5 of staves in Layer 1 BAD}");
0854     }
0855     if (status.at(2) == Quality::Bad)
0856     {
0857       ptt4->AddText("#color[2]{>1/5 of staves in Layer 2 BAD}");
0858     }
0859     if (status.at(3) == Quality::Bad)
0860     {
0861       ptt4->AddText("#color[2]{Too many noisy pixels}");
0862     }
0863     if (status.at(17) == Quality::Bad)
0864     {
0865        ptt4->AddText("#color[2]{2 or more DMA dead check grafana data rate}");
0866        for(int ibin = 1; ibin <= hDMAstatus[NFlx]->GetNbinsX(); ibin++)
0867        {
0868          if(hDMAstatus[NFlx]->GetBinContent(ibin) == 0) ptt4->AddText(Form("#color[2]{FELIX %d DMA %d no data}",(ibin-1)/2,(ibin-1)%2));
0869        }
0870     }
0871     if (status.at(18) == Quality::Bad)
0872     {
0873       ptt4->AddText("#color[2]{Decoder errors in the last 10 events}");
0874     }
0875     if ((bitsetAND & 0x3F) != 0x3F)
0876     {
0877       ptt4->AddText("#color[2]{Some Servers are Offline or in Error}");
0878     }
0879     bulb->SetFillColor(kRed);
0880     bulb->Draw();
0881     bulbRed->Draw("same");
0882   }
0883 
0884   ptt4->Draw();
0885 
0886   TPaveText *tlegend = new TPaveText(.2, .6, .8, .8, "blNDC");
0887   tlegend->SetTextSize(0.04);
0888   tlegend->SetFillColor(0);
0889   tlegend->SetTextAlign(22);
0890   tlegend->SetLineColor(0);
0891   tlegend->SetBorderSize(1);
0892   tlegend->AddText("Legend:");
0893   tlegend->AddText("#color[418]{Green = QA OK}");
0894   tlegend->AddText("#color[808]{Yellow = QA Medium}");
0895   tlegend->AddText("#color[2]{Red = QA Bad}");
0896   tlegend->Draw();
0897 
0898 bool DMA_error[12] = {false};
0899 if(hStrobesDMA[NFlx]){
0900 for (int iDMA = 0; iDMA < NFlx*2; iDMA++){
0901   if(lastStrobes[iDMA] > static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA+1))){
0902     lastStrobes[iDMA] = static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA+1));
0903     DMA_error[iDMA] = false;
0904   }
0905   else if (lastStrobes[iDMA] == static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA+1))){
0906     DMA_error[iDMA] = true;
0907   }
0908   else if (lastStrobes[iDMA] < static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA+1))){
0909     DMA_error[iDMA] = false;
0910     lastStrobes[iDMA] = static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(iDMA+1));
0911   }
0912 }
0913 }
0914 
0915   
0916 
0917   Pad[padID]->cd(8);
0918   TPaveText *pt = new TPaveText(.05, .1, .95, .8);
0919   pt->AddText("Online Monitoring Server Status");
0920   for (int iFelix = 0; iFelix < NFlx; iFelix++)
0921   {
0922     std::string serverStatus = "Felix " + std::to_string(iFelix);
0923     if ((bitsetOR & (1 << iFelix)) == 1 << iFelix && (bitsetAND & (1 << iFelix)) == 1 << iFelix)
0924     {
0925       serverStatus += " #color[418]{ONLINE} ";
0926       serverStatus += (DMA_error[2*iFelix])?"#color[2]{":"#color[418]{";
0927       serverStatus += std::to_string(static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(2*iFelix+1)));
0928       serverStatus += "}  ";
0929       serverStatus += (DMA_error[2*iFelix+1])?"#color[2]{":"#color[418]{";
0930       serverStatus += std::to_string(static_cast<int>(hStrobesDMA[NFlx]->GetBinContent(2*iFelix+2)));
0931       serverStatus += "}";
0932     }
0933     if ((bitsetOR & (1 << iFelix)) == 0 && (bitsetAND & (1 << iFelix)) == 0)
0934     {
0935       serverStatus += " #color[2]{OFFLINE}";
0936     }
0937     if ((bitsetOR & (1 << iFelix)) == 1 << iFelix && (bitsetAND & (1 << iFelix)) == 0)
0938     {
0939       serverStatus += " #color[2]{ERROR}";
0940     }
0941     pt->AddText(serverStatus.c_str());
0942   }
0943   pt->Draw();
0944   PublishStatistics(canvasID, cl);
0945   TC[canvasID]->SetEditable(false);
0946   return returnCode < 0 ? -1 : 0;
0947 }
0948 
0949 int MvtxMonDraw::DrawFEE(const std::string & /* what */)
0950 {
0951   OnlMonClient *cl = OnlMonClient::instance();
0952   const int canvasID = 2;
0953   const int padID = 2;
0954 
0955   //TH2I *mTriggerVsFeeId[NFlx + 1] = {nullptr};
0956   //TH1I *mTrigger[NFlx + 1] = {nullptr};
0957   TH2I* FHR_ErrorVsFeeid[NFlx+1] = {nullptr};
0958   TH2I *mLaneStatus[3][NFlx + 1] = {{nullptr}};
0959   TH2I *mLaneStatusCumulative[3][NFlx + 1] = {{nullptr}};
0960   //TH1I *mLaneStatusSummary[3][NFlx + 1] = {{nullptr}};
0961   //TH1I *mLaneStatusSummaryIB[NFlx + 1] = {nullptr};
0962   TH1D *mvtxmon_mGeneralErrorPlots[NFlx + 1] = {nullptr};
0963   TH2D *mvtxmon_mGeneralErrorFile[NFlx + 1] = {nullptr};
0964   TH1I *hRDHErrors[NFlx + 1] = {nullptr};
0965 
0966   for (int iFelix = 0; iFelix < NFlx; iFelix++)
0967   {
0968     //mTriggerVsFeeId[iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_FEE_TriggerVsFeeid"));
0969    // mTrigger[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_FEE_TriggerFlag"));
0970     FHR_ErrorVsFeeid[iFelix] = dynamic_cast<TH2I*>(cl->getHisto(Form("MVTXMON_%d",iFelix),"FHR_ErrorVsFeeid"));
0971     //mLaneStatusSummaryIB[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "FEE_LaneStatusSummary"));
0972     mvtxmon_mGeneralErrorPlots[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_DecErrors"));
0973      mvtxmon_mGeneralErrorFile[iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_DecErrorsEndpoint"));
0974     for (int i = 0; i < 3; i++)
0975     {
0976       mLaneStatus[i][iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FEE_LaneStatus_Flag_%s", mLaneStatusFlag[i].c_str())));
0977       mLaneStatusCumulative[i][iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FEE_LaneStatusFromSOX_Flag_%s", mLaneStatusFlag[i].c_str())));
0978       //mLaneStatusSummary[i][iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FEE_LaneStatusSummary_Layer_%i", i)));
0979     }
0980     hRDHErrors[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "RDHErrors_hfeeRDHErrors"));
0981   }
0982 
0983   for (int i = 0; i < 3; i++)
0984   {
0985     MergeServers<TH2I *>(mLaneStatus[i]);
0986     MergeServers<TH2I *>(mLaneStatusCumulative[i]);
0987     //MergeServers<TH1I *>(mLaneStatusSummary[i]);
0988   }
0989   //MergeServers<TH2I *>(mTriggerVsFeeId);
0990   //MergeServers<TH1I *>(mTrigger);
0991   // MergeServers<TH2I*>(mLaneInfo);
0992   MergeServers<TH2I *>(FHR_ErrorVsFeeid);
0993     MergeServers<TH1D *>(mvtxmon_mGeneralErrorPlots);
0994       MergeServers<TH2D *>(mvtxmon_mGeneralErrorFile);
0995   MergeServers<TH1I *>(hRDHErrors);
0996 
0997   if (!gROOT->FindObject("MvtxMon_FEE"))
0998   {
0999     MakeCanvas("MvtxMon_FEE");
1000   }
1001 
1002   TC[canvasID]->SetEditable(true);
1003   TC[canvasID]->Clear("D");
1004   Pad[padID]->Divide(4, 3);
1005 
1006   for (int i = 0; i < 3; i++)
1007   {
1008     if (mLaneStatus[i][NFlx])
1009     {
1010       mLaneStatus[i][NFlx]->GetXaxis()->SetTitleSize(0.055);
1011       mLaneStatus[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1012       mLaneStatus[i][NFlx]->GetYaxis()->SetTitleSize(0.06);
1013       mLaneStatus[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1014       mLaneStatus[i][NFlx]->GetYaxis()->SetLabelSize(0.05);
1015     }
1016     if (mLaneStatusCumulative[i][NFlx])
1017     {
1018       mLaneStatusCumulative[i][NFlx]->GetXaxis()->SetTitleSize(0.055);
1019       mLaneStatusCumulative[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1020       mLaneStatusCumulative[i][NFlx]->GetYaxis()->SetTitleSize(0.06);
1021       mLaneStatusCumulative[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1022       mLaneStatusCumulative[i][NFlx]->GetYaxis()->SetLabelSize(0.05);
1023     }
1024   }
1025   /*  if (mLaneStatusSummary[i][NFlx])
1026     {
1027       mLaneStatusSummary[i][NFlx]->GetXaxis()->SetLabelSize(0.07);
1028       mLaneStatusSummary[i][NFlx]->GetYaxis()->SetTitleSize(0.06);
1029       mLaneStatusSummary[i][NFlx]->GetYaxis()->SetLabelSize(0.05);
1030       mLaneStatusSummary[i][NFlx]->GetYaxis()->SetTitleOffset(0.9);
1031     }
1032   }
1033   if (mLaneStatusSummaryIB[NFlx])
1034   {
1035     mLaneStatusSummaryIB[NFlx]->GetXaxis()->SetLabelSize(0.07);
1036     mLaneStatusSummaryIB[NFlx]->GetYaxis()->SetTitleSize(0.06);
1037     mLaneStatusSummaryIB[NFlx]->GetYaxis()->SetLabelSize(0.05);
1038     mLaneStatusSummaryIB[NFlx]->GetYaxis()->SetTitleOffset(0.9);
1039   }*/
1040   /*if (mTriggerVsFeeId[NFlx])
1041   {
1042     mTriggerVsFeeId[NFlx]->GetXaxis()->SetTitleSize(0.055);
1043     mTriggerVsFeeId[NFlx]->GetXaxis()->SetTitleOffset(0.75);
1044     mTriggerVsFeeId[NFlx]->GetYaxis()->SetTitleOffset(1.2);
1045     mTriggerVsFeeId[NFlx]->GetYaxis()->SetTitleSize(0.06);
1046     mTriggerVsFeeId[NFlx]->GetYaxis()->SetLabelSize(0.06);
1047     mTriggerVsFeeId[NFlx]->GetXaxis()->SetLabelSize(0.05);
1048   }
1049   if (mTrigger[NFlx])
1050   {
1051     mTrigger[NFlx]->GetXaxis()->SetTitleSize(0.055);
1052     mTrigger[NFlx]->GetXaxis()->SetTitleOffset(0.85);
1053     mTrigger[NFlx]->GetYaxis()->SetTitleSize(0.06);
1054     mTrigger[NFlx]->GetYaxis()->SetLabelSize(0.06);
1055     mTrigger[NFlx]->GetXaxis()->SetLabelSize(0.05);
1056     mTrigger[NFlx]->GetYaxis()->SetTitleOffset(0.85);
1057   }*/
1058 
1059   TPaveText *tlayer[3] = {nullptr};
1060 
1061   for (int i = 0; i < 3; i++)
1062   {
1063     double shift[3] = {0, 0.25, 0.55};
1064     tlayer[i] = new TPaveText(.14 + shift[i], .87, .24 + shift[i], .93, "blNDC");
1065     tlayer[i]->SetTextSize(0.05);
1066     tlayer[i]->SetFillColor(0);
1067     tlayer[i]->SetTextAlign(22);
1068     tlayer[i]->SetLineColor(0);
1069     tlayer[i]->SetBorderSize(1);
1070     tlayer[i]->AddText(Form("Layer %d", i));
1071   }
1072 /*
1073   Pad[padID]->cd(3)->SetTopMargin(0.16);
1074   Pad[padID]->cd(4)->SetTopMargin(0.16);
1075   Pad[padID]->cd(4)->SetTopMargin(0.145);
1076   Pad[padID]->cd(7)->SetTopMargin(0.16);
1077   Pad[padID]->cd(8)->SetTopMargin(0.16);
1078   Pad[padID]->cd(11)->SetTopMargin(0.16);
1079   Pad[padID]->cd(12)->SetTopMargin(0.16);*/
1080 
1081   int returnCode = 0;
1082  // Pad[padID]->cd(1)->SetLeftMargin(0.16);
1083   returnCode += PublishHistogram(Pad[padID], 9, mvtxmon_mGeneralErrorPlots[NFlx]);
1084   returnCode += PublishHistogram(Pad[padID], 10, mvtxmon_mGeneralErrorFile[NFlx], "lcol");
1085   returnCode += PublishHistogram(Pad[padID], 11, FHR_ErrorVsFeeid[NFlx], "lcol");
1086   returnCode += PublishHistogram(Pad[padID], 12, hRDHErrors[NFlx], "lcol");
1087   //returnCode += PublishHistogram(Pad[padID], 1, mTriggerVsFeeId[NFlx], "lcol");
1088   //returnCode += PublishHistogram(Pad[padID], 5, mTrigger[NFlx]);
1089   // returnCode += PublishHistogram(Pad[9],3,mLaneInfo[NFlx]);
1090   returnCode += PublishHistogram(Pad[padID], 1, mLaneStatus[0][NFlx], "lcol");
1091   /*for (auto &i : tlayer)
1092   {
1093     i->Draw();
1094   }*/
1095   returnCode += PublishHistogram(Pad[padID], 2, mLaneStatus[1][NFlx], "lcol");
1096   /*for (auto &i : tlayer)
1097   {
1098     i->Draw();
1099   }*/
1100   returnCode += PublishHistogram(Pad[padID], 3, mLaneStatus[2][NFlx], "lcol");
1101   /*for (auto &i : tlayer)
1102   {
1103     i->Draw();
1104   }*/
1105   returnCode += PublishHistogram(Pad[padID], 5, mLaneStatusCumulative[0][NFlx], "lcol");
1106   /*for (auto &i : tlayer)
1107   {
1108     i->Draw();
1109   }*/
1110   returnCode += PublishHistogram(Pad[padID], 6, mLaneStatusCumulative[1][NFlx], "lcol");
1111   /*for (auto &i : tlayer)
1112   {
1113     i->Draw();
1114   }*/
1115   returnCode += PublishHistogram(Pad[padID], 7, mLaneStatusCumulative[2][NFlx], "lcol");
1116   /*for (auto &i : tlayer)
1117   {
1118     i->Draw();
1119   }*/
1120   /*returnCode += PublishHistogram(Pad[padID], 2, mLaneStatusSummary[0][NFlx]);
1121   returnCode += PublishHistogram(Pad[padID], 6, mLaneStatusSummary[1][NFlx]);
1122   returnCode += PublishHistogram(Pad[padID], 10, mLaneStatusSummary[2][NFlx]);
1123   returnCode += PublishHistogram(Pad[padID], 9, mLaneStatusSummaryIB[NFlx]);
1124 */
1125   PublishStatistics(canvasID, cl);
1126   TC[canvasID]->SetEditable(false);
1127   return returnCode < 0 ? -1 : 0;
1128 }
1129 
1130 int MvtxMonDraw::DrawOCC(const std::string & /* what */)
1131 {
1132   OnlMonClient *cl = OnlMonClient::instance();
1133   const int canvasID = 3;
1134   const int padID = 3;
1135 
1136   TH1D *hOccupancyPlot[3][NFlx + 1] = {{nullptr}};
1137   TH2D *hChipStaveOccupancy[3][NFlx + 1] = {{nullptr}};
1138   TH1D *mvtxmon_ChipStave1D[NFlx + 1] = {nullptr};
1139   TH1D *mvtxmon_ChipFiredHis[NFlx + 1] = {nullptr};
1140   TH1I *hChipStrobes[NFlx + 1] = {nullptr};
1141   TH1I *hChipL1[NFlx + 1] = {nullptr};
1142 
1143   for (int aLayer = 0; aLayer < 3; aLayer++)
1144   {
1145     for (int iFelix = 0; iFelix < NFlx; iFelix++)
1146     {
1147       hOccupancyPlot[aLayer][iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("OCC_Occupancy1D_Layer%d", aLayer)));
1148       hChipStaveOccupancy[aLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("OCC_OccupancyChipStave_Layer_%d", aLayer)));
1149     }
1150   }
1151 
1152 
1153   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1154   {
1155     mvtxmon_ChipStave1D[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_ChipStave1D"));
1156     mvtxmon_ChipFiredHis[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_ChipFiredFLX"));
1157     hChipStrobes[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_hChipStrobes"));
1158     hChipL1[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "General_ChipL1"));
1159   }
1160 
1161   for (int i = 0; i < 3; i++)
1162   {
1163     MergeServers<TH1D *>(hOccupancyPlot[i]);
1164     MergeServers<TH2D *>(hChipStaveOccupancy[i]);
1165   }
1166 
1167   TH2D *hChipStaveOccupancy_low[3] = {nullptr};
1168 
1169   for (int i = 0; i < 3; i++)
1170   {
1171     if (hOccupancyPlot[i][NFlx])
1172     {
1173       hOccupancyPlot[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1174       hOccupancyPlot[i][NFlx]->GetXaxis()->SetTitleSize(0.05);
1175       hOccupancyPlot[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1176       hOccupancyPlot[i][NFlx]->GetYaxis()->SetLabelSize(0.045);
1177       hOccupancyPlot[i][NFlx]->GetYaxis()->SetTitleSize(0.05);
1178       hOccupancyPlot[i][NFlx]->GetYaxis()->SetTitleOffset(1);
1179       hChipStaveOccupancy[i][NFlx]->SetMinimum(0);
1180     }
1181     if (hChipStaveOccupancy[i][NFlx])
1182     {
1183       hChipStaveOccupancy[i][NFlx]->GetXaxis()->SetLabelSize(0.05);
1184       hChipStaveOccupancy[i][NFlx]->GetXaxis()->SetTitleSize(0.05);
1185       hChipStaveOccupancy[i][NFlx]->GetXaxis()->SetTitleOffset(0.85);
1186       hChipStaveOccupancy[i][NFlx]->GetYaxis()->SetLabelSize(0.06);
1187       hChipStaveOccupancy[i][NFlx]->GetYaxis()->SetTitleSize(0.05);
1188       hChipStaveOccupancy[i][NFlx]->GetYaxis()->SetTitleOffset(0.7);
1189       hChipStaveOccupancy[i][NFlx]->SetContour(100);
1190 
1191       hChipStaveOccupancy_low[i] = (TH2D *) (hChipStaveOccupancy[i][NFlx])->Clone(Form("hChipStaveOccupancy_low_%d", i));
1192       TString tmp = "Chip Occupancy < 1\%";
1193       hChipStaveOccupancy_low[i]->SetTitle(tmp + Form(" of average occupancy in layer %d", i));
1194     }
1195   }
1196 
1197   MergeServers<TH1D *>(mvtxmon_ChipStave1D);
1198   MergeServers<TH1D *>(mvtxmon_ChipFiredHis);
1199   MergeServers<TH1I *>(hChipStrobes);
1200   MergeServers<TH1I *>(hChipL1);
1201 
1202   if (mvtxmon_ChipStave1D[NFlx])
1203   {
1204     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetLabelSize(0.05);
1205     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleSize(0.055);
1206     mvtxmon_ChipStave1D[NFlx]->GetXaxis()->SetTitleOffset(0.75);
1207     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetLabelSize(0.045);
1208     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleSize(0.06);
1209     mvtxmon_ChipStave1D[NFlx]->GetYaxis()->SetTitleOffset(1.2);
1210   }
1211 
1212   if (mvtxmon_ChipFiredHis[NFlx])
1213   {
1214     mvtxmon_ChipFiredHis[NFlx]->GetXaxis()->SetLabelSize(0.05);
1215     mvtxmon_ChipFiredHis[NFlx]->GetXaxis()->SetTitleSize(0.055);
1216     mvtxmon_ChipFiredHis[NFlx]->GetXaxis()->SetTitleOffset(0.75);
1217     mvtxmon_ChipFiredHis[NFlx]->GetYaxis()->SetLabelSize(0.06);
1218     mvtxmon_ChipFiredHis[NFlx]->GetYaxis()->SetTitleSize(0.06);
1219     mvtxmon_ChipFiredHis[NFlx]->GetYaxis()->SetTitleOffset(1.2);
1220   }
1221 
1222   double avr_occ[3] = {0};
1223 
1224   for (int iLayer = 0; iLayer < 3; iLayer++)
1225   {
1226     for (int iStave = 0; iStave < NStaves[iLayer]; iStave++)
1227     {
1228       for (int iChip = 0; iChip < 9; iChip++)
1229       {
1230         // double occ = hChipStaveOccupancy[iLayer][NFlx]->GetBinContent(iChip+1,iStave+1)/(hChipStrobes[NFlx]->GetBinContent((StaveBoundary[iLayer]+iStave)*9+iChip+1)*1024*512);
1231         double occ = hChipStaveOccupancy[iLayer][NFlx]->GetBinContent(iChip + 1, iStave + 1) / (hChipStrobes[NFlx]->GetBinContent((StaveBoundary[iLayer] + iStave) * 9 + iChip + 1) * 1024 * 512);
1232         if (occ > 10e-50)
1233         {
1234           hChipStaveOccupancy[iLayer][NFlx]->SetBinContent(iChip + 1, iStave + 1, occ);
1235         }
1236         if (occ > 10e-50)
1237         {
1238           avr_occ[iLayer] += occ;
1239         }
1240       }
1241     }
1242   }
1243 
1244   for (int iLayer = 0; iLayer < 3; iLayer++)
1245   {
1246     avr_occ[iLayer] /= (NStaves[iLayer] * 9);
1247     for (int iStave = 0; iStave < NStaves[iLayer]; iStave++)
1248     {
1249       for (int iChip = 0; iChip < 9; iChip++)
1250       {
1251         double occ = hChipStaveOccupancy[iLayer][NFlx]->GetBinContent(iChip + 1, iStave + 1);
1252         if (occ < 0.01 * avr_occ[iLayer])
1253         {
1254           hChipStaveOccupancy_low[iLayer]->SetBinContent(iChip + 1, iStave + 1, 1);
1255         }
1256         else
1257         {
1258           hChipStaveOccupancy_low[iLayer]->SetBinContent(iChip + 1, iStave + 1, 0);
1259         }
1260       }
1261     }
1262   }
1263 
1264   if (!gROOT->FindObject("MvtxMon_OCC"))
1265   {
1266     MakeCanvas("MvtxMon_OCC");
1267   }
1268 
1269   TC[canvasID]->SetEditable(true);
1270   TC[canvasID]->Clear("D");
1271   Pad[padID]->Divide(4, 3);
1272   Pad[padID]->cd(1)->SetLogy();
1273   Pad[padID]->cd(2)->SetLogy();
1274   Pad[padID]->cd(3)->SetLogy();
1275   Pad[padID]->cd(5)->SetRightMargin(0.15);
1276   Pad[padID]->cd(6)->SetRightMargin(0.15);
1277   Pad[padID]->cd(7)->SetRightMargin(0.15);
1278 
1279    //Pad[padID]->cd(1)->SetLogx();
1280   //[padID]->cd(2)->SetLogx();
1281   //Pad[padID]->cd(3)->SetLogx();
1282 
1283   hChipStaveOccupancy[0][NFlx]->GetZaxis()->SetTitle("");
1284   hChipStaveOccupancy[1][NFlx]->GetZaxis()->SetTitle("");
1285   hChipStaveOccupancy[2][NFlx]->GetZaxis()->SetTitle("");
1286 
1287 
1288   hChipStrobes[NFlx]->SetTitle("Chip Strobes (L1 triggers) vs Chip*Stave");
1289   hChipStrobes[NFlx]->GetYaxis()->SetTitle("Number of strobes");
1290 
1291   int returnCode = 0;
1292   returnCode += PublishHistogram(Pad[padID], 1, hOccupancyPlot[0][NFlx]);
1293   returnCode += PublishHistogram(Pad[padID], 2, hOccupancyPlot[1][NFlx]);
1294   returnCode += PublishHistogram(Pad[padID], 3, hOccupancyPlot[2][NFlx]);
1295   returnCode += PublishHistogram(Pad[padID], 5, hChipStaveOccupancy[0][NFlx], "colz");
1296   returnCode += PublishHistogram(Pad[padID], 6, hChipStaveOccupancy[1][NFlx], "colz");
1297   returnCode += PublishHistogram(Pad[padID], 7, hChipStaveOccupancy[2][NFlx], "colz");
1298   returnCode += PublishHistogram(Pad[padID], 9, hChipStaveOccupancy_low[0], "col");
1299   returnCode += PublishHistogram(Pad[padID], 10, hChipStaveOccupancy_low[1], "col");
1300   returnCode += PublishHistogram(Pad[padID], 11, hChipStaveOccupancy_low[2], "col");
1301   returnCode += PublishHistogram(Pad[padID], 4, mvtxmon_ChipStave1D[NFlx]);
1302   returnCode += PublishHistogram(Pad[padID], 8, mvtxmon_ChipFiredHis[NFlx]);
1303   returnCode += PublishHistogram(Pad[padID], 12, hChipStrobes[NFlx]);
1304 
1305   // for( int i = 1; i<= hChipL1[NFlx]->GetNbinsX();i++) std::cout<<hChipL1[NFlx]->GetBinContent(i)<<" ";
1306 
1307   Float_t rightmax = 2 * hChipL1[NFlx]->GetMaximum();
1308   Float_t scale = hChipStrobes[NFlx]->GetMaximum() / rightmax;
1309   hChipL1[NFlx]->SetLineColor(kRed);
1310   hChipL1[NFlx]->Scale(scale);
1311   // std::cout<<rightmax<<" "<<hChipStrobes[NFlx]->GetMaximum()<<" "<<scale<<std::endl;
1312   returnCode += PublishHistogram(Pad[padID], 12, hChipL1[NFlx], "same hist");
1313 
1314   TGaxis *axis = new TGaxis(48 * 9, 0, 48 * 9, hChipStrobes[NFlx]->GetMaximum(), 0, rightmax, 510, "+L");
1315   axis->SetLineColor(kRed);
1316   axis->SetLabelColor(kRed);
1317   axis->SetLabelFont(42);
1318   axis->SetTitleFont(42);
1319   axis->SetTitleColor(kRed);
1320   axis->SetTitle("Number of L1 triggers");
1321   axis->Draw();
1322 
1323   TPaveText *pt = new TPaveText(6, 12, 8.5, 13);
1324   pt->SetBorderSize(0);
1325   pt->SetFillStyle(0);
1326   TText *t1 = pt->AddText("Not saved in .root");
1327   t1->SetTextColor(kRed);
1328   Pad[padID]->cd(9);
1329   pt->Draw();
1330   Pad[padID]->cd(10);
1331   pt->Draw();
1332   Pad[padID]->cd(11);
1333   pt->Draw();
1334 
1335   PublishStatistics(canvasID, cl);
1336   TC[canvasID]->SetEditable(false);
1337   return returnCode < 0 ? -1 : 0;
1338 }
1339 
1340 int MvtxMonDraw::DrawFHR(const std::string & /* what */)
1341 {
1342   OnlMonClient *cl = OnlMonClient::instance();
1343   const int canvasID = 4;
1344   const int padID = 4;
1345 
1346   TH2D *mDeadChipPos[3][NFlx + 1] = {{nullptr}};
1347   //TH2D *mAliveChipPos[3][NFlx + 1] = {{nullptr}};
1348   // TH2D* mChipStaveOccupancy[3][NFlx];
1349   //TH1D *mOccupancyPlot[3][NFlx + 1] = {{nullptr}};
1350 
1351   TH2I *mErrorVsFeeid[NFlx + 1] = {nullptr};
1352   TH2Poly *mGeneralOccupancy[NFlx + 1] = {nullptr};
1353   TH2Poly *mGeneralNoisyPixel[NFlx + 1] = {nullptr};
1354   TH2D *mTotalDeadChipPos[NFlx + 1] = {nullptr};
1355   //TH2D *mTotalAliveChipPos[NFlx + 1] = {nullptr};
1356   TH1D *mvtxmon_EvtHitChip[NFlx + 1] = {nullptr};
1357   TH1D *mvtxmon_EvtHitDis[NFlx + 1] = {nullptr};
1358 
1359   TH1I *mRCDAQevt[NFlx + 1] = {nullptr};
1360 
1361   TH2D *mChipStaveNoisy[3][NFlx + 1]{{nullptr}};
1362 
1363   int nFLX[3] = {0};
1364 
1365   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1366   {
1367     mErrorVsFeeid[iFelix] = dynamic_cast<TH2I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_ErrorVsFeeid"));
1368     mGeneralOccupancy[iFelix] = dynamic_cast<TH2Poly *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_Occupancy"));
1369     mGeneralNoisyPixel[iFelix] = dynamic_cast<TH2Poly *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_General_Noisy_Pixel"));
1370     mTotalDeadChipPos[iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_Occupancy_TotalDeadChipPos"));
1371     //mTotalAliveChipPos[iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "MVTXMON_Occupancy_TotalAliveChipPos"));
1372     mvtxmon_EvtHitChip[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_HitChipPerStrobe"));
1373     mvtxmon_EvtHitDis[iFelix] = dynamic_cast<TH1D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "OCC_HitFLXPerStrobe"));
1374     mRCDAQevt[iFelix] = dynamic_cast<TH1I *>(cl->getHisto(Form("MVTXMON_%d", iFelix), "RCDAQ_evt"));
1375     for (int mLayer = 0; mLayer < 3; mLayer++)
1376     {
1377       mDeadChipPos[mLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("MVTXMON_Occupancy_Layer%d_Layer%dDeadChipPos", mLayer, mLayer)));
1378       if (mDeadChipPos[mLayer][iFelix])
1379       {
1380         nFLX[mLayer]++;
1381       }
1382       //mAliveChipPos[mLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("MVTXMON_Occupancy_Layer%d_Layer%dAliveChipPos", mLayer, mLayer)));
1383       // mChipStaveOccupancy[mLayer][iFelix] =  dynamic_cast<TH2D*>(cl->getHisto(Form("MVTXMON/Occupancy/Layer%d/Layer%dChipStaveC", mLayer, mLayer)));
1384 
1385       mChipStaveNoisy[mLayer][iFelix] = dynamic_cast<TH2D *>(cl->getHisto(Form("MVTXMON_%d", iFelix), Form("FHR_NoisyChipStave_Layer%d", mLayer)));
1386     }
1387   }
1388 
1389   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1390   {
1391     for (int mLayer = 0; mLayer < 3; mLayer++)
1392     {
1393       //if (mAliveChipPos[mLayer][iFelix] && mRCDAQevt[iFelix])
1394       //{
1395       //  mAliveChipPos[mLayer][iFelix]->Scale(1. / mRCDAQevt[iFelix]->Integral());
1396       //}
1397 
1398       if (mChipStaveNoisy[mLayer][iFelix] && mRCDAQevt[iFelix])
1399       {
1400         mChipStaveNoisy[mLayer][iFelix]->Scale(1. / mRCDAQevt[iFelix]->Integral());
1401       }
1402     }
1403   }
1404 
1405   for (int mLayer = 0; mLayer < 3; mLayer++)
1406   {
1407     MergeServers<TH2D *>(mDeadChipPos[mLayer]);
1408     //MergeServers<TH2D *>(mAliveChipPos[mLayer]);
1409     MergeServers<TH2D *>(mChipStaveNoisy[mLayer]);
1410     if (mDeadChipPos[mLayer][NFlx])
1411     {
1412       mDeadChipPos[mLayer][NFlx]->SetMinimum(0);
1413       mDeadChipPos[mLayer][NFlx]->SetMaximum(1);
1414     }
1415     /*if(mAliveChipPos[mLayer][NFlx]){
1416       mAliveChipPos[mLayer][NFlx]->SetMinimum(0);
1417       mAliveChipPos[mLayer][NFlx]->SetMaximum(1);
1418     }*/
1419   }
1420 
1421   MergeServers<TH2I *>(mErrorVsFeeid);
1422   MergeServers<TH2Poly *>(mGeneralOccupancy);
1423   MergeServers<TH2Poly *>(mGeneralNoisyPixel);
1424   MergeServers<TH2D *>(mTotalDeadChipPos);
1425   //MergeServers<TH2D *>(mTotalAliveChipPos);
1426   MergeServers<TH1D *>(mvtxmon_EvtHitChip);
1427   MergeServers<TH1D *>(mvtxmon_EvtHitDis);
1428   MergeServers<TH1I *>(mRCDAQevt);
1429 
1430   if (mTotalDeadChipPos[NFlx])
1431   {
1432     mTotalDeadChipPos[NFlx]->SetMinimum(0);
1433     mTotalDeadChipPos[NFlx]->SetMaximum(1);
1434   }
1435   /* if(mTotalAliveChipPos[NFlx]){
1436      mTotalAliveChipPos[NFlx]->SetMinimum(0);
1437      mTotalAliveChipPos[NFlx]->SetMaximum(1);
1438    }*/
1439 
1440   for (int mLayer = 0; mLayer < 3; mLayer++)
1441   {
1442     if (mDeadChipPos[mLayer][NFlx])
1443     {
1444       for (int binx = 0; binx < mDeadChipPos[mLayer][NFlx]->GetNbinsX(); binx++)
1445       {
1446         for (int biny = 0; biny < mDeadChipPos[mLayer][NFlx]->GetNbinsY(); biny++)
1447         {
1448           mDeadChipPos[mLayer][NFlx]->SetBinContent(binx + 1, biny + 1, mDeadChipPos[mLayer][NFlx]->GetBinContent(binx + 1, biny + 1) - nFLX[mLayer] + 1);
1449         }
1450       }
1451     }
1452   }
1453 
1454   if (!gROOT->FindObject("MvtxMon_FHR"))
1455   {
1456     MakeCanvas("MvtxMon_FHR");
1457   }
1458 
1459   TC[canvasID]->SetEditable(true);
1460   TC[canvasID]->Clear("D");
1461   Pad[padID]->Divide(3, 3);
1462 
1463   int returnCode = 0;
1464   // returnCode += PublishHistogram(Pad[padID],1,mErrorVsFeeid[0]);
1465   // returnCode += PublishHistogram(Pad[padID],6,mGeneralOccupancy[NFlx],"COLZ");
1466   returnCode += PublishHistogram(Pad[padID], 3, mGeneralNoisyPixel[NFlx], "COLZ", 0);
1467   returnCode += PublishHistogram(Pad[padID], 1, mDeadChipPos[0][NFlx], "COL");
1468   returnCode += PublishHistogram(Pad[padID], 4, mDeadChipPos[1][NFlx], "COL");
1469   returnCode += PublishHistogram(Pad[padID], 7, mDeadChipPos[2][NFlx], "COL");
1470   //returnCode += PublishHistogram(Pad[padID], 2, mAliveChipPos[0][NFlx], "COLZ");
1471   //returnCode += PublishHistogram(Pad[padID], 7, mAliveChipPos[1][NFlx], "COLZ");
1472   //sreturnCode += PublishHistogram(Pad[padID], 12, mAliveChipPos[2][NFlx], "COLZ");
1473   // returnCode += PublishHistogram<TH2D*>(TC[canvasID],10,mChipStaveOccupancy[0][0]);
1474   // returnCode += PublishHistogram<TH2D*>(TC[canvasID],11,mChipStaveOccupancy[1][0]);
1475   //  returnCode += PublishHistogram<TH2D*>(TC[canvasID],12,mChipStaveOccupancy[2][0]);
1476   returnCode += PublishHistogram(Pad[padID], 2, mChipStaveNoisy[0][NFlx], "COLZ");
1477   returnCode += PublishHistogram(Pad[padID], 5, mChipStaveNoisy[1][NFlx], "COLZ");
1478   returnCode += PublishHistogram(Pad[padID], 8, mChipStaveNoisy[2][NFlx], "COLZ");
1479   //returnCode += PublishHistogram(Pad[padID], 3, mOccupancyPlot[0][NFlx]);
1480   //returnCode += PublishHistogram(Pad[padID], 7, mOccupancyPlot[1][NFlx]);
1481   //returnCode += PublishHistogram(Pad[padID], 11, mOccupancyPlot[2][NFlx]);
1482 
1483   PublishHistogram(Pad[padID], 6, mvtxmon_EvtHitChip[NFlx]);
1484   PublishHistogram(Pad[padID], 9, mvtxmon_EvtHitDis[NFlx]);
1485 
1486   // returnCode += PublishHistogram(Pad[11],16,mTotalDeadChipPos[NFlx],"COL");
1487   // returnCode += PublishHistogram(Pad[11],17,mTotalAliveChipPos[NFlx],"COL");
1488 
1489   PublishStatistics(canvasID, cl);
1490   TC[canvasID]->SetEditable(false);
1491   return returnCode < 0 ? -1 : 0;
1492 }
1493 
1494 int MvtxMonDraw::SavePlot(const std::string &what, const std::string &type)
1495 {
1496   OnlMonClient *cl = OnlMonClient::instance();
1497   int iret = Draw(what);
1498   if (iret)  // on error no png files please
1499   {
1500     return iret;
1501   }
1502   int icnt = 0;
1503   for (TCanvas *canvas : TC)
1504   {
1505     if (canvas == nullptr)
1506     {
1507       continue;
1508     }
1509     icnt++;
1510     std::string filename = ThisName + "_" + std::to_string(icnt) + "_" +
1511                            std::to_string(cl->RunNumber()) + "." + type;
1512     cl->CanvasToPng(canvas, filename);
1513   }
1514   return 0;
1515 }
1516 
1517 int MvtxMonDraw::MakeHtml(const std::string &what)
1518 {
1519   int iret = Draw(what);
1520   if (iret)  // on error no html output please
1521   {
1522     return iret;
1523   }
1524 
1525   OnlMonClient *cl = OnlMonClient::instance();
1526 
1527   int icnt = 0;
1528   for (TCanvas *canvas : TC)
1529   {
1530     if (canvas == nullptr)
1531     {
1532       continue;
1533     }
1534     icnt++;
1535     // Register the canvas png file to the menu and produces the png file.
1536     std::string pngfile = cl->htmlRegisterPage(*this, canvas->GetTitle(), std::to_string(icnt), "png");
1537     cl->CanvasToPng(canvas, pngfile);
1538   }
1539   // Now register also EXPERTS html pages, under the EXPERTS subfolder.
1540 
1541   // std::string logfile = cl->htmlRegisterPage(*this, "EXPERTS/Log", "log", "html");
1542   // std::ofstream out(logfile.c_str());
1543   // out << "<HTML><HEAD><TITLE>Log file for run " << cl->RunNumber()
1544   //     << "</TITLE></HEAD>" << std::endl;
1545   // out << "<P>Some log file output would go here." << std::endl;
1546   // out.close();
1547 
1548   // std::string status = cl->htmlRegisterPage(*this, "EXPERTS/Status", "status", "html");
1549   // std::ofstream out2(status.c_str());
1550   // out2 << "<HTML><HEAD><TITLE>Status file for run " << cl->RunNumber()
1551   //      << "</TITLE></HEAD>" << std::endl;
1552   // out2 << "<P>Some status output would go here." << std::endl;
1553   // out2.close();
1554   // cl->SaveLogFile(*this);
1555   return 0;
1556 }
1557 
1558 int MvtxMonDraw::DrawHistory(const std::string & /* what */)
1559 {
1560   const int canvasID = 5;
1561   const int padID = 5;
1562 
1563   int iret[NFlx] = {0, 0, 0, 0, 0, 0};
1564   // you need to provide the following vectors
1565   // which are filled from the db
1566   std::vector<float> var[NFlx];
1567   std::vector<float> varerr[NFlx];
1568   std::vector<time_t> timestamp[NFlx];
1569   std::vector<int> runnumber[NFlx];
1570   std::string varname = "n_events";
1571   // this sets the time range from whihc values should be returned
1572   time_t begin = 0;            // begin of time (1.1.1970)
1573   time_t end = time(nullptr);  // current time (right NOW)
1574 
1575   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1576   {
1577     iret[iFelix] = dbvars[iFelix]->GetVar(begin, end, varname, timestamp[iFelix], runnumber[iFelix], var[iFelix], varerr[iFelix]);
1578     if (iret[iFelix])
1579     {
1580       std::cout << __PRETTY_FUNCTION__ << " Error in db access: FELIX " << iFelix << std::endl;
1581       // return iret;
1582     }
1583   }
1584 
1585   if (!gROOT->FindObject("MvtxMon3"))
1586   {
1587     MakeCanvas("MvtxMon3");
1588   }
1589   TC[canvasID]->SetEditable(true);
1590   TC[canvasID]->Clear("D");
1591   Pad[padID]->Divide(3, 2);
1592 
1593   for (int iFelix = 0; iFelix < NFlx; iFelix++)
1594   {
1595     // timestamps come sorted in ascending order
1596     float *x = new float[var[iFelix].size()];
1597     float *y = new float[var[iFelix].size()];
1598     float *ex = new float[var[iFelix].size()];
1599     float *ey = new float[var[iFelix].size()];
1600     int n = var[iFelix].size();
1601     for (unsigned int i = 0; i < var[iFelix].size(); i++)
1602     {
1603       //       std::cout << "timestamp: " << ctime(&timestamp[i])
1604       //       << ", run: " << runnumber[i]
1605       //       << ", var: " << var[i]
1606       //       << ", varerr: " << varerr[i]
1607       //       << std::endl;
1608       x[i] = timestamp[iFelix][i] - TimeOffsetTicks;
1609       y[i] = var[iFelix][i];
1610       ex[i] = 0;
1611       ey[i] = varerr[iFelix][i];
1612     }
1613     Pad[padID]->cd(iFelix + 1);
1614     if (gr[iFelix])
1615     {
1616       delete gr[iFelix];
1617     }
1618     gr[iFelix] = new TGraphErrors(n, x, y, ex, ey);
1619     gr[iFelix]->SetMarkerColor(4);
1620     gr[iFelix]->SetMarkerStyle(21);
1621     gr[iFelix]->Draw("ALP");
1622     gr[iFelix]->GetXaxis()->SetTimeDisplay(1);
1623     gr[iFelix]->GetXaxis()->SetLabelSize(0.03);
1624     // the x axis labeling looks like crap
1625     // please help me with this, the SetNdivisions
1626     // don't do the trick
1627     gr[iFelix]->GetXaxis()->SetNdivisions(-1006);
1628     gr[iFelix]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
1629     gr[iFelix]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
1630     delete[] x;
1631     delete[] y;
1632     delete[] ex;
1633     delete[] ey;
1634   }
1635 
1636   /* varname = "mvtxmoncount";
1637    iret = dbvars->GetVar(begin, end, varname, timestamp, runnumber, var, varerr);
1638    if (iret)
1639    {
1640      std::cout << __PRETTY_FUNCTION__ << " Error in db access" << std::endl;
1641      return iret;
1642    }
1643    x = new float[var.size()];
1644    y = new float[var.size()];
1645    ex = new float[var.size()];
1646    ey = new float[var.size()];
1647    n = var.size();
1648    for (unsigned int i = 0; i < var.size(); i++)
1649    {
1650      //       std::cout << "timestamp: " << ctime(&timestamp[i])
1651      //        << ", run: " << runnumber[i]
1652      //        << ", var: " << var[i]
1653      //        << ", varerr: " << varerr[i]
1654      //        << std::endl;
1655      x[i] = timestamp[i] - TimeOffsetTicks;
1656      y[i] = var[i];
1657      ex[i] = 0;
1658      ey[i] = varerr[i];
1659    }
1660    Pad[6]->cd();
1661    if (gr[1])
1662    {
1663      delete gr[1];
1664    }
1665    gr[1] = new TGraphErrors(n, x, y, ex, ey);
1666    gr[1]->SetMarkerColor(4);
1667    gr[1]->SetMarkerStyle(21);
1668    gr[1]->Draw("ALP");
1669    gr[1]->GetXaxis()->SetTimeDisplay(1);
1670    // TC[2]->Update();
1671    //    h1->GetXaxis()->SetTimeDisplay(1);
1672    //    h1->GetXaxis()->SetLabelSize(0.03);
1673    gr[1]->GetXaxis()->SetLabelSize(0.03);
1674    gr[1]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
1675    gr[1]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
1676    //    h1->Draw();
1677    delete[] x;
1678    delete[] y;
1679    delete[] ex;
1680    delete[] ey;*/
1681 
1682   TC[canvasID]->Update();
1683   TC[canvasID]->SetEditable(false);
1684   return 0;
1685 }
1686 
1687 void MvtxMonDraw::setPalDefault()
1688 {
1689     gStyle->SetPalette(1);
1690 }
1691 
1692 void MvtxMonDraw::setPalUser()
1693 {
1694    const int numColorsUser = 3;
1695    int colorsUser[numColorsUser] = {
1696         TColor::GetColor(0, 255, 0), //green
1697         TColor::GetColor(255, 255, 0), //yellow
1698         TColor::GetColor(255, 0, 0) //red
1699    };
1700 
1701    gStyle->SetPalette(numColorsUser, colorsUser);
1702 }
1703 
1704 // template <typename T>
1705 int MvtxMonDraw::PublishHistogram(TCanvas *c, int pad, TH1 *h, const char *opt, int palettestyle)
1706 {
1707   if (c && pad != 0)
1708   {
1709     c->cd(pad);
1710     // std::cout<<"ups"<<std::endl;
1711   }
1712   if (h)
1713   {
1714     if (palettestyle==0)
1715     {
1716       h->DrawCopy(opt);
1717       TExec *ex1 = new TExec("ex1","MvtxMonDraw::setPalDefault();");
1718       ex1->Draw();
1719       h->DrawCopy(opt);
1720     }
1721     else if (palettestyle==1)
1722     {
1723       h->SetMinimum(-1/48);
1724       h->SetMaximum(1200/48);
1725       // palette only for noisy pixel
1726       h->DrawCopy(opt);
1727       const int numLevels = 3;
1728       double levels[numLevels] = { 0, 200/48, 1000/48 };
1729       h->SetContour(numLevels, levels);
1730       h->SetMarkerSize(2);
1731       TExec *ex1 = new TExec("ex1","MvtxMonDraw::setPalUser();");
1732       ex1->Draw();
1733       h->DrawCopy(opt);
1734     }
1735     else if (palettestyle==2)
1736     {
1737       h->SetMinimum(0);
1738       h->SetMaximum(1);
1739       h->DrawCopy(opt);
1740       const int numLevels = 3;
1741       double levels[numLevels] = { 0, 0.11, 0.22 };
1742       h->SetContour(numLevels, levels);
1743       TExec *ex1 = new TExec("ex1","MvtxMonDraw::setPalUser();");
1744       ex1->Draw();
1745       h->DrawCopy(opt);
1746     }
1747     else
1748     {
1749       h->DrawCopy(opt);
1750     }
1751     return 0;
1752   }
1753   else
1754   {
1755     // DrawDeadServer(transparent[0]);
1756     return -1;
1757   }
1758 }
1759 
1760 // template <typename T>
1761 int MvtxMonDraw::PublishHistogram(TPad *p, int pad, TH1 *h, const char *opt, int palettestyle)
1762 {
1763   if (p && pad != 0)
1764   {
1765     p->cd(pad);
1766     TCanvas *c = nullptr;
1767     return PublishHistogram(c, 0, h, opt, palettestyle);
1768   }
1769   else
1770   {
1771     return -1;
1772   }
1773 }
1774 
1775 // template <typename T>
1776 int MvtxMonDraw::PublishHistogram(TPad *p, TH1 *h, const char *opt, int palettestyle)
1777 {
1778   if (p)
1779   {
1780     p->cd();
1781     TCanvas *c = nullptr;
1782     return PublishHistogram(c, 0, h, opt, palettestyle);
1783   }
1784 
1785   else
1786   {
1787     return -1;
1788   }
1789 }
1790 
1791 template <typename T>
1792 int MvtxMonDraw::MergeServers(T *h)
1793 {
1794   bool cloned = false;
1795   unsigned int bitset = 0;
1796   for (unsigned int iFelix = 0; iFelix < NFlx; iFelix++)
1797   {
1798     if (cloned == false)
1799     {
1800       if (h[iFelix])
1801       {
1802         h[NFlx] = dynamic_cast<T>(h[iFelix]->Clone());
1803         bitset |= (1U << (iFelix));
1804         cloned = true;
1805       }
1806       else
1807       {
1808         continue;
1809       }
1810     }
1811     else
1812     {
1813       if (h[iFelix])
1814       {
1815         h[NFlx]->Add(h[iFelix], 1.);
1816         bitset |= (1U << (iFelix));
1817       }
1818     }
1819   }
1820   return bitset;
1821 }
1822 
1823 void MvtxMonDraw::PublishStatistics(int canvasID, OnlMonClient *cl)
1824 {
1825   TC[canvasID]->cd();
1826   TText PrintRun;
1827   PrintRun.SetTextFont(62);
1828   PrintRun.SetTextSize(0.04);
1829   PrintRun.SetNDC();          // set to normalized coordinates
1830   PrintRun.SetTextAlign(23);  // center/top alignment
1831   std::ostringstream runnostream;
1832   std::string runstring;
1833   std::pair<time_t,int> evttime = cl->EventTime("CURRENT");
1834   // fill run number and event time into string
1835   runnostream << ThisName << "_1 Run " << cl->RunNumber()
1836               << ", Time: " << ctime(&evttime.first);
1837   runstring = runnostream.str();
1838   transparent[canvasID]->cd();
1839   PrintRun.SetTextColor(evttime.second);
1840   PrintRun.DrawText(0.5, 1., runstring.c_str());
1841   TC[canvasID]->Update();
1842   TC[canvasID]->Show();
1843 }
1844 
1845 void MvtxMonDraw::formatPaveText(TPaveText *aPT, float aTextSize, Color_t aTextColor, short aTextAlign, const char *aText)
1846 {
1847   aPT->SetTextSize(aTextSize);
1848   aPT->SetTextAlign(aTextAlign);
1849   aPT->SetFillColor(0);
1850   aPT->SetTextAlign(22);
1851   aPT->SetTextColor(aTextColor);
1852   aPT->AddText(aText);
1853 }
1854 
1855 std::vector<MvtxMonDraw::Quality> MvtxMonDraw::analyseForError(TH2Poly *lane, TH2Poly *noisy, TH1 *strobes, TH1 *decErr, TH1 *decErrTime, TH1 *DMAstat)
1856 {
1857   std::vector<Quality> result;
1858 
1859   for (int i = 0; i < 19; i++)
1860   {
1861     result.push_back(Quality::Good);
1862   }
1863 
1864   // count dead staves
1865   for (int ilayer = 0; ilayer < NLAYERS; ilayer++)
1866   {
1867     int countStave = 0;
1868     for (int ibin = StaveBoundary[ilayer] + 1; ibin <= StaveBoundary[ilayer + 1]; ++ibin)
1869     {
1870       double bincontent = 0;
1871       if (lane)
1872       {
1873         bincontent = lane->GetBinContent(ibin);
1874       }
1875       
1876       if (bincontent /*hp[iflag][NFlx]->GetBinContent(ibin)*/ >= maxbadchips / 9.)
1877       {
1878         // std::cout<<"bad stave"<<std::endl;
1879         countStave++;
1880         result.at(ilayer) = Quality::Medium;
1881       }
1882     }
1883     if (countStave > 0.2 * NStaves[ilayer])
1884     {
1885       result.at(ilayer) = Quality::Bad;
1886     }
1887   }
1888   
1889   // noisy pixels
1890   double noisypix = 0;
1891 
1892   for (int ilayer = 0; ilayer < NLAYERS; ilayer++)
1893   {
1894     for (int ibin = StaveBoundary[ilayer] + 1; ibin <= StaveBoundary[ilayer + 1]; ++ibin)
1895     {
1896       if (noisy)
1897       {
1898         noisypix = noisy->GetBinContent(ibin);
1899       }
1900     }
1901   }
1902   if(noisypix > 200 && noisypix < 2000){
1903     result.at(3) = Quality::Medium;
1904   }
1905   if(noisypix > 2000){
1906     result.at(3) = Quality::Bad;
1907   }
1908 
1909   if (strobes){
1910     double mins = 100000000;
1911     double avrs = 0;
1912     double maxs = 0;
1913     for (int ibin = 1; ibin <= strobes->GetNbinsX(); ibin++){
1914       double binc = static_cast<double>(strobes->GetBinContent(ibin));
1915       if(mins > binc) mins = binc;
1916       if(maxs < binc) maxs = binc;
1917       avrs += binc;
1918     }
1919     if(strobes->GetNbinsX() > 0) avrs = avrs/strobes->GetNbinsX();
1920     if(mins < 0.3*avrs || maxs > 1.7*avrs){
1921       result.at(4) = Quality::Medium;
1922     }
1923   }
1924 
1925   if (decErr)
1926   {
1927     for (int iflx = 0; iflx < 6; iflx++)
1928     {
1929       if (decErr->Integral(2 * iflx + 1, 2 * iflx + 1) > 0)
1930       {
1931         result.at(5 + 2 * iflx) = Quality::Medium;
1932       }
1933       if (decErr->Integral(2 * iflx + 2, 2 * iflx + 2) > 0)
1934       {
1935         result.at(5 + 2 * iflx + 1) = Quality::Medium;
1936       }
1937     }
1938   }
1939 
1940   if (decErrTime)
1941   {
1942     if (decErrTime->Integral(decErrTime->GetNbinsX() - 10, decErrTime->GetNbinsX()) > 0)
1943     {
1944       result.at(18) = Quality::Bad;
1945     }
1946   }
1947 
1948   if(DMAstat)
1949   {
1950     double integral = DMAstat->Integral();
1951 
1952     if (integral == 11)
1953     {
1954       result.at(17) = Quality::Medium;
1955     }
1956     else if (integral <= 10)
1957     {
1958       result.at(17) = Quality::Bad;
1959     }
1960   }
1961 
1962   return result;
1963 
1964   /* if (mo->getName() == Form("LaneStatus/laneStatusFlag%s", mLaneStatusFlag[iflag].c_str())) {
1965      result = Quality::Good;
1966      auto* h = dynamic_cast<TH2I*>(mo->getObject());
1967      if (h->GetMaximum() > 0) {
1968        result.set(Quality::Bad);
1969      }
1970    }*/
1971   // if (mo->getName() == Form("LaneStatus/laneStatusOverviewFlag%s", mLaneStatusFlag[iflag].c_str())) {
1972   /*   result.at(iflag) = Quality.Good;
1973      auto* hp = dynamic_cast<TH2Poly*>(mo->getObject());
1974      badStave = false;
1975      // Initialization of metaData for IB, ML, OL
1976      for (int ilayer = 0; ilayer < NLAYERS; ilayer++) {
1977        int countStave = 0;
1978        badStaveCount = false;
1979        for (int ibin = StaveBoundary[ilayer] + 1; ibin <= StaveBoundary[ilayer + 1]; ++ibin) {
1980            // Check if there are staves in the IB with lane in Bad (bins are filled with %)
1981            if (hp->GetBinContent(ibin) > maxbadchips / 9.) {
1982              badStave = true;
1983              result.at(iflag) = Quality.Medium;
1984              countStave++;
1985            }
1986        } // end loop bins (staves)
1987        // Initialize metadata for the 7 layers
1988        result.addMetadata(Form("Layer%d", ilayer), "good");
1989        // Check if there are more than 25% staves in Bad per layer
1990        if (countStave > 0.25 * NStaves[ilayer]) {
1991          badStaveCount = true;
1992          result.updateMetadata(Form("Layer%d", ilayer), "bad");
1993        }
1994      } // end loop over layers
1995      if (badStave) {
1996        result.at(iflag) = Quality.Medium;
1997      }
1998      if (badStaveCount) {
1999        result.at(iflag) = Quality.Bad;
2000      }
2001   // } // end lanestatusOverview
2002  }*/
2003 }
2004 
2005 void MvtxMonDraw::DrawPave(std::vector<MvtxMonDraw::Quality> status, int position, const char * /* what*/)
2006 {
2007   TPaveText *pt = new TPaveText(.4, .4, .6, .6, "blNDC");
2008   pt->SetTextSize(0.04);
2009   pt->SetFillColor(0);
2010   pt->SetLineColor(0);
2011   pt->SetBorderSize(1);
2012   if (status.at(position) == Quality::Good && status.at(position + 1) == Quality::Good && status.at(position + 2) == Quality::Good)
2013   {
2014     pt->AddText("#color[418]{QA OK}");
2015   }
2016   if (status.at(position) == Quality::Medium)
2017   {
2018     pt->AddText("#color[808]{QA Layer 0 Medium}");
2019   }
2020   if (status.at(position + 1) == Quality::Medium)
2021   {
2022     pt->AddText("#color[808]{QA Layer 1 Medium}");
2023   }
2024   if (status.at(position + 2) == Quality::Medium)
2025   {
2026     pt->AddText("#color[808]{QA Layer 2 Medium}");
2027   }
2028   if (status.at(position) == Quality::Bad)
2029   {
2030     pt->AddText("#color[2]{QA Layer 0 Bad}");
2031   }
2032   if (status.at(position + 1) == Quality::Bad)
2033   {
2034     pt->AddText("#color[2]{QA Layer 1 Bad}");
2035   }
2036   if (status.at(position + 2) == Quality::Bad)
2037   {
2038     pt->AddText("#color[2]{QA Layer 2 Bad}");
2039   }
2040   pt->Draw();
2041 }
2042 
2043 int MvtxMonDraw::DrawServerStats()
2044 {
2045   OnlMonClient *cl = OnlMonClient::instance();
2046   if (!gROOT->FindObject("MvtxMonServerStats"))
2047   {
2048     MakeCanvas("MvtxMonServerStats");
2049   }
2050   TC[6]->Clear("D");
2051   TC[6]->SetEditable(true);
2052   transparent[6]->cd();
2053   TText PrintRun;
2054   PrintRun.SetTextFont(62);
2055   PrintRun.SetNDC();          // set to normalized coordinates
2056   PrintRun.SetTextAlign(23);  // center/top alignment
2057   PrintRun.SetTextSize(0.04);
2058   PrintRun.SetTextColor(1);
2059   PrintRun.DrawText(0.5, 0.99, "Server Statistics");
2060 
2061   PrintRun.SetTextSize(0.02);
2062   double vdist = 0.05;
2063   double vpos = 0.9;
2064   for (const auto &server : m_ServerSet)
2065   {
2066     std::ostringstream txt;
2067     auto servermapiter = cl->GetServerMap(server);
2068     if (servermapiter == cl->GetServerMapEnd())
2069     {
2070       txt << "Server " << server
2071           << " is dead ";
2072       PrintRun.SetTextColor(kRed);
2073     }
2074     else
2075     {
2076       txt << "Server " << server
2077           << ", run number " << std::get<1>(servermapiter->second)
2078           << ", event count: " << std::get<2>(servermapiter->second)
2079           << ", current time " << ctime(&(std::get<3>(servermapiter->second)));
2080       if (std::get<0>(servermapiter->second))
2081       {
2082         PrintRun.SetTextColor(kGray+2);
2083       }
2084       else
2085       {
2086         PrintRun.SetTextColor(kRed);
2087       }
2088     }
2089     PrintRun.DrawText(0.5, vpos, txt.str().c_str());
2090     vpos -= vdist;
2091   }
2092   TC[6]->Update();
2093   TC[6]->Show();
2094   TC[6]->SetEditable(false);
2095 
2096   return 0;
2097 }