Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DaqMonDraw.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DaqMonDraw.cc
1 #include "DaqMonDraw.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 == "DaqMon1")
44  {
45  // xpos (-1) negative: do not draw menu bar
46  TC[0] = new TCanvas(name.c_str(), "DaqMon 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("daqpad1", "who needs this?", 0.1, 0.5, 0.9, 0.9, 0);
53  Pad[1] = new TPad("daqpad2", "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 == "DaqMon2")
63  {
64  // xpos negative: do not draw menu bar
65  TC[1] = new TCanvas(name.c_str(), "DaqMon2 Example Monitor", -xsize / 2, 0, xsize / 2, ysize);
66  gSystem->ProcessEvents();
67  Pad[2] = new TPad("daqpad3", "who needs this?", 0.1, 0.5, 0.9, 0.9, 0);
68  Pad[3] = new TPad("daqpad4", "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 == "DaqMon3")
78  {
79  TC[2] = new TCanvas(name.c_str(), "DaqMon3 Example Monitor", xsize / 2, 0, xsize / 2, ysize);
80  gSystem->ProcessEvents();
81  Pad[4] = new TPad("daqpad5", "who needs this?", 0.1, 0.5, 0.9, 0.9, 0);
82  Pad[5] = new TPad("daqpad6", "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 DaqMonDraw::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 DaqMonDraw::DrawFirst(const std::string & /* what */)
122 {
124  TH1 *daqmon_hist1 = cl->getHisto("DAQMON_0","daqmon_hist1");
125  TH1 *daqmon_hist2 = cl->getHisto("DAQMON_0","daqmon_hist1");
126  if (!gROOT->FindObject("DaqMon1"))
127  {
128  MakeCanvas("DaqMon1");
129  }
130  TC[0]->SetEditable(true);
131  TC[0]->Clear("D");
132  Pad[0]->cd();
133  if (daqmon_hist1)
134  {
135  daqmon_hist1->DrawCopy();
136  }
137  else
138  {
140  TC[0]->SetEditable(false);
141  return -1;
142  }
143  Pad[1]->cd();
144  if (daqmon_hist2)
145  {
146  daqmon_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 DaqMonDraw::DrawSecond(const std::string & /* what */)
169 {
171  TH1 *daqmon_hist1 = cl->getHisto("DAQMON_0","daqmon_hist2");
172  TH1 *daqmon_hist2 = cl->getHisto("DAQMON_0","daqmon_hist2");
173  if (!gROOT->FindObject("DaqMon2"))
174  {
175  MakeCanvas("DaqMon2");
176  }
177  TC[1]->SetEditable(true);
178  TC[1]->Clear("D");
179  Pad[2]->cd();
180  if (daqmon_hist1)
181  {
182  daqmon_hist1->DrawCopy();
183  }
184  else
185  {
187  TC[1]->SetEditable(false);
188  return -1;
189  }
190  Pad[3]->cd();
191  if (daqmon_hist2)
192  {
193  daqmon_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  // Register the 1st canvas png file to the menu and produces the png file.
250  std::string pngfile = cl->htmlRegisterPage(*this, "First Canvas", "1", "png");
251  cl->CanvasToPng(TC[0], pngfile);
252 
253  // idem for 2nd canvas.
254  pngfile = cl->htmlRegisterPage(*this, "Second Canvas", "2", "png");
255  cl->CanvasToPng(TC[1], pngfile);
256  // Now register also EXPERTS html pages, under the EXPERTS subfolder.
257 
258  std::string logfile = cl->htmlRegisterPage(*this, "EXPERTS/Log", "log", "html");
259  std::ofstream out(logfile.c_str());
260  out << "<HTML><HEAD><TITLE>Log file for run " << cl->RunNumber()
261  << "</TITLE></HEAD>" << std::endl;
262  out << "<P>Some log file output would go here." << std::endl;
263  out.close();
264 
265  std::string status = cl->htmlRegisterPage(*this, "EXPERTS/Status", "status", "html");
266  std::ofstream out2(status.c_str());
267  out2 << "<HTML><HEAD><TITLE>Status file for run " << cl->RunNumber()
268  << "</TITLE></HEAD>" << std::endl;
269  out2 << "<P>Some status output would go here." << std::endl;
270  out2.close();
271  cl->SaveLogFile(*this);
272  return 0;
273 }
274 
275 int DaqMonDraw::DrawHistory(const std::string & /* what */)
276 {
277  int iret = 0;
278  // you need to provide the following vectors
279  // which are filled from the db
280  std::vector<float> var;
281  std::vector<float> varerr;
282  std::vector<time_t> timestamp;
283  std::vector<int> runnumber;
284  std::string varname = "daqmondummy";
285  // this sets the time range from whihc values should be returned
286  time_t begin = 0; // begin of time (1.1.1970)
287  time_t end = time(nullptr); // current time (right NOW)
288  iret = dbvars->GetVar(begin, end, varname, timestamp, runnumber, var, varerr);
289  if (iret)
290  {
291  std::cout << __PRETTY_FUNCTION__ << " Error in db access" << std::endl;
292  return iret;
293  }
294  if (!gROOT->FindObject("DaqMon3"))
295  {
296  MakeCanvas("DaqMon3");
297  }
298  // timestamps come sorted in ascending order
299  float *x = new float[var.size()];
300  float *y = new float[var.size()];
301  float *ex = new float[var.size()];
302  float *ey = new float[var.size()];
303  int n = var.size();
304  for (unsigned int i = 0; i < var.size(); i++)
305  {
306  // std::cout << "timestamp: " << ctime(&timestamp[i])
307  // << ", run: " << runnumber[i]
308  // << ", var: " << var[i]
309  // << ", varerr: " << varerr[i]
310  // << std::endl;
311  x[i] = timestamp[i] - TimeOffsetTicks;
312  y[i] = var[i];
313  ex[i] = 0;
314  ey[i] = varerr[i];
315  }
316  Pad[4]->cd();
317  if (gr[0])
318  {
319  delete gr[0];
320  }
321  gr[0] = new TGraphErrors(n, x, y, ex, ey);
322  gr[0]->SetMarkerColor(4);
323  gr[0]->SetMarkerStyle(21);
324  gr[0]->Draw("ALP");
325  gr[0]->GetXaxis()->SetTimeDisplay(1);
326  gr[0]->GetXaxis()->SetLabelSize(0.03);
327  // the x axis labeling looks like crap
328  // please help me with this, the SetNdivisions
329  // don't do the trick
330  gr[0]->GetXaxis()->SetNdivisions(-1006);
331  gr[0]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
332  gr[0]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
333  delete[] x;
334  delete[] y;
335  delete[] ex;
336  delete[] ey;
337 
338  varname = "daqmoncount";
339  iret = dbvars->GetVar(begin, end, varname, timestamp, runnumber, var, varerr);
340  if (iret)
341  {
342  std::cout << __PRETTY_FUNCTION__ << " Error in db access" << std::endl;
343  return iret;
344  }
345  x = new float[var.size()];
346  y = new float[var.size()];
347  ex = new float[var.size()];
348  ey = new float[var.size()];
349  n = var.size();
350  for (unsigned int i = 0; i < var.size(); i++)
351  {
352  // std::cout << "timestamp: " << ctime(&timestamp[i])
353  // << ", run: " << runnumber[i]
354  // << ", var: " << var[i]
355  // << ", varerr: " << varerr[i]
356  // << std::endl;
357  x[i] = timestamp[i] - TimeOffsetTicks;
358  y[i] = var[i];
359  ex[i] = 0;
360  ey[i] = varerr[i];
361  }
362  Pad[5]->cd();
363  if (gr[1])
364  {
365  delete gr[1];
366  }
367  gr[1] = new TGraphErrors(n, x, y, ex, ey);
368  gr[1]->SetMarkerColor(4);
369  gr[1]->SetMarkerStyle(21);
370  gr[1]->Draw("ALP");
371  gr[1]->GetXaxis()->SetTimeDisplay(1);
372  // TC[2]->Update();
373  // h1->GetXaxis()->SetTimeDisplay(1);
374  // h1->GetXaxis()->SetLabelSize(0.03);
375  gr[1]->GetXaxis()->SetLabelSize(0.03);
376  gr[1]->GetXaxis()->SetTimeOffset(TimeOffsetTicks);
377  gr[1]->GetXaxis()->SetTimeFormat("%Y/%m/%d %H:%M");
378  // h1->Draw();
379  delete[] x;
380  delete[] y;
381  delete[] ex;
382  delete[] ey;
383 
384  TC[2]->Update();
385  return 0;
386 }