Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Poms.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Poms.cc
1 /****************************************************************************\
2  *
3  * PomsClient.C -- A program to graphically launch and control all online
4  * monitoring for PHENIX subsystems.
5  * This program requires the ROOT runtime environment and each subsystems
6  * individual online monitoring client macros.
7  *
8  * Program developed at Brookhaven National Laboratory for the PHENIX
9  * collaboration to be used by offline shifters.
10  *
11  *
12  *
13  * Copyright 2003 Phenix Collaboration
14  *
15  *
16  * M. McCain (mcm99c@acu.edu) January 2003
17  *
18  * Credit to Ryan Roth (LANL) for coding style and example of ROOT GUI
19  * in his implementation of HVDP (High Voltage Display Program)
20  ****************************************************************************
21  */
22 #include "Poms.h"
23 
24 #include <onlmon/OnlMonClient.h>
25 
26 #include <GuiTypes.h> // for kHorizontalFrame, kRaisedFrame
27 #include <TCanvas.h>
28 #include <TGButton.h>
29 #include <TGClient.h> // for TGClient, gClient
30 #include <TGLayout.h> // for TGLayoutHints, kLHintsTop, kLHintsE...
31 #include <TGMenu.h>
32 #include <TGMsgBox.h>
33 #include <TGString.h> // for TGHotString
34 #include <TList.h> // for TList
35 #include <TROOT.h>
36 #include <TSeqCollection.h> // for TSeqCollection
37 #include <TString.h> // for TString
38 #include <WidgetMessageTypes.h> // for GET_MSG, GET_SUBMSG, kCM_BUTTON
39 
40 #include <cmath>
41 #include <cstdlib>
42 #include <cstring> // for strlen
43 #include <iostream>
44 
45 const int SUBSYSTEM_ACTION_ID_BEGIN = 10001;
46 //const ULong_t SHUTTER_ITEM_BG_COLOR = 0xffaacc; // color is rrggbb (red, green, blue in hex)
47 
48 const char* pomsFileTypes[] =
49  {
50  "PHENIX raw data files", "*.prdf",
51  "All files", "*",
52  nullptr, nullptr};
53 
55 // PomsMainFrame Implementation //
57 
58 // Init Singleton instance
60 
62 {
63  if (!_instance)
64  _instance = new PomsMainFrame(gClient->GetRoot(), 1, 1);
65 
66  return _instance;
67 }
68 
69 PomsMainFrame::PomsMainFrame(const TGWindow* p, UInt_t w, UInt_t h)
70  : TGMainFrame(p, w, h)
71  , _rootHorizPad(10)
72  , _rootVertPad(0)
73  , _windowPad(20)
74 {
75  // Constructor sets up window widgets
76 
77  std::cout << POMS_VER << "PomsMainFrame constructor called..." << std::endl;
78 
79  // Find macro directory
80  if (getenv("ONLMON_MACROS"))
81  {
82  _macroPath = getenv("ONLMON_MACROS");
83  }
84  else
85  {
86  std::cout << "Environment variable ONLMON_MACROS not set, using current dir" << std::endl;
87  _macroPath = "./";
88  }
89  // Discover root window properties
90  TGFrame* rootWin = (TGFrame*) gClient->GetRoot();
91  _rootWidth = rootWin->GetDefaultWidth();
92  if (_rootWidth > 2000)
93  {
94  _rootWidth = _rootWidth / 2;
95  }
96  _rootHeight = rootWin->GetDefaultHeight();
97 
98  std::cout << POMS_VER << "Screen Width: " << _rootWidth << std::endl;
99  std::cout << POMS_VER << "Screen Height: " << _rootHeight << std::endl;
100 
101  TGLayoutHints* menuLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
102 
103  // TODO:
104  // Add close button
105 
106  // Setup MenuBar
107  _menuFile = new TGPopupMenu(gClient->GetRoot());
108  _menuFile->AddEntry("&Exit", M_FILE_EXIT);
109  _menuFile->Associate(this);
110  _menuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame | kRaisedFrame);
111  _menuBar->AddPopup("&File", _menuFile, menuLayout);
112 
113  _menuWindow = new TGPopupMenu(gClient->GetRoot());
114  _menuWindow->AddEntry("&Align Control Bar to Right", M_WINDOW_ALIGNRIGHT);
115  _menuWindow->AddEntry("&Tile All", M_WINDOW_TILEALL);
116  _menuWindow->Associate(this);
117  _menuBar->AddPopup("&Window", _menuWindow, menuLayout);
118  _menuBar->AddPopup("&DontpushThis", _menuFile, menuLayout);
119  AddFrame(_menuBar, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX,
120  0, 0, 1, 1));
121 
122  // Standard Window Setup functions
123  SetWindowName("POMS: PHENIX Online Monitoring System");
124  _shutter = nullptr;
125 }
126 
128 {
129  _macroPath = path;
130 }
131 
133 {
135  // Let macro know what's happening
136  std::cout << POMS_VER << "Attempting Build of PomsMainFrame..." << std::endl;
137 
138  // Build Subsystem Shutter
139  if (_shutter)
140  {
141  delete _shutter;
142  }
144  AddFrame(_shutter, new TGLayoutHints(kLHintsTop | kLHintsExpandX | kLHintsExpandY));
145 
146  MapSubwindows();
147  MapWindow();
148  AlignRight();
149  int xsize = cl->GetDisplaySizeX();
150  if (xsize > 2000)
151  {
152  xsize = xsize / 2;
153  }
154  int ysize = cl->GetDisplaySizeY();
155  xsize -= (_shutter->GetDefaultWidth()) + 30;
156  ysize -= 100;
157  cl->SetDisplaySizeX(xsize);
158  cl->SetDisplaySizeY(ysize);
159 }
160 
162 {
163  // Destructor gets rid of widgets
164 
165  delete _closeButton;
166  delete _menuBar;
167  delete _menuFile;
168  delete _shutter;
169  delete _menuWindow;
170 
171  //TODO: Add code to clean up threads
172 
173  _instance = nullptr;
174 }
175 
177 {
178  // Standard close window routine
179  TGMainFrame::CloseWindow();
180  std::cout << "\n\n"
181  << std::endl; // Prevent prompt from displaying at end of output
182  gROOT->ProcessLine(".q");
183 }
184 
185 Bool_t PomsMainFrame::ProcessMessage(Long_t msg, Long_t parm1, Long_t /* parm2 */)
186 {
187  // Function that defines what to do when window widgets are activated
188 
189  int status = 1;
190 
191 #ifdef DEBUG
192 
193  // Debug widgets
194  std::cout << "Msg = " << msg << std::endl
195  << "GET_MSG = " << GET_MSG(msg) << std::endl
196  << "SUB_MSG = " << GET_SUBMSG(msg) << std::endl
197  << "parm1 = " << parm1 << std::endl
198  << "parm2 = " << parm2 << std::endl;
199 
200 #endif
201 
202  switch (GET_MSG(msg))
203  {
204  case kC_COMMAND: //command type event
205 
206  switch (GET_SUBMSG(msg))
207  {
208  case kCM_MENU:
209  switch (parm1)
210  {
211  case M_FILE_EXIT:
212  CloseWindow();
213  break;
214 
215  case M_WINDOW_ALIGNRIGHT:
216  AlignRight();
217  break;
218  case M_WINDOW_TILEALL:
219  TileAllCanvases();
220  break;
221 
222  default:
223  break;
224  }
225  break;
226 
227  case kCM_BUTTON:
228  switch (parm1)
229  {
230  default:
231  HandleButtonPoms(parm1);
232  break;
233  }
234  }
235  break;
236  }
237 
238  int retval;
239  if (status != 1) // ERROR -- Create Message Window
240  {
241  new TGMsgBox(gClient->GetRoot(), this,
242  POMS_VER, "General error in executing widget handler!",
243  kMBIconStop, kMBOk, &retval);
244  }
245 
246  return kTRUE;
247 }
248 
250 {
251  // Check to see if button belongs to SubSystemAction
252  if (parm1 > (SUBSYSTEM_ACTION_ID_BEGIN - 1))
253  {
255 
256  if (!action)
257  return -1;
258 
259  return action->Execute();
260  }
261 
262  return -1;
263 }
264 
266  int addDefaultActions, int loadLibrary)
267 {
268  SubSystem* sub = nullptr;
269 
270  try
271  {
272  sub = new SubSystem(name, prefix, loadLibrary);
273 
274  if (addDefaultActions != 0)
275  sub->AddDefaultActions();
276 
277  _subSystemList.push_back(sub);
278  std::cout << POMS_VER << "SubSystem " << name << " added..." << std::endl;
279  }
280  catch (char* str)
281  {
282  std::cout << POMS_VER << "Unable to add subsystem " << name << "!" << std::endl;
283  std::cout << "\t" << str << std::endl;
284  delete str;
285  delete sub;
286  }
287  return sub;
288 }
289 
291 {
292  _subSystemList.push_back(subSystem);
293  std::cout << POMS_VER << "SubSystem " << subSystem->GetName() << " added..." << std::endl;
294  return subSystem;
295 }
296 
298 {
299  TGShutter* shutter = new TGShutter(this);
300  TGShutterItem* shutterItem;
301  TGCompositeFrame* container;
302  TGTextButton* button;
303  TGLayoutHints* layout;
304 
305  SubSystemList::iterator subSystem;
306  SubSystemActionList* actionList;
307  SubSystemActionList::iterator action;
308  int shutterItemId = 101;
309 
310  std::cout << POMS_VER << "Building SubSystem Shutter..." << std::endl;
311 
312  // Describe layout for buttons in shutter
313  layout = new TGLayoutHints(kLHintsExpandX | kLHintsTop, 5, 5, 0, 0);
314 
315  for (subSystem = _subSystemList.begin(); subSystem != _subSystemList.end(); ++subSystem)
316  {
317  actionList = (*subSystem)->GetActions();
318  action = actionList->begin();
319 
320  // Only add SubSystem if it has actions associated with it.
321  if (action != actionList->end())
322  {
323  std::cout << POMS_VER << "\tAdding " << (*subSystem)->GetName() << " to shutter" << std::endl;
324 
325  shutterItem = new TGShutterItem(shutter,
326  new TGHotString((*subSystem)->GetName().c_str()),
327  shutterItemId++);
328  container = (TGCompositeFrame*) shutterItem->GetContainer();
329 
330  for (; action != actionList->end(); ++action)
331  {
332  std::cout << POMS_VER << "\t\tAdding \"" << (*action)->GetDescription() << "\" button..." << std::endl;
333  button = new TGTextButton(container,
334  (*action)->GetDescription().c_str(),
335  (*action)->GetId());
336  button->SetTextColor(0xCC00FF);
337  container->AddFrame(button, layout);
338  button->Associate(this);
339  }
340  shutter->AddItem(shutterItem);
341  }
342  }
343  return shutter;
344 }
345 
347 {
348  Int_t x = (_rootWidth - GetDefaultWidth() - _rootHorizPad);
349  Int_t y = _rootVertPad;
350 
351  UInt_t width = GetDefaultWidth();
352  UInt_t height = _rootHeight - (2 * _rootVertPad) - 90;
353 
354  Resize(width, height);
355  Move(x, y);
356 }
357 
358 void PomsMainFrame::TileCanvases(TList* canvasList)
359 {
360  if (!canvasList)
361  {
362  std::cout << POMS_VER << "cannot tile canvases, canvas list empty!" << std::endl;
363  return;
364  }
365  AlignRight();
366 
367  TCanvas* canvas = (TCanvas*) canvasList->First();
368  int windowCount = canvasList->LastIndex() + 1;
369 
370  int windowCountHoriz = (int) ceil(sqrt((double) windowCount));
371  int windowCountVert = (int) floor(sqrt((double) windowCount));
372 
373  int i;
374  int j;
375 
376  int currX = _rootHorizPad;
377 
378  int width = (int) ((_rootWidth - (2 * _rootHorizPad) -
379  (windowCountHoriz * _windowPad) - GetDefaultWidth()) /
380  windowCountHoriz);
381  int height = (int) ((_rootHeight - (2 * _rootVertPad) - (windowCountVert * _windowPad)) / windowCountVert);
382 
383  for (i = 0; i < windowCountHoriz; i++)
384  {
385  // Reset Vertical Height
386  int currY = _rootVertPad;
387  currX += (width * i) + _windowPad;
388 
389  for (j = 0; j < windowCountVert; j++)
390  {
391  currY += (height * j) + _windowPad;
392 
393  if (canvas)
394  {
395  canvas->SetWindowSize(width, height);
396  canvas->SetWindowPosition(currX, currY);
397 
398  canvas = (TCanvas*) canvasList->After(canvas);
399  }
400  }
401  }
402 }
403 
404 void PomsMainFrame::CascadeCanvases(TList* /* canvasList */)
405 {
406 }
407 
409 {
410  // Scan all subsystems, grab their canvases, tile all together
411  SubSystemList::iterator subSystem;
412  TList* canvasList = new TList();
413 
414  for (subSystem = _subSystemList.begin(); subSystem != _subSystemList.end(); ++subSystem)
415  {
416  canvasList->AddAll((*subSystem)->GetCanvases());
417  (*subSystem)->ShowCanvases();
418  }
419  TileCanvases(canvasList);
420 
421  delete canvasList;
422 }
423 
425 // SubSystem Implementation //
427 
428 SubSystem::SubSystem(const char* name, const char* prefix, int loadLibrary)
429  : _name(name)
430  , _prefix(prefix)
431  , _canvasList(nullptr)
432  , _initialized(0)
433 {
434  std::string macroPath;
435 
436  if ((strlen(name) < 1) || (strlen(prefix) < 1))
437  {
438  const char* error = "ERROR: name and prefix must not be null!";
439  throw error;
440  }
441 
442  if (loadLibrary)
443  {
444  macroPath = PomsMainFrame::Instance()->GetMacroPath();
445  if (macroPath.size() == 0)
446  macroPath = ".";
447  gROOT->LoadMacro((macroPath + "/run_" + _prefix + "_client.C").c_str());
448  }
449 }
450 
452 {
453  delete _canvasList;
454 }
455 
456 TList* SubSystem::GetCanvases(int forceReQuery)
457 {
458  // If canvasList already exists, only requery if forced
459  if (_canvasList && !forceReQuery)
460  return _canvasList;
461 
462  delete _canvasList;
463 
464  TSeqCollection* allCanvases = gROOT->GetListOfCanvases();
465  TCanvas* canvas = (TCanvas*) allCanvases->First();
466  TString* prefix = new TString(_prefix.c_str());
467 
468  prefix->ToLower(); // Avoid case sensitive searching
469 
470  while (canvas)
471  {
472  TString* canvasName = new TString(canvas->GetName());
473  canvasName->ToLower();
474 
475  if (canvasName->Contains(*prefix))
476  {
477  // Canvas belongs to this sub system
478  if (!_canvasList)
479  {
480  // only create canvasList if we have canvases
481  _canvasList = new TList();
482  }
483  _canvasList->Add(canvas);
484  }
485 
486  delete canvasName;
487  canvas = (TCanvas*) allCanvases->After(canvas);
488  }
489 
490  delete prefix;
491 
492  if (!_canvasList)
493  std::cout << POMS_VER << "Canvas list empty for subsystem " << _name << "!" << std::endl;
494 
495  return _canvasList;
496 }
497 
499 {
500  TList* canvasList;
501  TCanvas* canvas;
502 
503  if (!(canvasList = GetCanvases()))
504  return;
505 
506  std::cout << POMS_VER << "Querying subsystem " << _name << " for canvases:" << std::endl;
507  canvas = (TCanvas*) canvasList->First();
508  while (canvas)
509  {
510  std::cout << "\t" << canvas->GetName() << std::endl;
511  canvas = (TCanvas*) canvasList->After(canvas);
512  }
513  std::cout << "End of Canvas List" << std::endl;
514  return;
515 }
516 
518 {
519  TList* canvasList;
520  TCanvas* canvas;
521 
522  if (!(canvasList = GetCanvases()))
523  return;
524 
525  canvas = (TCanvas*) canvasList->First();
526  while (canvas)
527  {
528  canvas->Show();
529  canvas = (TCanvas*) canvasList->After(canvas);
530  }
531  return;
532 }
533 
535 {
536  SubSystemAction* action = nullptr;
537 
538  try
539  {
540  action = new SubSystemAction(this, cmd, description);
541  _actions.push_back(action);
542 
543  std::cout << POMS_VER << "Action " << cmd << " added to " << _name << "..." << std::endl;
544  }
545  catch (char* str)
546  {
547  std::cout << POMS_VER << "Unable to add action " << cmd << "!" << std::endl;
548  std::cout << "\t" << str << std::endl;
549  delete str;
550  delete action;
551  }
552  return action;
553 }
554 
556 {
557  return AddAction(cmd.c_str(), description.c_str());
558 }
559 
561 {
562  _actions.push_back(action);
563 
564  std::cout << POMS_VER << "Action \"" << action->GetDescription() << "\" added to " << _name << "..." << std::endl;
565  return action;
566 }
567 
569 {
570  std::cout << POMS_VER << "Add default actions to subsystem " << _name << "..." << std::endl;
571 
572  // Add Draw Actions
573  AddAction(new SubSystemActionDraw(this));
574  AddAction(new SubSystemActionDrawPS(this));
575  // AddAction(new SubSystemActionDrawHtml(this));
576 
577  // Add Show Canvases Action
578  //AddAction(new SubSystemActionShowCanvases(this));
579 
580  // Add Tile Canvases Action
581  // AddAction(new SubSystemActionTileCanvases(this));
582 }
583 
585 {
587  pmf->TileCanvases(GetCanvases());
588  ShowCanvases();
589 }
590 
592 {
595  ShowCanvases();
596 }
597 
599 // SubSystemAction Implementation //
601 
604 
606  : _running(false)
607  , _parent(parent)
608 {
609  if (!parent)
610  {
611  const char* error = "ERROR: Action must have parent!";
612  throw error;
613  }
614 
615  _id = NextId();
616  _map[_id];
617 }
618 
620  : _running(false)
621  , _parent(parent)
622  , _description(description)
623 {
624  if (!parent)
625  {
626  const char* error = "ERROR: Action must have parent!";
627  throw error;
628  }
629 
630  _id = NextId(); // Id used to assign to buttons, menu items, etc
631  _map[_id] = this; // Add action to lookup table, see PomsMainFrame::HandleButtonPoms()
632 }
633 
634 SubSystemAction::SubSystemAction(SubSystem* parent, const char* cmd, const char* description)
635  : _running(false)
636  , _parent(parent)
637  , _cmd(cmd)
638  , _description(description)
639 {
640  if (!parent || (strlen(cmd) < 1))
641  {
642  const char* error = "ERROR: Action must have parent and command string!";
643  throw error;
644  }
645 
646  _id = NextId();
647  _map[_id] = this;
648 }
649 
651 {
652  _map[_id] = nullptr;
653 }
654 
656 {
657  if (_running)
658  return 0;
659 
660  _running = true;
661  if (!_parent->isInitialized()) // Check to see if DrawInit() has been executed
662  {
663  gROOT->ProcessLine((_parent->GetPrefix() + "DrawInit(1)").c_str());
665  }
666 
667  TSeqCollection* allCanvases = gROOT->GetListOfCanvases();
668  TCanvas* canvas = nullptr;
669  while ((canvas = (TCanvas*) allCanvases->First()))
670  {
671  std::cout << "Deleting Canvas " << canvas->GetName() << std::endl;
672  delete canvas;
673  }
674  gROOT->ProcessLine(_cmd.c_str());
675  _running = false;
676  return 0;
677 }
678 
680 // SubSystemActionDraw Implementation //
682 
684  : SubSystemAction(parent, "Draw")
685 {
686 }
687 
689 {
690  if (_running)
691  return 0;
692 
693  _running = true;
694 
695  if (!_parent->isInitialized()) // Check to see if DrawInit() has been executed
696  {
697  gROOT->ProcessLine((_parent->GetPrefix() + "DrawInit(1)").c_str());
699  }
700 
701  TSeqCollection* allCanvases = gROOT->GetListOfCanvases();
702  TCanvas* canvas = nullptr;
703  while ((canvas = (TCanvas*) allCanvases->First()))
704  {
705  std::cout << "Deleting Canvas " << canvas->GetName() << std::endl;
706  delete canvas;
707  }
708  gROOT->ProcessLine((_parent->GetPrefix() + "Draw()").c_str());
709  _running = false;
710  return 0;
711 }
712 
714 // SubSystemActionSavePlot Implementation //
716 
718  : SubSystemAction(parent, "Save Plots")
719 {
720 }
721 
723 {
724  if (_running)
725  return 0;
726 
727  _running = true;
728  gROOT->ProcessLine((_parent->GetPrefix() + "SavePlot()").c_str());
729  _running = false;
730  return 0;
731 }
732 
734 // SubSystemActionDrawPS Implementation //
736 
738  : SubSystemAction(parent, "Save Postscript")
739 {
740 }
741 
743 {
744  if (_running)
745  return 0;
746 
747  _running = true;
748  gROOT->ProcessLine((_parent->GetPrefix() + "PS()").c_str());
749  _running = false;
750  return 0;
751 }
752 
754 // SubSystemActionDrawHtml Implementation //
756 
758  : SubSystemAction(parent, "Save to HTML")
759 {
760 }
761 
763 {
764  if (_running)
765  return 0;
766 
767  _running = true;
768  gROOT->ProcessLine((_parent->GetPrefix() + "Html()").c_str());
769  _running = false;
770  return 0;
771 }
772 
774 // SubSystemActionShowCanvases Implementation //
776 
778  : SubSystemAction(parent, "Show Canvases")
779 {
780 }
781 
783 {
784  if (_running)
785  return 0;
786 
787  _running = true;
789  _running = false;
790  return 0;
791 }
792 
794 // SubSystemActionTileCanvases Implementation //
796 
798  : SubSystemAction(parent, "Tile Canvases")
799 {
800 }
801 
803 {
804  if (_running)
805  return 0;
806 
807  _running = true;
809  _running = false;
810  return 0;
811 }
812 
813 // -------------------------------------------------------------
814 // ColorShutterItem Implementation
815 // -------------------------------------------------------------
816 
817 ColorShutterItem::ColorShutterItem(const ULong_t bgColor, const TGWindow* p, TGHotString* s,
818  Int_t id, UInt_t options)
819  : TGShutterItem(p, s, id, options)
820 {
821  fButton->ChangeBackground(bgColor);
822 }