Back to home page

sPhenix code displayed by LXR

 
 

    


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

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