Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MyMonDraw.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MyMonDraw.cc
1 #include "MyMonDraw.h"
2 
3 #include <onlmon/OnlMonClient.h>
4 #include <onlmon/OnlMonDB.h>
5 
6 #include <TAxis.h> // for TAxis
7 #include <TCanvas.h>
8 #include <TDatime.h>
9 #include <TGraphErrors.h>
10 #include <TH1.h>
11 #include <TPad.h>
12 #include <TROOT.h>
13 #include <TSystem.h>
14 #include <TText.h>
15 
16 #include <cstring> // for memset
17 #include <ctime>
18 #include <fstream>
19 #include <iostream> // for operator<<, basic_ostream, basic_os...
20 #include <sstream>
21 #include <vector> // for vector
22 
24  : OnlMonDraw(name)
25 {
26  // this TimeOffsetTicks is neccessary to get the time axis right
27  TDatime T0(2003, 01, 01, 00, 00, 00);
28  TimeOffsetTicks = T0.Convert();
29  dbvars = new OnlMonDB(ThisName);
30  return;
31 }
32 
34 {
35  return 0;
36 }
37 
39 {
41  int xsize = cl->GetDisplaySizeX();
42  int ysize = cl->GetDisplaySizeY();
43  if (name == "MyMon1")
44  {
45  // xpos (-1) negative: do not draw menu bar
46  TC[0] = new TCanvas(name.c_str(), "MyMon Example Monitor", -1, 0, xsize / 2, ysize);
47  // root is pathetic, whenever a new TCanvas is created root piles up
48  // 6kb worth of X11 events which need to be cleared with
49  // gSystem->ProcessEvents(), otherwise your process will grow and
50  // grow and grow but will not show a definitely lost memory leak
51  gSystem->ProcessEvents();
52  Pad[0] = new TPad("mypad1", "who needs this?", 0.1, 0.5, 0.9, 0.9, 0);
53  Pad[1] = new TPad("mypad2", "who needs this?", 0.1, 0.05, 0.9, 0.45, 0);
54  Pad[0]->Draw();
55  Pad[1]->Draw();
56  // this one is used to plot the run number on the canvas
57  transparent[0] = new TPad("transparent0", "this does not show", 0, 0, 1, 1);
58  transparent[0]->SetFillStyle(4000);
59  transparent[0]->Draw();
60  TC[0]->SetEditable(false);
61  }
62  else if (name == "MyMon2")
63  {
64  // xpos negative: do not draw menu bar
65  TC[1] = new TCanvas(name.c_str(), "MyMon2 Example Monitor", -xsize / 2, 0, xsize / 2, ysize);
66  gSystem->ProcessEvents();
67  Pad[2] = new TPad("mypad3", "who needs this?", 0.1, 0.5, 0.9, 0.9, 0);
68  Pad[3] = new TPad("mypad4", "who needs this?", 0.1, 0.05, 0.9, 0.45, 0);
69  Pad[2]->Draw();
70  Pad[3]->Draw();
71  // this one is used to plot the run number on the canvas
72  transparent[1] = new TPad("transparent1", "this does not show", 0, 0, 1, 1);
73  transparent[1]->SetFillStyle(4000);
74  transparent[1]->Draw();
75  TC[1]->SetEditable(false);
76  }
77  else if (name == "MyMon3")
78  {
79  TC[2] = new TCanvas(name.c_str(), "MyMon3 Example Monitor", xsize / 2, 0, xsize / 2, ysize);
80  gSystem->ProcessEvents();
81  Pad[4] = new TPad("mypad5", "who needs this?", 0.1, 0.5, 0.9, 0.9, 0);
82  Pad[5] = new TPad("mypad6", "who needs this?", 0.1, 0.05, 0.9, 0.45, 0);
83  Pad[4]->Draw();
84  Pad[5]->Draw();
85  // this one is used to plot the run number on the canvas
86  // transparent[2] = new TPad("transparent2", "this does not show", 0, 0, 1, 1);
87  // transparent[2]->SetFillStyle(4000);
88  // transparent[2]->Draw();
89  // TC[2]->SetEditable(0);
90  }
91  return 0;
92 }
93 
94 int MyMonDraw::Draw(const std::string &what)
95 {
96  int iret = 0;
97  int idraw = 0;
98  if (what == "ALL" || what == "FIRST")
99  {
100  iret += DrawFirst(what);
101  idraw++;
102  }
103  if (what == "ALL" || what == "SECOND")
104  {
105  iret += DrawSecond(what);
106  idraw++;
107  }
108  if (what == "ALL" || what == "HISTORY")
109  {
110  iret += DrawHistory(what);
111  idraw++;
112  }
113  if (!idraw)
114  {
115  std::cout << __PRETTY_FUNCTION__ << " Unimplemented Drawing option: " << what << std::endl;
116  iret = -1;
117  }
118  return iret;
119 }
120 
121 int MyMonDraw::DrawFirst(const std::string & /* what */)
122 {
124  TH1 *mymon_hist1 = cl->getHisto("MYMON_0","mymon_hist1");
125  TH1 *mymon_hist2 = cl->getHisto("MYMON_1","mymon_hist1");
126  if (!gROOT->FindObject("MyMon1"))
127  {
128  MakeCanvas("MyMon1");
129  }
130  TC[0]->SetEditable(true);
131  TC[0]->Clear("D");
132  Pad[0]->cd();
133  if (mymon_hist1)
134  {
135  mymon_hist1->DrawCopy();
136  }
137  else
138  {
140  TC[0]->SetEditable(false);
141  return -1;
142  }
143  Pad[1]->cd();
144  if (mymon_hist2)
145  {
146  mymon_hist2->DrawCopy();
147  }
148  TText PrintRun;
149  PrintRun.SetTextFont(62);
150  PrintRun.SetTextSize(0.04);
151  PrintRun.SetNDC(); // set to normalized coordinates
152  PrintRun.SetTextAlign(23); // center/top alignment
153  std::ostringstream runnostream;
154  std::string runstring;
155  time_t evttime = cl->EventTime("CURRENT");
156  // fill run number and event time into string
157  runnostream << ThisName << "_1 Run " << cl->RunNumber()
158  << ", Time: " << ctime(&evttime);
159  runstring = runnostream.str();
160  transparent[0]->cd();
161  PrintRun.DrawText(0.5, 1., runstring.c_str());
162  TC[0]->Update();
163  TC[0]->Show();
164  TC[0]->SetEditable(false);
165  return 0;
166 }
167 
168 int MyMonDraw::DrawSecond(const std::string & /* what */)
169 {
171  TH1 *mymon_hist1 = cl->getHisto("MYMON_0","mymon_hist2");
172  TH1 *mymon_hist2 = cl->getHisto("MYMON_1","mymon_hist2");
173  if (!gROOT->FindObject("MyMon2"))
174  {
175  MakeCanvas("MyMon2");
176  }
177  TC[1]->SetEditable(true);
178  TC[1]->Clear("D");
179  Pad[2]->cd();
180  if (mymon_hist1)
181  {
182  mymon_hist1->DrawCopy();
183  }
184  else
185  {
187  TC[1]->SetEditable(false);
188  return -1;
189  }
190  Pad[3]->cd();
191  if (mymon_hist2)
192  {
193  mymon_hist2->DrawCopy();
194  }
195  TText PrintRun;
196  PrintRun.SetTextFont(62);
197  PrintRun.SetTextSize(0.04);
198  PrintRun.SetNDC(); // set to normalized coordinates
199  PrintRun.SetTextAlign(23); // center/top alignment
200  std::ostringstream runnostream;
201  std::string runstring;
202  time_t evttime = cl->EventTime("CURRENT");
203  // fill run number and event time into string
204  runnostream << ThisName << "_2 Run " << cl->RunNumber()
205  << ", Time: " << ctime(&evttime);
206  runstring = runnostream.str();
207  transparent[1]->cd();
208  PrintRun.DrawText(0.5, 1., runstring.c_str());
209  TC[1]->Update();
210  TC[1]->Show();
211  TC[1]->SetEditable(false);
212  return 0;
213 }
214 
216 {
217 
219  int iret = Draw(what);
220  if (iret) // on error no png files please
221  {
222  return iret;
223  }
224  int icnt = 0;
225  for (TCanvas *canvas : TC)
226  {
227  if (canvas == nullptr)
228  {
229  continue;
230  }
231  icnt++;
232  std::string filename = ThisName + "_" + std::to_string(icnt) + "_" +
233  std::to_string(cl->RunNumber()) + "." + type;
234  cl->CanvasToPng(canvas, filename);
235  }
236  return 0;
237 }
238 
240 {
241  int iret = Draw(what);
242  if (iret) // on error no html output please
243  {
244  return iret;
245  }
246 
248 
249  int icnt = 0;
250  for (TCanvas *canvas : TC)
251  {
252  if (canvas == nullptr)
253  {
254  continue;
255  }
256  icnt++;
257  // Register the canvas png file to the menu and produces the png file.
258  std::string pngfile = cl->htmlRegisterPage(*this, canvas->GetTitle(), std::to_string(icnt), "png");
259  cl->CanvasToPng(canvas, pngfile);
260  }
261 
262  // Now register also EXPERTS html pages, under the EXPERTS subfolder.
263 
264  std::string logfile = cl->htmlRegisterPage(*this, "EXPERTS/Log", "log", "html");
265  std::ofstream out(logfile.c_str());
266  out << "<HTML><HEAD><TITLE>Log file for run " << cl->RunNumber()
267  << "</TITLE></HEAD>" << std::endl;
268  out << "<P>Some log file output would go here." << std::endl;
269  out.close();
270 
271  std::string status = cl->htmlRegisterPage(*this, "EXPERTS/Status", "status", "html");
272  std::ofstream out2(status.c_str());
273  out2 << "<HTML><HEAD><TITLE>Status file for run " << cl->RunNumber()
274  << "</TITLE></HEAD>" << std::endl;
275  out2 << "<P>Some status output would go here." << std::endl;
276  out2.close();
277  cl->SaveLogFile(*this);
278  return 0;
279 }
280 
281 int MyMonDraw::DrawHistory(const std::string & /* what */)
282 {
283  int iret = 0;
284  // you need to provide the following vectors
285  // which are filled from the db
286  std::vector<float> var;
287  std::vector<float> varerr;
288  std::vector<time_t> timestamp;
289  std::vector<int> runnumber;
290  std::string varname = "mymondummy";
291  // this sets the time range from whihc values should be returned
292  time_t begin = 0; // begin of time (1.1.1970)
293  time_t end = time(nullptr); // current time (right NOW)
294  iret = dbvars->GetVar(begin, end, varname, timestamp, runnumber, var, varerr);
295  if (iret)
296  {
297  std::cout << __PRETTY_FUNCTION__ << " Error in db access" << std::endl;
298  return iret;
299  }
300  if (!gROOT->FindObject("MyMon3"))
301  {
302  MakeCanvas("MyMon3");
303  }
304  // timestamps come sorted in ascending order
305  float *x = new float[var.size()];
306  float *y = new float[var.size()];
307  float *ex = new float[var.size()];
308  float *ey = new float[var.size()];
309  int n = var.size();
310  for (unsigned int i = 0; i < var.size(); i++)
311  {
312  // std::cout << "timestamp: " << ctime(&timestamp[i])
313  // << ", run: " << runnumber[i]
314  // << ", var: " << var[i]
315  // << ", varerr: " << varerr[i]
316  // << std::endl;
317  x[i] = timestamp[i] - TimeOffsetTicks;
318  y[i] = var[i];
319  ex[i] = 0;
320  ey[i] = varerr[i];
321  }
322  Pad[4]->cd();
323  if (gr[0])
324  {
325  delete gr[0];
326  }
327  gr[0] = new TGraphErrors(n, x, y, ex, ey);
328  gr[0]->SetMarkerColor(4);
329  gr[0]->SetMarkerStyle(21);
330  gr[0]->Draw("ALP");
331  gr[0]->GetXaxis()->SetTimeDisplay(1);
332  gr[0]->GetXaxis()->SetLabelSize(0.03);
333  // the x axis labeling looks like crap
334  // please help me with this, the SetNdivisions
335  // don't do the trick
336  gr[0]->GetXaxis()->SetNdivisions(-1006);
337  gr[0]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
338  gr[0]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
339  delete[] x;
340  delete[] y;
341  delete[] ex;
342  delete[] ey;
343 
344  varname = "mymoncount";
345  iret = dbvars->GetVar(begin, end, varname, timestamp, runnumber, var, varerr);
346  if (iret)
347  {
348  std::cout << __PRETTY_FUNCTION__ << " Error in db access" << std::endl;
349  return iret;
350  }
351  x = new float[var.size()];
352  y = new float[var.size()];
353  ex = new float[var.size()];
354  ey = new float[var.size()];
355  n = var.size();
356  for (unsigned int i = 0; i < var.size(); i++)
357  {
358  // std::cout << "timestamp: " << ctime(&timestamp[i])
359  // << ", run: " << runnumber[i]
360  // << ", var: " << var[i]
361  // << ", varerr: " << varerr[i]
362  // << std::endl;
363  x[i] = timestamp[i] - TimeOffsetTicks;
364  y[i] = var[i];
365  ex[i] = 0;
366  ey[i] = varerr[i];
367  }
368  Pad[5]->cd();
369  if (gr[1])
370  {
371  delete gr[1];
372  }
373  gr[1] = new TGraphErrors(n, x, y, ex, ey);
374  gr[1]->SetMarkerColor(4);
375  gr[1]->SetMarkerStyle(21);
376  gr[1]->Draw("ALP");
377  gr[1]->GetXaxis()->SetTimeDisplay(1);
378  // TC[2]->Update();
379  // h1->GetXaxis()->SetTimeDisplay(1);
380  // h1->GetXaxis()->SetLabelSize(0.03);
381  gr[1]->GetXaxis()->SetLabelSize(0.03);
382  gr[1]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
383  gr[1]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
384  // h1->Draw();
385  delete[] x;
386  delete[] y;
387  delete[] ex;
388  delete[] ey;
389 
390  TC[2]->Update();
391  return 0;
392 }