Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-04-03 08:16:42

0001 #include "SpinMonDraw.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 <TDatime.h>
0009 #include <TGraphErrors.h>
0010 #include <TH1.h>
0011 #include <TH2.h>
0012 #include <TH2I.h>
0013 #include <TLatex.h>
0014 #include <TLegend.h>
0015 #include <TLine.h>
0016 #include <TPad.h>
0017 #include <TROOT.h>
0018 #include <TStyle.h>
0019 #include <TSystem.h>
0020 #include <TText.h>
0021 
0022 #include <cstring>  // for memset
0023 #include <ctime>
0024 #include <fstream>
0025 #include <iostream>  // for operator<<, basic_ostream, basic_os...
0026 #include <sstream>
0027 #include <vector>  // for vector
0028 
0029 // triggermap
0030 enum
0031 {
0032   MBD_NS = 0,
0033   MBD_VTX = 1,
0034   MBD_10cm_VTX = 2,
0035   MBD_S = 3,
0036   MBD_N = 4,
0037   ZDC_NS = 5,
0038   ZDC_S = 6,
0039   ZDC_N = 7,
0040   EMPTY1 = 8,
0041   EMPTY2 = 9,
0042   EMPTY3 = 10,
0043   EMPTY4 = 11,
0044   EMPTY5 = 12,
0045   EMPTY6 = 13,
0046   EMPTY7 = 14,
0047   EMPTY8 = 15
0048 };
0049 
0050 SpinMonDraw::SpinMonDraw(const std::string &name)
0051   : OnlMonDraw(name)
0052 {
0053   return;
0054 }
0055 
0056 int SpinMonDraw::Init()
0057 {
0058   preset_pattern_blue["111x111_P1"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0059   preset_pattern_yellow["111x111_P1"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0060   preset_pattern_blue["111x111_P2"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0061   preset_pattern_yellow["111x111_P2"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0062   preset_pattern_blue["111x111_P3"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0063   preset_pattern_yellow["111x111_P3"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0064   preset_pattern_blue["111x111_P4"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0065   preset_pattern_yellow["111x111_P4"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0066   preset_pattern_blue["111x111_P5"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0067   preset_pattern_yellow["111x111_P5"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0068   preset_pattern_blue["111x111_P6"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0069   preset_pattern_yellow["111x111_P6"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0070   preset_pattern_blue["111x111_P7"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0071   preset_pattern_yellow["111x111_P7"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0072   preset_pattern_blue["111x111_P8"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0073   preset_pattern_yellow["111x111_P8"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0074 
0075   return 0;
0076 }
0077 
0078 int SpinMonDraw::MakeCanvas(const std::string &name)
0079 {
0080   OnlMonClient *cl = OnlMonClient::instance();
0081   int xsize = cl->GetDisplaySizeX();
0082   int ysize = cl->GetDisplaySizeY();
0083   if (name == "SpinMon1")
0084   {
0085     // xpos (-1) negative: do not draw menu bar
0086     TC[0] = new TCanvas(name.c_str(), "SpinMon Shift Crew", -1, ysize, xsize * 0.95, ysize);
0087     // root is pathetic, whenever a new TCanvas is created root piles up
0088     // 6kb worth of X11 events which need to be cleared with
0089     // gSystem->ProcessEvents(), otherwise your process will grow and
0090     // grow and grow but will not show a definitely lost memory leak
0091     gSystem->ProcessEvents();
0092     Pad[0] = new TPad("spinpad1", "who needs this?", 0.01, 0.8, 0.99, 0.95, 0);
0093     Pad[1] = new TPad("spinpad2", "who needs this?", 0.01, 0.65, 0.99, 0.8, 0);
0094     Pad[2] = new TPad("spinpad3", "who needs this?", 0.65, 0.05, 0.95, 0.6, 0);
0095     Pad[3] = new TPad("spinpad4", "who needs this?", 0.05, 0.35, 0.35, 0.65, 0);
0096     Pad[4] = new TPad("spinpad5", "who needs this?", 0.35, 0.35, 0.65, 0.65, 0);
0097     Pad[5] = new TPad("spinpad6", "who needs this?", 0.05, 0.05, 0.35, 0.35, 0);
0098     Pad[6] = new TPad("spinpad7", "who needs this?", 0.35, 0.05, 0.65, 0.35, 0);
0099 
0100     Pad[0]->Draw();
0101     Pad[1]->Draw();
0102     Pad[2]->Draw();
0103     Pad[3]->Draw();
0104     Pad[4]->Draw();
0105     Pad[5]->Draw();
0106     Pad[6]->Draw();
0107 
0108     // this one is used to plot the run number on the canvas
0109     transparent[0] = new TPad("transparent0", "this does not show", 0, 0, 1, 1);
0110     transparent[0]->SetFillStyle(4000);
0111     transparent[0]->Draw();
0112     TC[0]->SetEditable(false);
0113   }
0114   else if (name == "SpinMon2")
0115   {
0116     // xpos negative: do not draw menu bar
0117     TC[1] = new TCanvas(name.c_str(), "SpinMon Experts", -1, ysize, xsize * 0.95, ysize);
0118     gSystem->ProcessEvents();
0119 
0120     Pad[7] = new TPad("spinpad8", "who needs this?", 0.05, 0.725, 0.35, 0.95, 0);
0121     Pad[8] = new TPad("spinpad9", "who needs this?", 0.35, 0.725, 0.65, 0.95, 0);
0122     Pad[9] = new TPad("spinpad10", "who needs this?", 0.65, 0.725, 0.95, 0.95, 0);
0123     Pad[10] = new TPad("spinpad11", "who needs this?", 0.05, 0.50, 0.35, 0.725, 0);
0124     Pad[11] = new TPad("spinpad12", "who needs this?", 0.35, 0.50, 0.65, 0.725, 0);
0125     Pad[12] = new TPad("spinpad13", "who needs this?", 0.65, 0.50, 0.95, 0.725, 0);
0126 
0127     Pad[13] = new TPad("spinpad14", "who needs this?", 0.05, 0.3875, 0.275, 0.5, 0);
0128     Pad[14] = new TPad("spinpad15", "who needs this?", 0.275, 0.3875, 0.5, 0.5, 0);
0129     Pad[15] = new TPad("spinpad16", "who needs this?", 0.5, 0.3875, 0.725, 0.5, 0);
0130     Pad[16] = new TPad("spinpad17", "who needs this?", 0.725, 0.3875, 0.95, 0.5, 0);
0131     Pad[17] = new TPad("spinpad18", "who needs this?", 0.05, 0.275, 0.275, 0.3875, 0);
0132     Pad[18] = new TPad("spinpad19", "who needs this?", 0.275, 0.275, 0.5, 0.3875, 0);
0133     Pad[19] = new TPad("spinpad20", "who needs this?", 0.5, 0.275, 0.725, 0.3875, 0);
0134     Pad[20] = new TPad("spinpad21", "who needs this?", 0.725, 0.275, 0.95, 0.3875, 0);
0135     Pad[21] = new TPad("spinpad22", "who needs this?", 0.05, 0.1625, 0.275, 0.275, 0);
0136     Pad[22] = new TPad("spinpad23", "who needs this?", 0.275, 0.1625, 0.5, 0.275, 0);
0137     Pad[23] = new TPad("spinpad24", "who needs this?", 0.5, 0.1625, 0.725, 0.275, 0);
0138     Pad[24] = new TPad("spinpad25", "who needs this?", 0.725, 0.1625, 0.95, 0.275, 0);
0139     Pad[25] = new TPad("spinpad26", "who needs this?", 0.05, 0.05, 0.275, 0.1625, 0);
0140     Pad[26] = new TPad("spinpad27", "who needs this?", 0.275, 0.05, 0.5, 0.1625, 0);
0141     Pad[27] = new TPad("spinpad28", "who needs this?", 0.5, 0.05, 0.725, 0.1625, 0);
0142     Pad[28] = new TPad("spinpad29", "who needs this?", 0.725, 0.05, 0.95, 0.1625, 0);
0143 
0144     Pad[7]->Draw();
0145     Pad[8]->Draw();
0146     Pad[9]->Draw();
0147     Pad[10]->Draw();
0148     Pad[11]->Draw();
0149     Pad[12]->Draw();
0150     Pad[13]->Draw();
0151     Pad[14]->Draw();
0152     Pad[15]->Draw();
0153     Pad[16]->Draw();
0154     Pad[17]->Draw();
0155     Pad[18]->Draw();
0156     Pad[19]->Draw();
0157     Pad[20]->Draw();
0158     Pad[21]->Draw();
0159     Pad[22]->Draw();
0160     Pad[23]->Draw();
0161     Pad[24]->Draw();
0162     Pad[25]->Draw();
0163     Pad[26]->Draw();
0164     Pad[27]->Draw();
0165     Pad[28]->Draw();
0166     // this one is used to plot the run number on the canvas
0167     transparent[1] = new TPad("transparent1", "this does not show", 0, 0, 1, 1);
0168     transparent[1]->SetFillStyle(4000);
0169     transparent[1]->Draw();
0170     TC[1]->SetEditable(false);
0171   } else if (name == "SpinMon3")
0172   {
0173     TC[2] = new TCanvas(name.c_str(), "SpinMon Bunch Numbers", -1, ysize, xsize * 0.95, ysize);
0174     gSystem->ProcessEvents();
0175 
0176     Pad[29] = new TPad("spinpad30", "who needs this?", 0.05, 0.05, 0.95, 0.95, 0);
0177     Pad[29]->Draw();
0178 
0179     // this one is used to plot the run number on the canvas
0180     transparent[2] = new TPad("transparent2", "this does not show", 0, 0, 1, 1);
0181     transparent[2]->SetFillStyle(4000);
0182     transparent[2]->Draw();
0183     TC[2]->SetEditable(false);
0184   }
0185   return 0;
0186 }
0187 
0188 int SpinMonDraw::Draw(const std::string &what)
0189 {
0190   int iret = 0;
0191   int idraw = 0;
0192 
0193   if (what == "ALL" || what == "FIRST")
0194   {
0195     iret += DrawFirst(what);
0196     idraw++;
0197   }
0198   if (what == "ALL" || what == "SECOND")
0199   {
0200     iret += DrawSecond(what);
0201     idraw++;
0202   }
0203   if (what == "ALL" || what == "THIRD")
0204   {
0205     iret += DrawThird(what);
0206     idraw++;
0207   }
0208   if (!idraw)
0209   {
0210     std::cout << __PRETTY_FUNCTION__ << " Unimplemented Drawing option: " << what << std::endl;
0211     iret = -1;
0212   }
0213   return iret;
0214 }
0215 
0216 int SpinMonDraw::DrawFirst(const std::string & /* what */)
0217 {
0218   // const int NTRIG = 16;
0219 
0220   OnlMonClient *cl = OnlMonClient::instance();
0221 
0222   TH1 *hpCspinpatternBlue = cl->getHisto("SPINMON_0", "h1_pCspinpatternBlue");
0223   TH1 *hpCspinpatternYellow = cl->getHisto("SPINMON_0", "h1_pCspinpatternYellow");
0224   TH1 *hspinpatternBlue = cl->getHisto("SPINMON_0", "h1_spinpatternBlue");
0225   TH1 *hspinpatternYellow = cl->getHisto("SPINMON_0", "h1_spinpatternYellow");
0226 
0227   TH2I *pCspinpatternBlueUp = (TH2I *) cl->getHisto("SPINMON_0", "h2_pCspinpatternBlueUp");
0228   TH2I *pCspinpatternBlueDown = (TH2I *) cl->getHisto("SPINMON_0", "h2_pCspinpatternBlueDown");
0229   TH2I *pCspinpatternBlueUnpol = (TH2I *) cl->getHisto("SPINMON_0", "h2_pCspinpatternBlueUnpol");
0230   TH2I *pCspinpatternYellowUp = (TH2I *) cl->getHisto("SPINMON_0", "h2_pCspinpatternYellowUp");
0231   TH2I *pCspinpatternYellowDown = (TH2I *) cl->getHisto("SPINMON_0", "h2_pCspinpatternYellowDown");
0232   TH2I *pCspinpatternYellowUnpol = (TH2I *) cl->getHisto("SPINMON_0", "h2_pCspinpatternYellowUnpol");
0233 
0234   TH2I *spinpatternBlueUp = (TH2I *) cl->getHisto("SPINMON_0", "h2_spinpatternBlueUp");
0235   TH2I *spinpatternBlueDown = (TH2I *) cl->getHisto("SPINMON_0", "h2_spinpatternBlueDown");
0236   TH2I *spinpatternBlueUnpol = (TH2I *) cl->getHisto("SPINMON_0", "h2_spinpatternBlueUnpol");
0237   TH2I *spinpatternYellowUp = (TH2I *) cl->getHisto("SPINMON_0", "h2_spinpatternYellowUp");
0238   TH2I *spinpatternYellowDown = (TH2I *) cl->getHisto("SPINMON_0", "h2_spinpatternYellowDown");
0239   TH2I *spinpatternYellowUnpol = (TH2I *) cl->getHisto("SPINMON_0", "h2_spinpatternYellowUnpol");
0240 
0241   TH1D *hpolBlue = (TH1D *) cl->getHisto("SPINMON_0", "h1_polBlue");
0242   TH1D *hpolYellow = (TH1D *) cl->getHisto("SPINMON_0", "h1_polYellow");
0243 
0244   TH1 *hxingshift = cl->getHisto("SPINMON_0", "h1_xingshift");
0245   TH1 *hfillnumber = cl->getHisto("SPINMON_0", "h1_fillnumber");
0246   TH1 *hfilltypeBlue = cl->getHisto("SPINMON_0", "h1_filltypeBlue");
0247   TH1 *hfilltypeYellow = cl->getHisto("SPINMON_0", "h1_filltypeYellow");
0248 
0249   if (!gROOT->FindObject("SpinMon1"))
0250   {
0251     MakeCanvas("SpinMon1");
0252   }
0253 
0254   for (int i = 0; i < NTRIG; i++)
0255   {
0256     gl1_counter[i] = cl->getHisto("SPINMON_0", Form("gl1_counter_trig%d", i));
0257     if (!gl1_counter[i])
0258     {
0259       DrawDeadServer(transparent[0]);
0260       TC[0]->SetEditable(false);
0261       if (isHtml())
0262       {
0263         delete TC[0];
0264         TC[0] = nullptr;
0265       }
0266       return -1;
0267     }
0268   }
0269 
0270   double agrat[4] = {-999,-999,-999,-999};
0271   
0272   gl1ptriggers["MBD_NS"] = gl1_counter[MBD_NS];
0273   gl1ptriggers["MBD_NS"]->SetTitle("gl1p MBD NS");
0274   double mbdns_int_fill = gl1ptriggers["MBD_NS"]->Integral();
0275   double mbdns_int_ag = gl1ptriggers["MBD_NS"]->Integral(112, 120);
0276   if (gl1ptriggers["MBD_NS"]->GetSumOfWeights() != 0)
0277   {
0278     agrat[0] = mbdns_int_ag / mbdns_int_fill;
0279   }
0280   
0281   gl1ptriggers["MBD_VTX"] = gl1_counter[MBD_VTX];
0282   gl1ptriggers["MBD_VTX"]->SetTitle("gl1p MBD VTX");
0283   double mbdvtx_int_fill = gl1ptriggers["MBD_VTX"]->Integral();
0284   double mbdvtx_int_ag = gl1ptriggers["MBD_VTX"]->Integral(112, 120);
0285 
0286   if (gl1ptriggers["MBD_VTX"]->GetSumOfWeights() != 0)
0287   {
0288     agrat[1] = mbdvtx_int_ag / mbdvtx_int_fill;
0289   }
0290   gl1ptriggers["MBD_10cm_VTX"] = gl1_counter[MBD_10cm_VTX];
0291   gl1ptriggers["MBD_10cm_VTX"]->SetTitle("gl1p MBD +/-10cm VTX");
0292   double mbd10cm_int_fill = gl1ptriggers["MBD_10cm_VTX"]->Integral();
0293   double mbd10cm_int_ag = gl1ptriggers["MBD_10cm_VTX"]->Integral(112, 120);
0294 
0295   if (gl1ptriggers["MBD_10cm_VTX"]->GetSumOfWeights() != 0)
0296   {
0297     agrat[2] = mbd10cm_int_ag / mbd10cm_int_fill;
0298   }
0299   gl1ptriggers["MBD_S"] = gl1_counter[MBD_S];
0300   gl1ptriggers["MBD_S"]->SetTitle("gl1p MBD S");
0301   gl1ptriggers["MBD_N"] = gl1_counter[MBD_N];
0302   gl1ptriggers["MBD_N"]->SetTitle("gl1p MBD N");
0303   gl1ptriggers["ZDC_NS"] = gl1_counter[ZDC_NS];
0304   gl1ptriggers["ZDC_NS"]->SetTitle("gl1p ZDC NS");
0305   double zdcns_int_fill = gl1ptriggers["ZDC_NS"]->Integral();
0306   double zdcns_int_ag = gl1ptriggers["ZDC_NS"]->Integral(112, 120);
0307 
0308   if (gl1ptriggers["ZDC_NS"]->GetSumOfWeights() != 0)
0309   {
0310     agrat[3] = zdcns_int_ag / zdcns_int_fill;
0311   }
0312   gl1ptriggers["ZDC_S"] = gl1_counter[ZDC_S];
0313   gl1ptriggers["ZDC_S"]->SetTitle("gl1p ZDC S");
0314   gl1ptriggers["ZDC_N"] = gl1_counter[ZDC_N];
0315   gl1ptriggers["ZDC_N"]->SetTitle("gl1p ZDC N");
0316   gl1ptriggers["EMPTY1"] = gl1_counter[EMPTY1];
0317   gl1ptriggers["EMPTY1"]->SetTitle("gl1p empty1");
0318   gl1ptriggers["EMPTY2"] = gl1_counter[EMPTY2];
0319   gl1ptriggers["EMPTY2"]->SetTitle("gl1p empty2");
0320   gl1ptriggers["EMPTY3"] = gl1_counter[EMPTY3];
0321   gl1ptriggers["EMPTY3"]->SetTitle("gl1p empty3");
0322   gl1ptriggers["EMPTY4"] = gl1_counter[EMPTY4];
0323   gl1ptriggers["EMPTY4"]->SetTitle("gl1p empty4");
0324   gl1ptriggers["EMPTY5"] = gl1_counter[EMPTY5];
0325   gl1ptriggers["EMPTY5"]->SetTitle("gl1p empty5");
0326   gl1ptriggers["EMPTY6"] = gl1_counter[EMPTY6];
0327   gl1ptriggers["EMPTY6"]->SetTitle("gl1p empty6");
0328   gl1ptriggers["EMPTY7"] = gl1_counter[EMPTY7];
0329   gl1ptriggers["EMPTY7"]->SetTitle("gl1p empty7");
0330   gl1ptriggers["EMPTY8"] = gl1_counter[EMPTY8];
0331   gl1ptriggers["EMPTY8"]->SetTitle("gl1p empty8");
0332 
0333   TC[0]->SetEditable(true);
0334   TC[0]->Clear("D");
0335   gStyle->SetOptStat(0);
0336   // gStyle->SetTitleAlign(23);
0337   // gStyle->SetLabelSize(0.5,"X");
0338 
0339   //===================== Measured spin patterns ===============//
0340   Pad[0]->cd();
0341   Pad[0]->SetTopMargin(0.25);
0342   Pad[0]->SetBottomMargin(0.25);
0343   Pad[0]->SetLeftMargin(0.15);
0344   Pad[0]->SetRightMargin(0.15);
0345 
0346   float labelsize = 0.1;
0347   if (!pCspinpatternBlueUp || !pCspinpatternBlueDown || !pCspinpatternBlueUnpol || !pCspinpatternYellowUp || !pCspinpatternYellowDown || !pCspinpatternYellowUnpol)
0348   {
0349     DrawDeadServer(transparent[0]);
0350     TC[0]->SetEditable(false);
0351     return -1;
0352   }
0353   else
0354   {
0355     // Measured Fill Pattern (pC)
0356     pCspinpatternBlueUp->SetFillColor(6);
0357     pCspinpatternBlueUp->GetXaxis()->SetLabelSize(labelsize);
0358     // pCspinpatternBlueUp->SetTitleSize(0.05);
0359     pCspinpatternBlueUp->SetStats(false);
0360     pCspinpatternBlueUp->GetXaxis()->SetTickLength(0);
0361     pCspinpatternBlueUp->GetYaxis()->SetTickLength(0);
0362     pCspinpatternBlueUp->GetXaxis()->SetNdivisions(120);
0363     pCspinpatternBlueUp->SetLineColor(kBlack);
0364     pCspinpatternBlueUp->SetLineWidth(1);
0365     pCspinpatternBlueUp->GetYaxis()->SetLabelSize(0);
0366     pCspinpatternBlueUp->DrawCopy("box1");
0367     pCspinpatternBlueDown->SetFillColor(7);
0368     pCspinpatternBlueDown->GetXaxis()->SetLabelSize(labelsize);
0369     pCspinpatternBlueDown->DrawCopy("box1,same");
0370     pCspinpatternBlueUnpol->SetFillColor(4);
0371     pCspinpatternBlueDown->GetXaxis()->SetLabelSize(labelsize);
0372     pCspinpatternBlueUnpol->DrawCopy("box1,same");
0373     pCspinpatternYellowUp->SetFillColor(2);
0374     pCspinpatternYellowUp->DrawCopy("box1,same");
0375     pCspinpatternYellowUp->GetXaxis()->SetLabelSize(labelsize);
0376     pCspinpatternYellowDown->SetFillColor(3);
0377     pCspinpatternYellowDown->DrawCopy("box1,same");
0378     pCspinpatternYellowDown->GetXaxis()->SetLabelSize(labelsize);
0379     pCspinpatternYellowUnpol->SetFillColor(5);
0380     pCspinpatternYellowUnpol->DrawCopy("box1,same");
0381     pCspinpatternYellowUnpol->GetXaxis()->SetLabelSize(labelsize);
0382 
0383     TLegend *leg_blue = new TLegend(0.01, 0.01, 0.125, 0.99);
0384     leg_blue->SetFillStyle(0);
0385     leg_blue->SetBorderSize(1);
0386     leg_blue->AddEntry(pCspinpatternBlueUp, "Blue Up", "F");
0387     leg_blue->AddEntry(pCspinpatternBlueDown, "Blue Down", "F");
0388     leg_blue->AddEntry(pCspinpatternBlueUnpol, "Blue Unpol", "F");
0389 
0390     TLegend *leg_yellow = new TLegend(0.875, 0.01, 0.99, 0.99);
0391     leg_yellow->SetFillStyle(0);
0392     leg_yellow->SetBorderSize(1);
0393     leg_yellow->AddEntry(pCspinpatternYellowUp, "Yellow Up", "F");
0394     leg_yellow->AddEntry(pCspinpatternYellowDown, "Yellow Down", "F");
0395     leg_yellow->AddEntry(pCspinpatternYellowUnpol, "Yellow Unpol", "F");
0396 
0397     leg_blue->Draw("same");
0398     leg_yellow->Draw("same");
0399 
0400     TText t_pCSpinPatt;
0401     t_pCSpinPatt.SetTextFont(62);
0402     t_pCSpinPatt.SetTextSize(0.2);
0403     t_pCSpinPatt.SetNDC();
0404     t_pCSpinPatt.SetTextAlign(23);
0405     std::string pCSPstring = "Measured Spin Pattern (pC)";
0406     t_pCSpinPatt.DrawText(0.5, 1, pCSPstring.c_str());
0407   }
0408 
0409   //===================== Intended spin patterns ===============//
0410   Pad[1]->cd();
0411   Pad[1]->SetTopMargin(0.25);
0412   Pad[1]->SetBottomMargin(0.25);
0413   Pad[1]->SetLeftMargin(0.15);
0414   Pad[1]->SetRightMargin(0.15);
0415 
0416   if (!spinpatternBlueUp || !spinpatternBlueDown || !spinpatternBlueUnpol || !spinpatternYellowUp || !spinpatternYellowDown || !spinpatternYellowUnpol)
0417   {
0418     DrawDeadServer(transparent[0]);
0419     TC[0]->SetEditable(false);
0420     return -1;
0421   }
0422   else
0423   {
0424     // Intended Fill Pattern (CDEV)
0425     spinpatternBlueUp->SetFillColor(6);
0426     spinpatternBlueUp->GetXaxis()->SetLabelSize(labelsize);
0427     spinpatternBlueUp->SetStats(false);
0428     spinpatternBlueUp->GetXaxis()->SetTickLength(0);
0429     spinpatternBlueUp->GetXaxis()->SetNdivisions(120);
0430     spinpatternBlueUp->SetLineColor(kBlack);
0431     spinpatternBlueUp->SetLineStyle(1);
0432     spinpatternBlueUp->GetYaxis()->SetTickLength(0);
0433     spinpatternBlueUp->GetYaxis()->SetLabelSize(0);
0434     spinpatternBlueUp->DrawCopy("box1");
0435     spinpatternBlueDown->SetFillColor(7);
0436     spinpatternBlueDown->GetXaxis()->SetLabelSize(labelsize);
0437     spinpatternBlueDown->DrawCopy("box1,same");
0438     spinpatternBlueUnpol->SetFillColor(4);
0439     spinpatternBlueDown->GetXaxis()->SetLabelSize(labelsize);
0440     spinpatternBlueUnpol->DrawCopy("box1,same");
0441     spinpatternYellowUp->SetFillColor(2);
0442     spinpatternYellowUp->DrawCopy("box1,same");
0443     spinpatternYellowUp->GetXaxis()->SetLabelSize(labelsize);
0444     spinpatternYellowDown->SetFillColor(3);
0445     spinpatternYellowDown->DrawCopy("box1,same");
0446     spinpatternYellowDown->GetXaxis()->SetLabelSize(labelsize);
0447     spinpatternYellowUnpol->SetFillColor(5);
0448     spinpatternYellowUnpol->DrawCopy("box1,same");
0449     spinpatternYellowUnpol->GetXaxis()->SetLabelSize(labelsize);
0450 
0451     TText t_SpinPatt;
0452     t_SpinPatt.SetTextFont(62);
0453     t_SpinPatt.SetTextSize(0.2);
0454     t_SpinPatt.SetNDC();
0455     t_SpinPatt.SetTextAlign(23);
0456     std::string SPstring = "Intended Spin Pattern (CDEV)";
0457     t_SpinPatt.DrawText(0.5, 1, SPstring.c_str());
0458   }
0459 
0460   //============== text information ===============//
0461   Pad[2]->SetFillColor(18);
0462   Pad[2]->cd();
0463   float textsize = 0.05;
0464 
0465   TText t_FillNumber;
0466   t_FillNumber.SetTextFont(62);
0467   t_FillNumber.SetTextSize(textsize);
0468   t_FillNumber.SetNDC();
0469   std::string fillnumberstring;
0470   if (hfillnumber->GetBinContent(1) == hfillnumber->GetBinContent(2) && hfillnumber->GetBinContent(1) != 0)
0471   {
0472     std::ostringstream fillnumberstream;
0473     fillnumberstream << "Fill number: " << hfillnumber->GetBinContent(1);
0474     fillnumberstring = fillnumberstream.str();
0475     t_FillNumber.DrawText(0.15, 0.85, fillnumberstring.c_str());
0476   }
0477   else
0478   {
0479     fillnumberstring = "Fill number not available";
0480     t_FillNumber.DrawText(0.15, 0.85, fillnumberstring.c_str());
0481   }
0482 
0483   TText t_FillType;
0484   t_FillType.SetTextFont(62);
0485   t_FillType.SetTextSize(textsize);
0486   t_FillType.SetNDC();
0487   std::ostringstream filltypestream;
0488   filltypestream << "Fill type: " << hfilltypeBlue->GetBinContent(1) << "x" << hfilltypeYellow->GetBinContent(1);
0489   std::string filltypestring = filltypestream.str();
0490   t_FillType.DrawText(0.15, 0.8, filltypestring.c_str());
0491 
0492   std::string scdev_blue = TH1_to_string(hspinpatternBlue);
0493   std::string scdev_yellow = TH1_to_string(hspinpatternYellow);
0494   std::string pattern_name = "UNKNOWN";
0495 
0496   for (std::map<std::string, std::string>::const_iterator ii = preset_pattern_blue.begin(); ii != preset_pattern_blue.end(); ++ii)
0497   {
0498     std::string key = (*ii).first;
0499     if (preset_pattern_blue[key] == scdev_blue && preset_pattern_yellow[key] == scdev_yellow)
0500     {
0501       pattern_name = key;
0502     }
0503   }
0504 
0505   TText t_Pattern;
0506   t_Pattern.SetTextFont(62);
0507   t_Pattern.SetTextSize(textsize);
0508   t_Pattern.SetNDC();
0509   std::ostringstream patternstream;
0510   std::string patternstring;
0511   patternstream << "Pattern: " << pattern_name;
0512   patternstring = patternstream.str();
0513   t_Pattern.DrawText(0.15, 0.7, patternstring.c_str());
0514 
0515   int mismatches = 0;
0516   for (int crossing = 0; crossing < 120; crossing++)
0517   {
0518     int spin_cdev_blue = hspinpatternBlue->GetBinContent(crossing + 1);
0519     int spin_pC_blue = hpCspinpatternBlue->GetBinContent(crossing + 1);
0520 
0521     int spin_cdev_yell = hspinpatternYellow->GetBinContent(crossing + 1);
0522     int spin_pC_yell = hpCspinpatternYellow->GetBinContent(crossing + 1);
0523 
0524     if(spin_pC_blue==-1 || spin_pC_blue==1)
0525     {
0526       if (spin_cdev_blue != spin_pC_blue && !(spin_cdev_blue == 0 && spin_pC_blue == 10))
0527       {
0528     mismatches += 1;
0529       }
0530     }
0531 
0532     if(spin_pC_yell==-1 || spin_pC_yell==1)
0533     {
0534       if (spin_cdev_yell != spin_pC_yell && !(spin_cdev_blue == 0 && spin_pC_blue == 10))
0535       {
0536     mismatches += 1;
0537       }
0538     }
0539   }
0540 
0541   TText t_PatternMatch;
0542   t_PatternMatch.SetTextFont(62);
0543   t_PatternMatch.SetTextSize(textsize);
0544   t_PatternMatch.SetNDC();
0545 
0546   if (!mismatches)
0547   {
0548     std::string patternmatchstring = "pC AND CDEV PATTERNS MATCH";
0549     t_PatternMatch.SetTextColor(kGreen);
0550     t_PatternMatch.DrawText(0.15, 0.65, patternmatchstring.c_str());
0551   }
0552   else
0553   {
0554     std::string patternmatchstring1 = "pC/CDEV PATTERN MISMATCH:";
0555     std::ostringstream patternmatchstream;
0556     patternmatchstream << mismatches << " bunch(es)";
0557     std::string patternmatchstring2 = patternmatchstream.str();
0558     t_PatternMatch.SetTextColor(kRed);
0559     t_PatternMatch.DrawText(0.15, 0.65, patternmatchstring1.c_str());
0560     t_PatternMatch.DrawText(0.15, 0.6, patternmatchstring2.c_str());
0561   }
0562 
0563   TLatex *latPol = new TLatex();
0564   latPol->SetTextSize(textsize);
0565   latPol->SetTextColor(kBlack);
0566   latPol->SetNDC();
0567   latPol->DrawLatex(0.15, 0.5, "CNI POLARIZATION (%)");
0568 
0569   TLatex *t_PolBlue = new TLatex();
0570   t_PolBlue->SetTextFont(62);
0571   t_PolBlue->SetTextSize(textsize);
0572   t_PolBlue->SetNDC();
0573   t_PolBlue->SetTextColor(kBlue);
0574   t_PolBlue->DrawLatex(0.15, 0.45, "BLUE");
0575   std::ostringstream polbluestream;
0576   std::string polbluestring;
0577   polbluestream << round(hpolBlue->GetBinContent(1) * 100) / 100 << " #pm " << round(hpolBlue->GetBinError(1) * 100) / 100 << " (stat)";
0578   polbluestring = polbluestream.str();
0579   t_PolBlue->SetTextColor(kBlack);
0580   t_PolBlue->DrawLatex(0.4, 0.45, polbluestring.c_str());
0581 
0582   TLatex *t_PolYellow = new TLatex();
0583   t_PolYellow->SetTextFont(62);
0584   t_PolYellow->SetTextSize(textsize);
0585   t_PolYellow->SetNDC();
0586   t_PolYellow->SetTextColor(kOrange);
0587   t_PolYellow->DrawLatex(0.15, 0.4, "YELLOW");
0588   std::ostringstream polyellowstream;
0589   std::string polyellowstring;
0590   polyellowstream << round(hpolYellow->GetBinContent(1) * 100) / 100 << " #pm " << round(hpolYellow->GetBinError(1) * 100) / 100 << " (stat)";
0591   polyellowstring = polyellowstream.str();
0592   t_PolYellow->SetTextColor(kBlack);
0593   t_PolYellow->DrawLatex(0.4, 0.4, polyellowstring.c_str());
0594 
0595   TText t_xingshift;
0596   t_xingshift.SetTextFont(62);
0597   t_xingshift.SetTextSize(textsize);
0598   t_xingshift.SetNDC();
0599   std::ostringstream xingshiftstream;
0600   std::string xingshiftstring;
0601   xingshiftstream << "Default crossing shift: " << hxingshift->GetBinContent(1);
0602   xingshiftstring = xingshiftstream.str();
0603   t_xingshift.DrawText(0.15, 0.3, xingshiftstring.c_str());
0604 
0605   /*
0606   std::string addxingshiftstring;
0607   if (hxingshift->GetBinContent(2) != -999)
0608   {
0609     std::ostringstream addxingshiftstream;
0610     addxingshiftstream << "Additional crossing shift: " << hxingshift->GetBinContent(2);
0611     addxingshiftstring = addxingshiftstream.str();
0612     t_xingshift.DrawText(0.15, 0.25, addxingshiftstring.c_str());
0613   }
0614   else
0615   {
0616     addxingshiftstring = "Additional crossing shift: Unknown";
0617     t_xingshift.DrawText(0.15, 0.25, addxingshiftstring.c_str());
0618   }
0619   */
0620 
0621   TText t_agrat;
0622   t_agrat.SetTextFont(62);
0623   t_agrat.SetTextSize(textsize);
0624   t_agrat.SetNDC(); 
0625   t_agrat.DrawText(0.15, 0.2, "Abort gap scalers (keep below 7%)");
0626   t_agrat.DrawText(0.075, 0.125, "MBD_NS");
0627   t_agrat.DrawText(0.308, 0.125, "MBD_VTX");
0628   t_agrat.DrawText(0.541, 0.125, "MBD_10");
0629   t_agrat.DrawText(0.75, 0.125, "ZDC_NS");
0630   
0631   std::ostringstream agratstream[4];
0632   std::string agratstring[4] = {"N/A","N/A","N/A","N/A"};
0633   for (int i = 0; i < 4; i++)
0634   {
0635     t_agrat.SetTextColor(kBlack);
0636     float agrat_pct = std::round((agrat[i]*100) * 100.0) / 100.0;
0637     agratstream[i] << agrat_pct << "%";
0638     if (agrat_pct > 7)
0639     {
0640       t_agrat.SetTextColor(kRed);
0641       agratstring[i] = agratstream[i].str();
0642     }
0643     else if (agrat_pct >= 0)
0644     {
0645       t_agrat.SetTextColor(kBlack);
0646       agratstring[i] = agratstream[i].str();
0647     }
0648     float x = 0.075+(0.7/3)*i;
0649     t_agrat.DrawText(x, 0.075, agratstring[i].c_str());
0650   }
0651   //================================================
0652 
0653   gStyle->SetTitleFontSize(0.06);
0654   gStyle->SetTitleAlign(33);
0655   gStyle->SetTitleX(0.75);
0656   labelsize = 0.05;
0657 
0658   for (std::map<std::string, TH1 *>::const_iterator ii = gl1ptriggers.begin(); ii != gl1ptriggers.end(); ++ii)
0659   {
0660     std::string key = (*ii).first;
0661     if (key == "MBD_NS")
0662     {
0663       if (gl1ptriggers[key])
0664       {
0665         Pad[3]->cd();
0666         gl1ptriggers[key]->GetXaxis()->SetLabelSize(labelsize);
0667         gl1ptriggers[key]->GetYaxis()->SetLabelSize(labelsize);
0668         gl1ptriggers[key]->GetYaxis()->SetMaxDigits(2);
0669         gl1ptriggers[key]->SetStats(false);
0670         gl1ptriggers[key]->DrawCopy("HIST");
0671         if (gl1ptriggers[key]->GetSumOfWeights() == 0)
0672         {
0673           TLatex *lat = new TLatex();
0674           lat->SetTextSize(0.15);
0675           lat->SetTextColor(kRed);
0676           lat->SetTextAngle(45);
0677           lat->SetNDC();
0678           lat->DrawLatex(0.25, 0.15, "NOT ACTIVE");
0679         }
0680       }
0681       else
0682       {
0683         DrawDeadServer(transparent[0]);
0684         TC[0]->SetEditable(false);
0685         return -1;
0686       }
0687     }
0688     else if (key == "MBD_VTX")
0689     {
0690       if (gl1ptriggers[key])
0691       {
0692         Pad[4]->cd();
0693         gl1ptriggers[key]->GetXaxis()->SetLabelSize(labelsize);
0694         gl1ptriggers[key]->GetYaxis()->SetLabelSize(labelsize);
0695         gl1ptriggers[key]->GetYaxis()->SetMaxDigits(2);
0696         gl1ptriggers[key]->SetStats(false);
0697         gl1ptriggers[key]->DrawCopy("HIST");
0698         if (gl1ptriggers[key]->GetSumOfWeights() == 0)
0699         {
0700           TLatex *lat = new TLatex();
0701           lat->SetTextSize(0.15);
0702           lat->SetTextColor(kRed);
0703           lat->SetTextAngle(45);
0704           lat->SetNDC();
0705           lat->DrawLatex(0.25, 0.15, "NOT ACTIVE");
0706         }
0707       }
0708       else
0709       {
0710         DrawDeadServer(transparent[0]);
0711         TC[0]->SetEditable(false);
0712         return -1;
0713       }
0714     }
0715     else if (key == "MBD_10cm_VTX")
0716     {
0717       if (gl1ptriggers[key])
0718       {
0719         Pad[5]->cd();
0720         gl1ptriggers[key]->GetXaxis()->SetLabelSize(labelsize);
0721         gl1ptriggers[key]->GetYaxis()->SetLabelSize(labelsize);
0722         gl1ptriggers[key]->GetYaxis()->SetMaxDigits(2);
0723         gl1ptriggers[key]->SetStats(false);
0724         gl1ptriggers[key]->DrawCopy("HIST");
0725         if (gl1ptriggers[key]->GetSumOfWeights() == 0)
0726         {
0727           TLatex *lat = new TLatex();
0728           lat->SetTextSize(0.15);
0729           lat->SetTextColor(kRed);
0730           lat->SetTextAngle(45);
0731           lat->SetNDC();
0732           lat->DrawLatex(0.25, 0.15, "NOT ACTIVE");
0733         }
0734       }
0735       else
0736       {
0737         DrawDeadServer(transparent[0]);
0738         TC[0]->SetEditable(false);
0739         return -1;
0740       }
0741     }
0742     else if (key == "ZDC_NS")
0743     {
0744       if (gl1ptriggers[key])
0745       {
0746         Pad[6]->cd();
0747         gl1ptriggers[key]->GetXaxis()->SetLabelSize(labelsize);
0748         gl1ptriggers[key]->GetYaxis()->SetLabelSize(labelsize);
0749         gl1ptriggers[key]->GetYaxis()->SetMaxDigits(2);
0750         gl1ptriggers[key]->SetStats(false);
0751         gl1ptriggers[key]->DrawCopy("HIST");
0752         if (gl1ptriggers[key]->GetSumOfWeights() == 0)
0753         {
0754           TLatex *lat = new TLatex();
0755           lat->SetTextSize(0.15);
0756           lat->SetTextColor(kRed);
0757           lat->SetTextAngle(45);
0758           lat->SetNDC();
0759           lat->DrawLatex(0.25, 0.15, "NOT ACTIVE");
0760         }
0761       }
0762       else
0763       {
0764         DrawDeadServer(transparent[0]);
0765         TC[0]->SetEditable(false);
0766         return -1;
0767       }
0768     }
0769   }
0770 
0771   TText PrintRun;
0772   PrintRun.SetTextFont(62);
0773   PrintRun.SetTextSize(0.04);
0774   PrintRun.SetNDC();          // set to normalized coordinates
0775   PrintRun.SetTextAlign(23);  // center/top alignment
0776   std::ostringstream runnostream;
0777   std::string runstring;
0778   std::pair<time_t,int> evttime = cl->EventTime("CURRENT");
0779   // fill run number and event time into string
0780   runnostream << ThisName << "_1 Run " << cl->RunNumber()
0781               << ", Time: " << ctime(&evttime.first);
0782   runstring = runnostream.str();
0783   transparent[0]->cd();
0784   PrintRun.SetTextColor(evttime.second);
0785   PrintRun.DrawText(0.5, 1., runstring.c_str());
0786   TC[0]->Update();
0787   TC[0]->Show();
0788   TC[0]->SetEditable(false);
0789   return 0;
0790 }
0791 
0792 int SpinMonDraw::DrawSecond(const std::string & /* what */)
0793 {
0794   OnlMonClient *cl = OnlMonClient::instance();
0795 
0796   if (!gROOT->FindObject("SpinMon2"))
0797   {
0798     MakeCanvas("SpinMon2");
0799   }
0800 
0801   
0802   for (int i = 0; i < NTRIG; i++)
0803   {
0804     gl1_counter[i] = cl->getHisto("SPINMON_0", Form("gl1_counter_trig%d", i));
0805     if (!gl1_counter[i])
0806     {
0807       DrawDeadServer(transparent[1]);
0808       TC[1]->SetEditable(false);
0809       if (isHtml())
0810       {
0811         delete TC[1];
0812         TC[1] = nullptr;
0813       }
0814       return -1;
0815     }
0816   }
0817 
0818 
0819   gl1ptriggers["MBD_NS"] = gl1_counter[MBD_NS];
0820   gl1ptriggers["MBD_NS"]->SetTitle("gl1p MBD NS");
0821   
0822   gl1ptriggers["MBD_VTX"] = gl1_counter[MBD_VTX];
0823   gl1ptriggers["MBD_VTX"]->SetTitle("gl1p MBD VTX");
0824 
0825   gl1ptriggers["MBD_10cm_VTX"] = gl1_counter[MBD_10cm_VTX];
0826   gl1ptriggers["MBD_10cm_VTX"]->SetTitle("gl1p MBD +/-10cm VTX");
0827 
0828   gl1ptriggers["MBD_S"] = gl1_counter[MBD_S];
0829   gl1ptriggers["MBD_S"]->SetTitle("gl1p MBD S");
0830   gl1ptriggers["MBD_N"] = gl1_counter[MBD_N];
0831   gl1ptriggers["MBD_N"]->SetTitle("gl1p MBD N");
0832   gl1ptriggers["ZDC_NS"] = gl1_counter[ZDC_NS];
0833   gl1ptriggers["ZDC_NS"]->SetTitle("gl1p ZDC NS");
0834 
0835   gl1ptriggers["ZDC_S"] = gl1_counter[ZDC_S];
0836   gl1ptriggers["ZDC_S"]->SetTitle("gl1p ZDC S");
0837   gl1ptriggers["ZDC_N"] = gl1_counter[ZDC_N];
0838   gl1ptriggers["ZDC_N"]->SetTitle("gl1p ZDC N");
0839   gl1ptriggers["EMPTY1"] = gl1_counter[EMPTY1];
0840   gl1ptriggers["EMPTY1"]->SetTitle("gl1p empty1");
0841   gl1ptriggers["EMPTY2"] = gl1_counter[EMPTY2];
0842   gl1ptriggers["EMPTY2"]->SetTitle("gl1p empty2");
0843   gl1ptriggers["EMPTY3"] = gl1_counter[EMPTY3];
0844   gl1ptriggers["EMPTY3"]->SetTitle("gl1p empty3");
0845   gl1ptriggers["EMPTY4"] = gl1_counter[EMPTY4];
0846   gl1ptriggers["EMPTY4"]->SetTitle("gl1p empty4");
0847   gl1ptriggers["EMPTY5"] = gl1_counter[EMPTY5];
0848   gl1ptriggers["EMPTY5"]->SetTitle("gl1p empty5");
0849   gl1ptriggers["EMPTY6"] = gl1_counter[EMPTY6];
0850   gl1ptriggers["EMPTY6"]->SetTitle("gl1p empty6");
0851   gl1ptriggers["EMPTY7"] = gl1_counter[EMPTY7];
0852   gl1ptriggers["EMPTY7"]->SetTitle("gl1p empty7");
0853   gl1ptriggers["EMPTY8"] = gl1_counter[EMPTY8];
0854   gl1ptriggers["EMPTY8"]->SetTitle("gl1p empty8");
0855   
0856 
0857 
0858   TC[1]->SetEditable(true);
0859   TC[1]->Clear("D");
0860 
0861   gStyle->SetTitleFontSize(0.05);
0862   gStyle->SetTitleAlign(33);
0863   gStyle->SetTitleX(0.75);
0864   float labelsize = 0.05;
0865 
0866   
0867 
0868   if (gl1ptriggers["MBD_NS"] && gl1ptriggers["MBD_VTX"])
0869   {
0870     Pad[7]->cd();
0871     std::string trig1 = "MBD_NS";
0872     std::string trig2 = "MBD_VTX";
0873     DrawGL1pRatio(trig1, trig2);
0874   }
0875   else
0876   {
0877     DrawDeadServer(transparent[1]);
0878     TC[1]->SetEditable(false);
0879     return -1;
0880   }
0881 
0882   if (gl1ptriggers["MBD_NS"] && gl1ptriggers["MBD_10cm_VTX"])
0883   {
0884     Pad[8]->cd();
0885     std::string trig1 = "MBD_NS";
0886     std::string trig2 = "MBD_10cm_VTX";
0887     DrawGL1pRatio(trig1, trig2);
0888   }
0889   else
0890   {
0891     DrawDeadServer(transparent[1]);
0892     TC[1]->SetEditable(false);
0893     return -1;
0894   }
0895 
0896   if (gl1ptriggers["MBD_NS"] && gl1ptriggers["ZDC_NS"])
0897   {
0898     Pad[9]->cd();
0899     std::string trig1 = "MBD_NS";
0900     std::string trig2 = "ZDC_NS";
0901     DrawGL1pRatio(trig1, trig2);
0902   }
0903   else
0904   {
0905     DrawDeadServer(transparent[1]);
0906     TC[1]->SetEditable(false);
0907     return -1;
0908   }
0909 
0910   if (gl1ptriggers["MBD_VTX"] && gl1ptriggers["MBD_10cm_VTX"])
0911   {
0912     Pad[10]->cd();
0913     std::string trig1 = "MBD_VTX";
0914     std::string trig2 = "MBD_10cm_VTX";
0915     DrawGL1pRatio(trig1, trig2);
0916   }
0917   else
0918   {
0919     DrawDeadServer(transparent[1]);
0920     TC[1]->SetEditable(false);
0921     return -1;
0922   }
0923 
0924   if (gl1ptriggers["MBD_VTX"] && gl1ptriggers["ZDC_NS"])
0925   {
0926     Pad[11]->cd();
0927     std::string trig1 = "MBD_VTX";
0928     std::string trig2 = "ZDC_NS";
0929     DrawGL1pRatio(trig1, trig2);
0930   }
0931   else
0932   {
0933     DrawDeadServer(transparent[1]);
0934     TC[1]->SetEditable(false);
0935     return -1;
0936   }
0937 
0938   if (gl1ptriggers["MBD_10cm_VTX"] && gl1ptriggers["ZDC_NS"])
0939   {
0940     Pad[12]->cd();
0941     std::string trig1 = "MBD_10cm_VTX";
0942     std::string trig2 = "ZDC_NS";
0943     DrawGL1pRatio(trig1, trig2);
0944   }
0945   else
0946   {
0947     DrawDeadServer(transparent[1]);
0948     TC[1]->SetEditable(false);
0949     return -1;
0950   }
0951 
0952   gStyle->SetTitleFontSize(0.1);
0953   gStyle->SetTitleAlign(33);
0954   gStyle->SetTitleX(0.75);
0955   labelsize = 0.05;
0956 
0957   for (int i = 0; i < NTRIG; i++)
0958   {
0959     Pad[i + 13]->cd();
0960     if (gl1_counter[i])
0961     {
0962       gl1_counter[i]->GetXaxis()->SetLabelSize(labelsize);
0963       gl1_counter[i]->GetYaxis()->SetLabelSize(labelsize);
0964       gl1_counter[i]->GetYaxis()->SetMaxDigits(2);
0965       gl1_counter[i]->SetStats(false);
0966       gl1_counter[i]->DrawCopy("HIST");
0967       if (gl1_counter[i]->GetSumOfWeights() == 0)
0968       {
0969         TLatex *lat = new TLatex();
0970         lat->SetTextSize(0.15);
0971         lat->SetTextColor(kRed);
0972         lat->SetTextAngle(45);
0973         lat->SetNDC();
0974         lat->DrawLatex(0.25, 0.15, "NOT ACTIVE");
0975       }
0976     }
0977     else
0978     {
0979       DrawDeadServer(transparent[1]);
0980       TC[1]->SetEditable(false);
0981       return -1;
0982     }
0983   }
0984 
0985   TText PrintRun;
0986   PrintRun.SetTextFont(62);
0987   PrintRun.SetTextSize(0.04);
0988   PrintRun.SetNDC();          // set to normalized coordinates
0989   PrintRun.SetTextAlign(23);  // center/top alignment
0990   std::ostringstream runnostream;
0991   std::string runstring;
0992   std::pair<time_t,int> evttime = cl->EventTime("CURRENT");
0993   // fill run number and event time into string
0994   runnostream << ThisName << "_2 Run " << cl->RunNumber()
0995               << ", Time: " << ctime(&evttime.first);
0996   runstring = runnostream.str();
0997   transparent[1]->cd();
0998   PrintRun.SetTextColor(evttime.second);
0999   PrintRun.DrawText(0.5, 1., runstring.c_str());
1000   TC[1]->Update();
1001   TC[1]->Show();
1002   TC[1]->SetEditable(false);
1003   return 0;
1004 }
1005 
1006 int SpinMonDraw::DrawThird(const std::string & /* what */)
1007 {
1008 
1009   OnlMonClient *cl = OnlMonClient::instance();
1010 
1011   TH1 *hCorrect = cl->getHisto("SPINMON_0", "hCorrect");
1012   TH1 *hAbortgap = cl->getHisto("SPINMON_0", "hAbortgap");
1013   TH1 *hForbidden = cl->getHisto("SPINMON_0", "hForbidden");
1014 
1015   if (!gROOT->FindObject("SpinMon3"))
1016   {
1017     MakeCanvas("SpinMon3");
1018   }
1019   
1020   TC[2]->SetEditable(true);
1021   TC[2]->Clear("D");
1022 
1023 
1024   Pad[29]->cd();
1025   Pad[29]->SetTopMargin(0.25);
1026   Pad[29]->SetBottomMargin(0.25);
1027   Pad[29]->SetLeftMargin(0.15);
1028   Pad[29]->SetRightMargin(0.15);
1029 
1030   
1031   if (!hCorrect || !hAbortgap || !hForbidden)
1032   {
1033     DrawDeadServer(transparent[2]);
1034     TC[2]->SetEditable(false);
1035     return -1;
1036   }
1037   else
1038   {
1039     hCorrect->SetTitle("");
1040     hCorrect->GetXaxis()->SetTitle("Bunch Number");
1041     hCorrect->GetYaxis()->SetTitle("Count");
1042     hCorrect->SetFillColor(kGreen+2);
1043     hCorrect->SetLineWidth(0);
1044     hCorrect->SetStats(0);
1045 
1046     hAbortgap->GetXaxis()->SetTitle("Bunch Number");
1047     hAbortgap->GetYaxis()->SetTitle("Count");
1048     hAbortgap->SetFillColor(kOrange);
1049     hAbortgap->SetLineWidth(0);
1050 
1051     hForbidden->GetXaxis()->SetTitle("Bunch Number");
1052     hForbidden->GetYaxis()->SetTitle("Count");
1053     hForbidden->SetFillColor(kRed+2);
1054     hForbidden->SetLineWidth(0);
1055 
1056     double ymax = hCorrect->GetMaximum();
1057     if ( hAbortgap->GetMaximum() > ymax ) 
1058     {
1059       ymax = hAbortgap->GetMaximum();
1060     }
1061     if ( hForbidden->GetMaximum() > ymax )
1062     {
1063       ymax = hForbidden->GetMaximum();
1064     }
1065 
1066     hCorrect->DrawCopy("hist");
1067     hAbortgap->DrawCopy("hist,same");
1068     hForbidden->DrawCopy("hist,same");
1069 
1070     TLine *tl111 = new TLine(110.5,0,110.5,ymax);
1071     tl111->SetLineWidth(2);
1072     tl111->SetLineColor(kBlue);
1073     //tl111->SetLineStyle(3);
1074     tl111->Draw();
1075 
1076     TLine *tl120 = new TLine(120,0,120,ymax);
1077     tl120->SetLineWidth(2);
1078     tl120->SetLineColor(kBlue);
1079     //tl120->SetLineStyle(3);
1080     tl120->Draw();
1081 
1082     TText annotation;
1083     annotation.SetTextFont(62);
1084     annotation.SetTextSize(0.04);
1085     //annotation.SetNDC();          // set to normalized coordinates
1086     annotation.SetTextAlign(22);  // center alignment
1087     annotation.DrawText(55, 0.3*ymax, "Collisions");
1088 
1089     TText ag;
1090     ag.SetTextAngle(90);
1091     ag.SetTextFont(62);
1092     ag.SetTextSize(0.04);
1093     //  ag.SetNDC();          // set to normalized coordinates
1094     ag.SetTextAlign(22);  // center/top alignment
1095     ag.DrawText(115, ymax/3., "Abort Gap");
1096 
1097 
1098     TText fg;
1099     fg.SetTextAngle(90);
1100     fg.SetTextFont(62);
1101     fg.SetTextSize(0.04);
1102     //  fg.SetNDC();          // set to normalized coordinates
1103     fg.SetTextAlign(22);  // center alignment
1104     fg.DrawText(125, ymax/3., "Forbidden");
1105   }
1106 
1107   TText PrintRun;
1108   PrintRun.SetTextFont(62);
1109   PrintRun.SetTextSize(0.04);
1110   PrintRun.SetNDC();          // set to normalized coordinates
1111   PrintRun.SetTextAlign(23);  // center/top alignment
1112   std::ostringstream runnostream;
1113   std::string runstring;
1114   std::pair<time_t,int> evttime = cl->EventTime("CURRENT");
1115   // fill run number and event time into string
1116   runnostream << ThisName << "_3 Run " << cl->RunNumber()
1117               << ", Time: " << ctime(&evttime.first);
1118   runstring = runnostream.str();
1119   transparent[2]->cd();
1120   PrintRun.SetTextColor(evttime.second);
1121   PrintRun.DrawText(0.5, 1., runstring.c_str());
1122   TC[2]->Update();
1123   TC[2]->Show();
1124   TC[2]->SetEditable(false);
1125   return 0;
1126 
1127 
1128 }
1129 
1130 
1131 
1132 int SpinMonDraw::SavePlot(const std::string &what, const std::string &type)
1133 {
1134   OnlMonClient *cl = OnlMonClient::instance();
1135   int iret = Draw(what);
1136   if (iret)  // on error no png files please
1137   {
1138     return iret;
1139   }
1140   int icnt = 0;
1141   for (TCanvas *canvas : TC)
1142   {
1143     if (canvas == nullptr)
1144     {
1145       continue;
1146     }
1147     icnt++;
1148     std::string filename = ThisName + "_" + std::to_string(icnt) + "_" +
1149                            std::to_string(cl->RunNumber()) + "." + type;
1150     cl->CanvasToPng(canvas, filename);
1151   }
1152   return 0;
1153 }
1154 
1155 int SpinMonDraw::MakeHtml(const std::string &what)
1156 {
1157   int iret = Draw(what);
1158   if (iret)  // on error no html output please
1159   {
1160     return iret;
1161   }
1162 
1163   OnlMonClient *cl = OnlMonClient::instance();
1164 
1165   // Register the 1st canvas png file to the menu and produces the png file.
1166   std::string pngfile = cl->htmlRegisterPage(*this, "Shift Crew", "1", "png");
1167   cl->CanvasToPng(TC[0], pngfile);
1168 
1169   // idem for 2nd canvas.
1170   pngfile = cl->htmlRegisterPage(*this, "Expert", "2", "png");
1171   cl->CanvasToPng(TC[1], pngfile);
1172   // Now register also EXPERTS html pages, under the EXPERTS subfolder.
1173 
1174   pngfile = cl->htmlRegisterPage(*this, "Bunch numbers", "3", "png");
1175   cl->CanvasToPng(TC[2], pngfile);
1176 
1177   /*
1178   std::string logfile = cl->htmlRegisterPage(*this, "EXPERTS/Log", "log", "html");
1179   std::ofstream out(logfile.c_str());
1180   out << "<HTML><HEAD><TITLE>Log file for run " << cl->RunNumber()
1181       << "</TITLE></HEAD>" << std::endl;
1182   out << "<P>Some log file output would go here." << std::endl;
1183   out.close();
1184 
1185   std::string status = cl->htmlRegisterPage(*this, "EXPERTS/Status", "status", "html");
1186   std::ofstream out2(status.c_str());
1187   out2 << "<HTML><HEAD><TITLE>Status file for run " << cl->RunNumber()
1188        << "</TITLE></HEAD>" << std::endl;
1189   out2 << "<P>Some status output would go here." << std::endl;
1190   out2.close();
1191   cl->SaveLogFile(*this);
1192   */
1193 
1194   return 0;
1195 }
1196 
1197 std::string SpinMonDraw::TH1_to_string(TH1 *hspin_pattern)
1198 {
1199   std::string spin_pattern = "";
1200   for (int crossing = 0; crossing < 120; crossing++)
1201   {
1202     int ispin = hspin_pattern->GetBinContent(crossing + 1);
1203     if (ispin == 1)
1204     {
1205       spin_pattern.push_back('+');
1206     }
1207     else if (ispin == -1)
1208     {
1209       spin_pattern.push_back('-');
1210     }
1211     else
1212     {
1213       spin_pattern.push_back('*');
1214     }
1215   }
1216   return spin_pattern;
1217 }
1218 
1219 int SpinMonDraw::DrawGL1pRatio(const std::string &trig1, const std::string &trig2)
1220 {
1221   TH1 *ratio;
1222   float labelsize = 0.05;
1223   if (gl1ptriggers[trig1]->GetSumOfWeights() != 0 && gl1ptriggers[trig2]->GetSumOfWeights() != 0)
1224   {
1225     ratio = (TH1I *) gl1ptriggers[trig1]->Clone();
1226     ratio->Divide(gl1ptriggers[trig2]);
1227     ratio->SetTitle(Form("%s / %s", trig1.c_str(), trig2.c_str()));
1228     ratio->GetXaxis()->SetLabelSize(labelsize);
1229     ratio->GetYaxis()->SetLabelSize(labelsize);
1230     ratio->SetStats(false);
1231     ratio->DrawCopy();
1232   }
1233   else if (gl1ptriggers[trig1]->GetSumOfWeights() == 0)
1234   {
1235     ratio = (TH1I *) gl1ptriggers[trig1]->Clone();
1236     ratio->SetTitle(Form("%s / %s", trig1.c_str(), trig2.c_str()));
1237     ratio->GetXaxis()->SetLabelSize(labelsize);
1238     ratio->GetYaxis()->SetLabelSize(labelsize);
1239     ratio->SetStats(false);
1240     ratio->DrawCopy();
1241     TLatex *lat = new TLatex();
1242     lat->SetTextSize(0.15);
1243     lat->SetTextColor(kRed);
1244     lat->SetTextAngle(45);
1245     lat->SetNDC();
1246     lat->DrawLatex(0.25, 0.15, "NOT ACTIVE");
1247   }
1248   else if (gl1ptriggers[trig2]->GetSumOfWeights() == 0)
1249   {
1250     ratio = (TH1I *) gl1ptriggers[trig2]->Clone();
1251     ratio->SetTitle(Form("%s / %s", trig1.c_str(), trig2.c_str()));
1252     ratio->GetXaxis()->SetLabelSize(labelsize);
1253     ratio->GetYaxis()->SetLabelSize(labelsize);
1254     ratio->SetStats(false);
1255     ratio->DrawCopy();
1256     TLatex *lat = new TLatex();
1257     lat->SetTextSize(0.15);
1258     lat->SetTextColor(kRed);
1259     lat->SetTextAngle(45);
1260     lat->SetNDC();
1261     lat->DrawLatex(0.25, 0.15, "NOT ACTIVE");
1262   }
1263 
1264   return 0;
1265 }