AlcapDAQ  1
TOnlineFrame.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <sstream>
4 #include <fstream>
5 #include <vector>
6 #include <time.h>
7 #include <stdlib.h>
8 #include <libgen.h>
9 #include <iostream>
10 
11 #include "TApplication.h"
12 #include "TGButton.h"
13 #include "TRootEmbeddedCanvas.h"
14 #include "TGStatusBar.h"
15 #include "TCanvas.h"
16 #include "TROOT.h"
17 #include "TGTextEntry.h"
18 #include "TGLabel.h"
19 #include "TG3DLine.h"
20 #include "TGFileDialog.h"
21 #include "TObjString.h"
22 #include "TH1.h"
23 #include "TH1D.h"
24 #include "TH1F.h"
25 #include "TH1I.h"
26 
27 #include "getHist.h"
28 #include "TOnlineFrame.h"
29 
30 using std::ifstream;
31 using std::cout;
32 using std::endl;
33 
34 TOnlineFrame::TOnlineFrame(const TGWindow * p,std::string module_file_name):TGMainFrame(p, width,
35  height)
36 {
37 
38  fCurrentDisplay = 8;
39  run_nr = 0;
40 
41  // read macroses from the external file
42  //const char *is_name = "/home/daq/DAQ/online-display/MODULES";
43  const char *env_name = "DAQdir";
44  std::string env_value = "";
45  std::string is_name;
46  if ( getenv(env_name) )
47  {
48  if (module_file_name.empty() ) module_file_name="MODULES";
49  env_value = getenv(env_name);
50  is_name = env_value + "/online-display/"+module_file_name;
51  }
52  else
53  {
54  std::cerr << "***ERROR! shell variable " << env_name << " is not set. The program will not be able to find display modules." << std::endl;
55  }
56 
57  //const char *is_name = "/home/daq/DAQ/online-display/MODULES";
58  std::cout << "Reading modules from file [" << is_name << "]" << std::endl;
59  ifstream *is = new ifstream( is_name.c_str() );
60  char buf[1024];
61  std::string args;
62  while ( is->good() )
63  {
64  *is >> std::ws;
65  is->getline(buf,1024);
66  if ( buf[0] == '#' ) continue;
67  if ( is->gcount() < 2 ) break;
68  std::istringstream iss (buf,std::istringstream::in);
69  screen_info info={"","","",false};
70  iss >> std::ws >> info.visibleName >> std::ws >> info.macroName>> std::ws >>args;
71  if (!args.empty()) {
72  info.macroArgs=args;
73  info.hasArgs =true;
74  }
75  screens.push_back(info);
76  std::cout << buf << std::endl;
77  args="";
78  }
79  delete is;
80 
81  // configure macro path
82  std::string macro_path = gROOT->GetMacroPath();
83  macro_path += std::string(":")+std::string(env_value)+std::string("/online-display/modules");
84  gROOT->SetMacroPath( macro_path.c_str() );
85 
86 
87  // a little frame at the top
88  fTopFrame = new TGHorizontalFrame(this, width - 10, 30, kChildFrame);//, kFixedWidth);
89  AddFrame(fTopFrame, new TGLayoutHints(kLHintsExpandX) );
90 
91  // an "update" button
92  fUpdateButton = new TGTextButton(fTopFrame, "Update", B_UPDATE);
93  fUpdateButton->Associate(this);
94  fTopFrame->AddFrame(fUpdateButton, new TGLayoutHints(kLHintsLeft,2,2,2,2));
95 
96  // Autoupdate checkbox
97  fAutoUpdate = new TGCheckButton(fTopFrame, "AutoUpdate", B_AUTOUPDATE);
98  fAutoUpdate->Associate(this);
99  fTopFrame->AddFrame(fAutoUpdate, new TGLayoutHints(kLHintsLeft|kLHintsCenterY));
100 
101  TGLabel *label = new TGLabel(fTopFrame,"every");
102  fTopFrame->AddFrame(label, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,0,2,2,2));
103 
104  fAutoUpdateTime = new TGTextEntry(fTopFrame,"10");
105  fAutoUpdateTime->SetWidth(20);
106  fAutoUpdateTime->SetMaxLength(4);
107  fTopFrame->AddFrame(fAutoUpdateTime, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,2,2,2));
108 
109  label = new TGLabel(fTopFrame,"s");
110  fTopFrame->AddFrame(label, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,1,2,2,2));
111 
112  // a "cycle" checkbox
113  fCycleDisplays = new TGCheckButton(fTopFrame, "Cycle", B_CYCLE);
114  fCycleDisplays->Associate(this);
115  fTopFrame->AddFrame(fCycleDisplays, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,1,2,2));
116 
117 
118  // separator
119  TGVertical3DLine *vline = new TGVertical3DLine(fTopFrame);
120  fTopFrame->AddFrame(vline, new TGLayoutHints(kLHintsLeft|kLHintsExpandY,1,2,2,2));
121 
122  // server name
123  label = new TGLabel(fTopFrame,"Server");
124  fTopFrame->AddFrame(label, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,1,2,2));
125 
126  fServerName = new TGTextEntry(fTopFrame,"");
127  fServerName->SetWidth(150);
128  fServerName->SetMaxLength(64);
129  fTopFrame->AddFrame(fServerName, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,2,2,2));
130 
131  // server port
132  label = new TGLabel(fTopFrame,"port");
133  fTopFrame->AddFrame(label, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,2,2,2));
134 
135  fServerPort = new TGTextEntry(fTopFrame,"");
136  fServerPort->SetWidth(50);
137  fServerPort->SetMaxLength(6);
138  fTopFrame->AddFrame(fServerPort, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,2,2,2));
139 
140  // connect to server button
141  fConnectButton = new TGTextButton(fTopFrame, "Connect", B_CONNECT);
142  fConnectButton->Associate(this);
143  fTopFrame->AddFrame(fConnectButton, new TGLayoutHints(kLHintsLeft,2,2,2,2));
144 
145  // separator
146  vline = new TGVertical3DLine(fTopFrame);
147  fTopFrame->AddFrame(vline, new TGLayoutHints(kLHintsLeft|kLHintsExpandY,1,2,2,2));
148 
149  // ROOT file
150  label = new TGLabel(fTopFrame,"File");
151  fTopFrame->AddFrame(label, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,2,2,2));
152 
153  fFileName = new TGTextEntry(fTopFrame,"");
154  fFileName->SetWidth(100);
155  fFileName->SetMaxLength(32);
156  //fFileName->SetState(kFALSE);
157  fFileName->Associate(this);
158  fTopFrame->AddFrame(fFileName, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,2,2,2,2));
159 
160 
161  // Open File button
162  fFileOpenButton = new TGTextButton(fTopFrame, "Open", B_FILE_OPEN);
163  fFileOpenButton->Associate(this);
164  fTopFrame->AddFrame(fFileOpenButton, new TGLayoutHints(kLHintsLeft,2,2,2,2));
165 
166  // separator
167  vline = new TGVertical3DLine(fTopFrame);
168  fTopFrame->AddFrame(vline, new TGLayoutHints(kLHintsLeft|kLHintsExpandY,1,2,2,2));
169 
170 
171 
172  // a "print" button
173  fPrintButton = new TGTextButton(fTopFrame, "Print to File", B_PRINT);
174  fPrintButton->Associate(this);
175  fTopFrame->AddFrame(fPrintButton, new TGLayoutHints(kLHintsRight,2,2,2,2));
176 
177 
178 
179  // containter for user buttons and canvas
180  TGHorizontalFrame *frame_aux = new TGHorizontalFrame(this, 50, 80);
181  AddFrame(frame_aux, new TGLayoutHints(kLHintsExpandY|kLHintsExpandX,1,1,1,1) );
182 
183 
184  // left frame for user script buttons
185  TGVerticalFrame *frame_user = new TGVerticalFrame(frame_aux, 10, 30);
186  frame_aux->AddFrame(frame_user, new TGLayoutHints(kLHintsExpandY,1,1,1,1) );
187 
188 
189 
190  // a menu for changing screens
191  //fScreenFrame = new TGHorizontalFrame(fTopFrame, 480, 28, kChildFrame);//, kFixedWidth);
192  //fTopFrame->AddFrame(fScreenFrame, new TGLayoutHints(kLHintsLeft));
193  for (unsigned int i = 0; i < screens.size(); i++)
194  {
195  TGTextButton *b = new TGTextButton(frame_user, screens[i].visibleName,
196  SCREENS_BASE + i);
197  b->SetToolTipText((screens[i].macroName + screens[i].macroArgs).c_str());
198  b->Associate(this);
199  frame_user->AddFrame(b, new TGLayoutHints(kLHintsLeft|kFitWidth));
200  fButtons[screens[i].visibleName]=b;
201  }
202 
203  // our big embedded canvas
205  new TRootEmbeddedCanvas("Canvas", frame_aux, width - 10, height - 32,kSunkenFrame|kDoubleBorder|kFitWidth|kFitHeight);
206  fEmbeddedCanvas->SetAutoFit( kTRUE );
207  frame_aux->AddFrame(fEmbeddedCanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 1, 1, 1, 1));
208 
209  fStatusBar = new TGStatusBar(this);
210  AddFrame(fStatusBar, new TGLayoutHints(kLHintsExpandX, 1, 1, 1, 1));
211  int parts[] = {70,10,20};
212  fStatusBar->SetParts(parts,3);
213 
214  SetWindowName("MIDAS Online Display");
215  MapSubwindows();
216  Resize(GetDefaultSize());
217  MapWindow();
218  SetMinWidth(300);
219 
220 // Define the histogram
221  gROOT->LoadMacro("modules/common/get_histogram.C");
222  gROOT->LoadMacro("modules/common/get_histogram_2d.C");
223 
224 }
225 
227 {
228 }
229 
230 Bool_t TOnlineFrame::ProcessMessage(Long_t msg, Long_t param1,
231  Long_t param2)
232 {
233  Bool_t ret = false;
234  char name[1024];
235  char text[1024];
236 
237  switch (GET_MSG(msg))
238  {
239  case kC_COMMAND:
240  switch (GET_SUBMSG(msg))
241  {
242  case kCM_BUTTON:
243  if (param1 >= SCREENS_BASE)
244  {
245  ULong_t ucolor_black;
246  gClient->GetColorByName("#000000",ucolor_black);
247  fButtons[screens[fCurrentDisplay].visibleName]->SetTextColor(ucolor_black);
248  fCurrentDisplay = param1 - SCREENS_BASE;
249  }
250  if ( param1 == B_UPDATE || param1 >= SCREENS_BASE )
251  {
252  UpdateDisplay();
253  }
254  else if (param1 == B_PRINT)
255  {
256  unsigned long int t = time(NULL);
257  sprintf(name,"%s_run_%06ld_%lu.pdf",screens[fCurrentDisplay].visibleName,run_nr,t);
258  fEmbeddedCanvas->GetCanvas()->Print(name);
259  sprintf(name,"%s_run_%06ld_%lu.png",screens[fCurrentDisplay].visibleName,run_nr,t);
260  fEmbeddedCanvas->GetCanvas()->Print(name);
261  sprintf(text,"Canvas printed to file [%s]",name);
262  print_msg(text);
263  }
264  else if ( param1 == B_CONNECT )
265  {
266  if ( ConnectToServer() )
267  {
268  ConsiderAutoupdate( kTRUE );
269  }
270  }
271  else if ( param1 == B_FILE_OPEN )
272  {
273  TGFileInfo fi;
274  const char *file_types[] = {"hist files", "h*.root",
275  0, 0};
276  fi.fFileTypes = file_types;
277  fi.fMultipleSelection = kFALSE;
278  fi.SetMultipleSelection( kFALSE );
279  //TGFileDialog *f = new TGFileDialog(gClient->GetRoot(),this,kFDOpen,&fi);
280  if ( fi.fFilename )
281  {
282  if ( OpenRootFile(fi.fFilename) )
283  {
284  ConsiderAutoupdate( kTRUE );
285  }
286  }
287  }
288  ret = true;
289  break;
290  default:
291  printf("Unknown command received\n");
292  break;
293  } // switch (GET_SUBMSG(msg))
294  break; // case kC_COMMAND
295  case kC_TEXTENTRY:
296  switch (GET_SUBMSG(msg))
297  {
298  case kTE_ENTER:
299  if ( OpenRootFile( fFileName->GetText(), kFALSE ) )
300  {
301  ConsiderAutoupdate( kTRUE );
302  }
303  break;
304  }
305  break; // case kC_TEXTENTRY
306  } // switch (GET_MSG(msg))
307 
308 
309 
310  return ret;
311 }
312 
314  screen_info &current_display=screens[fCurrentDisplay];
315  //runMacro(macro);
316  if(fLoadedMacros.count(current_display.macroName) ==0) {
317  gROOT->LoadMacro(current_display.macroName.c_str());
318  cout<<"Loaded macro: "<<current_display.macroName<<endl;
319  fLoadedMacros.insert(current_display.macroName);
320  }
321  int last_slash=current_display.macroName.rfind("/")+1;
322  std::string command=current_display.macroName.substr(last_slash);
323  int extension_start=command.find(".");
324  command=command.substr(0,extension_start);
325  if(!current_display.hasArgs) command+="()";
326  else command+=current_display.macroArgs;
327  cout<<"Processing Line: "<<command<<endl;
328  gROOT->ProcessLine(command.c_str());
329 
330  cout<< "about to set color"<<endl;
331  ULong_t ucolor_red;
332  gClient->GetColorByName("#FF0000",ucolor_red);
333  fButtons[screens[fCurrentDisplay].visibleName]->SetTextColor(ucolor_red);
334  gPad->Update();
335 }
336 
338 {
339  DeleteWindow();
340  gApplication->Terminate(0);
341  exit(1);
342 }
343 
345 {
346  if(fCycleDisplays->GetState() == kButtonDown)
347  {
348  fCurrentDisplay = (fCurrentDisplay+1) % screens.size();
349  const char *macro = screens[fCurrentDisplay].macroName.c_str();
350  runMacro(macro);
351  }
352 }
353 
360 void TOnlineFrame::ConsiderAutoupdate(const Bool_t force)
361 {
362  if (((fAutoUpdate->GetState() == kButtonDown) && fCycleDisplays->GetState()) != kButtonDown || force )
363  {
364  const char *macro = screens[fCurrentDisplay].macroName.c_str();
365  runMacro(macro);
366  }
367 }
368 
369 const char *TOnlineFrame::getServerName() const
370 {
371  return fServerName->GetText();
372 }
373 
374 void TOnlineFrame::setServerName(const char *name)
375 {
376  return fServerName->SetText( name );
377 }
378 
379 const unsigned int TOnlineFrame::getServerPort() const
380 {
381  return atol(fServerPort->GetText());
382 }
383 
384 void TOnlineFrame::setServerPort(const unsigned int port_nr)
385 {
386  char txt[32];
387  sprintf(txt,"%d",port_nr);
388  return fServerPort->SetText( txt );
389 }
390 
391 const unsigned int TOnlineFrame::getAutoUpdateTime() const
392 {
393  unsigned int t = atol(fAutoUpdateTime->GetText());
394  if ( t < 1 ) t = 1;
395  return t;
396 }
397 
399 {
400  TSocket *s = NULL;
401  const char *hostname = getServerName();
402  const unsigned int port_nr = getServerPort();
403  char msg[1024];
404 
405  gROOT->DeleteAll();
406  fEmbeddedCanvas->GetCanvas()->Clear();
407  fEmbeddedCanvas->Clear();
408 
409  ULong_t ucolor_white;
410  gClient->GetColorByName("#ffffff",ucolor_white);
411 
412 
413  if ( (s = openSocket(hostname,port_nr)) == 0 )
414  {
415  sprintf(msg,"Cannot connect to port %d on host [%s]",port_nr,hostname);
416  print_msg(msg);
417  print_msg("ERROR",2);
418  exit(1);
419  //fServerName->ChangeBackground(ucolor_white);
420  }
421  else
422  {
423  sprintf(msg,"Connected to remote server %s:%d",hostname,port_nr);
424  print_msg(msg);
425  sprintf(msg,"%s:%d",hostname,port_nr);
426  print_msg(msg,2);
427  //ConsiderAutoupdate( kTRUE );
428  ULong_t ucolor_green;
429  gClient->GetColorByName("#A0F5A0",ucolor_green);
430  fServerName->ChangeBackground(ucolor_green);
431  }
432  //fFileName->SetText("");
433  fFileName->ChangeBackground(ucolor_white);
434  fpSock = s;
435  return s;
436 }
437 
438 TFile *TOnlineFrame::OpenRootFile(const char *filename, const Bool_t update_filename)
439 {
440  TFile *f = NULL;
441  char msg[1024];
442 
443  gROOT->DeleteAll();
444  fEmbeddedCanvas->GetCanvas()->Clear();
445  fEmbeddedCanvas->Clear();
446 
447  ULong_t ucolor_white;
448  gClient->GetColorByName("#ffffff",ucolor_white);
449 
450 
451  if ( (f = openRootFile(filename)) == 0 )
452  {
453  sprintf(msg,"Cannot open ROOT file [%s]",filename);
454  print_msg(msg);
455  print_msg("ERROR",1);
456  print_msg("ERROR",2);
457  exit(1);
458  //fFileName->SetText("");
459  //fFileName->ChangeBackground(ucolor_white);
460  }
461  else
462  {
463  sprintf(msg,"Connected to ROOT file %s",filename);
464  print_msg(msg);
465  print_msg(basename((char*)filename),1);
466  print_msg("File",2);
467  //fFileName->SetText(basename(filename));
468  //ConsiderAutoupdate( kTRUE );
469  ULong_t ucolor_green;
470  gClient->GetColorByName("#A0FfA0",ucolor_green);
471  fFileName->ChangeBackground(ucolor_green);
472  }
473 
474  if ( update_filename )
475  fFileName->SetText(basename((char*)filename));
476 
477  fServerName->ChangeBackground(ucolor_white);
478 
479  return f;
480 }
481 
482 
483 void TOnlineFrame::runMacro(const char *macro)
484 {
485 
486  char txt[1024];
487 
489  sprintf(txt,"%ld",run_nr);
490  print_msg(txt,1);
491  sprintf(txt,"Executing macro [%s]",macro);
492  print_msg(txt);
493 
494  gROOT->DeleteAll();
496  fEmbeddedCanvas->GetCanvas()->Clear();
497  fEmbeddedCanvas->Clear();
498  gROOT->cd();
499  gROOT->Macro(macro);
500  // check status
501  int status = get_status_code();
502  if ( status != 0 )
503  {
504  const char *msg = "";
505  switch ( status )
506  {
507  case RDISP_ERR_NO_CON:
508  msg = "No connection to remote server";
509  break;
511  msg = "Bad response from the server";
512  break;
513  case RDISP_ERR_NO_RESPONSE:
514  msg = "No response from the server";
515  break;
516  case RDISP_ERR_NO_SOURCE:
517  msg = "No sources opened";
518  break;
520  msg = "Broken pipe";
521  break;
522  case RDISP_ERR_NO_FILE:
523  msg = "Cannot open ROOT file";
524  break;
525  case RDISP_ERR_NO_FOLDER:
526  msg = "Cannot load root folder from the ROOT file";
527  break;
528  default:
529  msg = "Unknown error";
530  break;
531  }
532  print_msg( msg );
533  }
534 }
535 
536 void TOnlineFrame::print_msg(const char *msg, const Int_t partidx)
537 {
538  printf("%s\n",msg);
539  fStatusBar->SetText(msg, partidx);
540 }
541 
542 //TObjArray *TOnlineFrame::GetHistTitles()
543 //{
544  //if(!fpSock)
545  //return NULL;
546 
547  //TMessage *msg;
548  //fpSock->Send("LIST");
549  //fpSock->Recv(msg);
550  //TObjArray *objArray = (TObjArray*)msg->ReadObject(msg->GetClass());
551  //delete msg;
552  //return objArray;
553 //}
554 
555 
556 
557 TH1* TOnlineFrame::GetHist(const char * histname)
558 {
559  if (!fpSock)
560  return NULL;
561 
562  char req[2048];
563  sprintf(req, "GET %s", histname);
564  TMessage *msg;
565 
566  fpSock->Send(req);
567  fpSock->Recv(msg);
568  TH1 *hist = (TH1*) msg->ReadObject(msg->GetClass());
569  //hist->Print();
570  //hist->Draw();
571 
572  delete msg;
573  return hist;
574 }
575 
576 std::vector<TString> TOnlineFrame::GetHistTitles()
577 {
578  std::vector<TString> v;
579  if(!fpSock)
580  return v;
581 
582  fpSock->Send("LIST");
583  TMessage *msg;
584  fpSock->Recv(msg);
585  TObjArray *objArray = (TObjArray *)msg->ReadObject(msg->GetClass());
586  for (int i = 0; i < objArray->GetEntries(); ++i)
587  {
588  TObjString *title = (TObjString *)objArray->At(i);
589  v.push_back((TString)title->GetString());
590  }
591  delete msg;
592  return v;
593 }