1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // This class receives monitor histograms from a monitor process and //
21 // provides a graphical user interface for browsing and analysing the //
22 // monitor histograms. //
24 ///////////////////////////////////////////////////////////////////////////////
27 #include <TApplication.h>
35 #include <TGFileDialog.h>
37 #include <TGListTree.h>
40 #include <TGNumberEntry.h>
41 #include <TGSplitter.h>
42 #include <TGTextEntry.h>
43 #include <TGTextView.h>
44 #include <TGToolBar.h>
46 #include <TRootEmbeddedCanvas.h>
52 #include "AliMonitorClient.h"
53 #include "AliMonitorHisto.h"
54 #include "AliMonitorProcess.h"
56 ClassImp(AliMonitorClient)
59 const char* AliMonitorClient::fgSettingsFileName = ".AliMonitorClient";
62 //_____________________________________________________________________________
63 AliMonitorClient::AliMonitorStringDlg::AliMonitorStringDlg(TString& string,
67 AliMonitorDialog(main, 300, 80),
68 fStringLayout(new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2)),
69 fStringLabel(new TGLabel(fFrame, label)),
70 fStringEntry(new TGTextEntry(fFrame, string.Data())),
73 // create a dialog for connecting to a monitor process
75 fFrame->AddFrame(fStringLabel, fStringLayout);
76 fStringEntry->Resize(100, fStringEntry->GetDefaultHeight());
77 fFrame->AddFrame(fStringEntry, fStringLayout);
81 fMain->SetWindowName(title);
82 fMain->MapSubwindows();
84 gClient->WaitFor(fMain);
87 //_____________________________________________________________________________
88 AliMonitorClient::AliMonitorStringDlg::~AliMonitorStringDlg()
97 //_____________________________________________________________________________
98 void AliMonitorClient::AliMonitorStringDlg::OnOkClicked()
100 fString = fStringEntry->GetText();
104 //_____________________________________________________________________________
105 AliMonitorClient::AliMonitorNumberDlg::AliMonitorNumberDlg(Float_t& value,
110 AliMonitorDialog(main, 250, 80),
111 fNumberLayout(new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2)),
112 fNumberLabel(new TGLabel(fFrame, label)),
113 fNumberEntry(new TGNumberEntry(fFrame, value, 4, -1, TGNumberFormat::kNESRealOne)),
116 // create a dialog for getting a number
118 fFrame->AddFrame(fNumberLabel, fNumberLayout);
119 fNumberEntry->SetLimits(TGNumberFormat::kNELLimitMin, min, 0);
120 fFrame->AddFrame(fNumberEntry, fNumberLayout);
124 fMain->SetWindowName(title);
125 fMain->MapSubwindows();
127 gClient->WaitFor(fMain);
130 //_____________________________________________________________________________
131 AliMonitorClient::AliMonitorNumberDlg::~AliMonitorNumberDlg()
136 delete fNumberLayout;
140 //_____________________________________________________________________________
141 void AliMonitorClient::AliMonitorNumberDlg::OnOkClicked()
143 fNumber = fNumberEntry->GetNumber();
148 // constants for menu entries
149 enum {kMenuFileConnect, kMenuFileDisconnect, kMenuFileOpen, kMenuFileExit,
150 kMenuViewToolBar, kMenuViewTree, kMenuViewDescription,
151 kMenuViewReference, kMenuViewStatistics,
152 kMenuFavAdd, kMenuFavDelete,
153 kMenuFavLoad, kMenuFavSave, kMenuFavSaveAs, kMenuFavSaveOnExit,
154 kMenuRefLoad, kMenuRefThreshold,
155 kMenuRefTakeCurrent, kMenuRefSave, kMenuRefSaveAs,
156 kMenuOptLoop, kMenuOptPrint,
157 kMenuOptSave, kMenuOptSaveOnExit,
158 kMenuHelpDoc, kMenuHelpAbout
161 //_____________________________________________________________________________
162 AliMonitorClient::AliMonitorClient():
163 TGMainFrame(gClient->GetRoot(), 500, 300),
165 fMenuBarLayout(new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1)),
166 fMenuBarItemLayout(new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)),
167 fMenuBarHelpLayout(new TGLayoutHints(kLHintsTop | kLHintsRight)),
168 fMenuFile(new TGPopupMenu(gClient->GetRoot())),
169 fMenuView(new TGPopupMenu(gClient->GetRoot())),
170 fMenuFavorites(new TGPopupMenu(gClient->GetRoot())),
171 fMenuReference(new TGPopupMenu(gClient->GetRoot())),
172 fMenuOptions(new TGPopupMenu(gClient->GetRoot())),
173 fMenuHelp(new TGPopupMenu(gClient->GetRoot())),
174 fMenuBar(new TGMenuBar(this, 1, 1, kHorizontalFrame)),
175 fToolBarLayout(new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 2, 2)),
176 fToolBarSep(new TGHorizontal3DLine(this)),
177 fToolBar(new TGToolBar(this, 60, 20, kHorizontalFrame)),
178 fEventNumberLayout(new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 10, 2, 10, 5)),
179 fEventNumber(new TGNumberEntry(fToolBar, 1, 4, 10, TGNumberFormat::kNESInteger)),
184 fLoopOnPicture(NULL),
185 fLoopOffPicture(NULL),
186 fPreviousButton(NULL),
191 fBottomLayout(new TGLayoutHints(kLHintsExpandX | kLHintsBottom)),
192 fLeftLayout(new TGLayoutHints(kLHintsLeft | kLHintsExpandY)),
193 fExpandLayout(new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)),
194 fVerticalFrame(new TGVerticalFrame(this, 10, 10)),
195 fHorizontalFrame(new TGHorizontalFrame(fVerticalFrame, 10, 10)),
196 fTreeFrame(new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame | kFixedWidth)),
197 fTreeCanvas(new TGCanvas(fTreeFrame, 10, 10)),
198 fTree(new TGListTree(fTreeCanvas, kHorizontalFrame)),
199 fHistoPicture(fClient->GetPicture("h1_t.xpm")),
200 fAllItem(fTree->AddItem(NULL, "All")),
201 fFavoritesItem(fTree->AddItem(NULL, "Favorites")),
202 fComparisonItem(fTree->AddItem(NULL, "Comparison")),
203 fTreeSplitter(new TGVSplitter(fHorizontalFrame, 4)),
204 fDrawFrame(new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame)),
205 fDrawCanvas(new TRootEmbeddedCanvas("current monitor histogram", fDrawFrame, 10, 10)),
206 fDescriptionSplitter(new TGHSplitter(fVerticalFrame, 4, 4)),
207 fDescriptionFrame(new TGCompositeFrame(fVerticalFrame, 10, 60, kSunkenFrame | kFixedHeight)),
208 fDescription(new TGTextView(fDescriptionFrame, 10, 60, "")),
209 fServerName("localhost"),
211 fSocketHandler(NULL),
212 fFolder(CreateTopFolder()),
217 fFavoritesFileName(""),
218 fReferenceFileName(""),
219 fReference(CreateTopFolder()),
222 // initialize the monitoring client window
225 fMenuFile->AddEntry("&Connect...", kMenuFileConnect);
226 fMenuFile->AddEntry("&Disconnect...", kMenuFileDisconnect);
227 fMenuFile->HideEntry(kMenuFileDisconnect);
228 fMenuFile->AddEntry("&Open...", kMenuFileOpen);
229 fMenuFile->AddSeparator();
230 fMenuFile->AddEntry("E&xit", kMenuFileExit);
231 fMenuFile->Connect("Activated(Int_t)", "AliMonitorClient", this,
232 "OnMenuActivated(Int_t)");
235 fMenuView->AddEntry("Tool&bar", kMenuViewToolBar);
236 fMenuView->CheckEntry(kMenuViewToolBar);
237 fMenuView->AddEntry("&Tree", kMenuViewTree);
238 fMenuView->CheckEntry(kMenuViewTree);
239 fMenuView->AddEntry("&Description", kMenuViewDescription);
240 fMenuView->CheckEntry(kMenuViewDescription);
241 fMenuView->AddSeparator();
242 fMenuView->AddEntry("&Reference", kMenuViewReference);
243 fMenuView->CheckEntry(kMenuViewReference);
244 AliMonitorHisto::SetDrawRef(kTRUE);
245 fMenuView->AddEntry("&Statistics", kMenuViewStatistics);
246 fMenuView->CheckEntry(kMenuViewStatistics);
247 gStyle->SetOptStat(1110);
248 fMenuView->Connect("Activated(Int_t)", "AliMonitorClient", this,
249 "OnMenuActivated(Int_t)");
252 fMenuFavorites->AddEntry("&Add", kMenuFavAdd);
253 fMenuFavorites->DisableEntry(kMenuFavAdd);
254 fMenuFavorites->AddEntry("&Delete", kMenuFavDelete);
255 fMenuFavorites->DisableEntry(kMenuFavDelete);
256 fMenuFavorites->AddSeparator();
257 fMenuFavorites->AddEntry("&Load...", kMenuFavLoad);
258 fMenuFavorites->AddEntry("&Save", kMenuFavSave);
259 fMenuFavorites->DisableEntry(kMenuFavSave);
260 fMenuFavorites->AddEntry("&Save As...", kMenuFavSaveAs);
261 fMenuFavorites->DisableEntry(kMenuFavSaveAs);
262 fMenuFavorites->AddEntry("Save On &Exit", kMenuFavSaveOnExit);
263 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
264 fMenuFavorites->Connect("Activated(Int_t)", "AliMonitorClient", this,
265 "OnMenuActivated(Int_t)");
268 fMenuReference->AddEntry("&Load...", kMenuRefLoad);
269 fMenuReference->AddEntry("&Threshold...", kMenuRefThreshold);
270 fMenuReference->AddSeparator();
271 fMenuReference->AddEntry("Take &Current", kMenuRefTakeCurrent);
272 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
273 fMenuReference->AddEntry("&Save", kMenuRefSave);
274 fMenuReference->DisableEntry(kMenuRefSave);
275 fMenuReference->AddEntry("Save &As...", kMenuRefSaveAs);
276 fMenuReference->DisableEntry(kMenuRefSaveAs);
277 fMenuReference->Connect("Activated(Int_t)", "AliMonitorClient", this,
278 "OnMenuActivated(Int_t)");
281 fMenuOptions->AddEntry("&Loop Interval...", kMenuOptLoop);
282 fMenuOptions->AddEntry("&Print Command...", kMenuOptPrint);
283 fMenuOptions->AddSeparator();
284 fMenuOptions->AddEntry("&Save Settings", kMenuOptSave);
285 fMenuOptions->AddEntry("Save Settings on &Exit", kMenuOptSaveOnExit);
286 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
287 fMenuOptions->Connect("Activated(Int_t)", "AliMonitorClient", this,
288 "OnMenuActivated(Int_t)");
291 fMenuHelp->AddEntry("&Documentation...", kMenuHelpDoc);
292 fMenuHelp->AddEntry("A&bout...", kMenuHelpAbout);
293 fMenuHelp->Connect("Activated(Int_t)", "AliMonitorClient", this,
294 "OnMenuActivated(Int_t)");
297 fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
298 fMenuBar->AddPopup("&View", fMenuView, fMenuBarItemLayout);
299 fMenuBar->AddPopup("F&avorites", fMenuFavorites, fMenuBarItemLayout);
300 fMenuBar->AddPopup("&Reference", fMenuReference, fMenuBarItemLayout);
301 fMenuBar->AddPopup("&Options", fMenuOptions, fMenuBarItemLayout);
302 fMenuBar->AddPopup("&Help", fMenuHelp, fMenuBarHelpLayout);
304 AddFrame(fMenuBar, fMenuBarLayout);
308 AddFrame(fToolBarSep, fToolBarLayout);
309 AddFrame(fToolBar, fToolBarLayout);
311 // event number field
312 fEventNumber->SetLimits(TGNumberFormat::kNELLimitMin, 1, 0);
313 fToolBar->AddFrame(fEventNumber, fEventNumberLayout);
314 fEventNumber->GetNumberEntry()->Connect("ReturnPressed()",
315 "AliMonitorClient", this,
316 "OnEventNumberChanged()");
317 fEventNumber->GetButtonUp()->Connect("Clicked()",
318 "AliMonitorClient", this,
319 "OnEventNumberChanged()");
320 fEventNumber->GetButtonDown()->Connect("Clicked()",
321 "AliMonitorClient", this,
322 "OnEventNumberChanged()");
325 ToolBarData_t eventButton = {"h1_s.xpm", "draw event histogram",
327 fToolBar->AddButton(this, &eventButton, 5);
328 fEventButton = eventButton.fButton;
329 fEventButton->Connect("Pressed()", "AliMonitorClient", this,
330 "OnEventButtonPressed()");
333 ToolBarData_t sumButton = {"h2_s.xpm", "draw sum histogram",
335 fToolBar->AddButton(this, &sumButton, 5);
336 fSumButton = sumButton.fButton;
337 fSumButton->Connect("Pressed()", "AliMonitorClient", this,
338 "OnSumButtonPressed()");
341 ToolBarData_t runButton = {"h3_s.xpm", "draw run histogram",
343 fToolBar->AddButton(this, &runButton, 5);
344 fRunButton = runButton.fButton;
345 fRunButton->SetDown(kTRUE);
346 fRunButton->Connect("Pressed()", "AliMonitorClient", this,
347 "OnRunButtonPressed()");
351 sprintf(fileName, "%s/MONITOR/loop_on.xpm", gSystem->Getenv("ALICE_ROOT"));
352 ToolBarData_t loopButton = {fileName, "loop over histograms",
354 fToolBar->AddButton(this, &loopButton, 25);
355 fLoopButton = loopButton.fButton;
356 fLoopButton->Connect("Clicked()", "AliMonitorClient", this,
357 "OnLoopButtonClicked()");
358 fLoopOnPicture = gClient->GetPicture(fileName);
359 sprintf(fileName, "%s/MONITOR/loop_off2.xpm", gSystem->Getenv("ALICE_ROOT"));
360 fLoopOffPicture = gClient->GetPicture(fileName);
363 sprintf(fileName, "%s/MONITOR/previous_s.xpm",
364 gSystem->Getenv("ALICE_ROOT"));
365 ToolBarData_t previousButton = {fileName, "go to previous histogram",
367 fToolBar->AddButton(this, &previousButton, 5);
368 fPreviousButton = previousButton.fButton;
369 fPreviousButton->Connect("Clicked()", "AliMonitorClient", this,
370 "OnPreviousButtonClicked()");
373 sprintf(fileName, "%s/MONITOR/next_s.xpm", gSystem->Getenv("ALICE_ROOT"));
374 ToolBarData_t nextButton = {fileName, "go to next histogram",
376 fToolBar->AddButton(this, &nextButton, 5);
377 fNextButton = nextButton.fButton;
378 fNextButton->Connect("Clicked()", "AliMonitorClient", this,
379 "OnNextButtonClicked()");
382 sprintf(fileName, "%s/MONITOR/copy_s.xpm", gSystem->Getenv("ALICE_ROOT"));
383 ToolBarData_t copyButton = {fileName,
384 "copy the current histogram to a new canvas",
386 fToolBar->AddButton(this, ©Button, 25);
387 fCopyButton = copyButton.fButton;
388 fCopyButton->Connect("Clicked()", "AliMonitorClient", this,
389 "OnCopyButtonClicked()");
392 sprintf(fileName, "%s/MONITOR/save_s.xpm", gSystem->Getenv("ALICE_ROOT"));
393 ToolBarData_t saveButton = {fileName, "save the current histogram",
395 fToolBar->AddButton(this, &saveButton, 5);
396 fSaveButton = saveButton.fButton;
397 fSaveButton->Connect("Clicked()", "AliMonitorClient", this,
398 "OnSaveButtonClicked()");
401 ToolBarData_t printButton = {"printer_s.xpm", "print the current histogram",
403 fToolBar->AddButton(this, &printButton, 5);
404 fPrintButton = printButton.fButton;
405 fPrintButton->Connect("Clicked()", "AliMonitorClient", this,
406 "OnPrintButtonClicked()");
409 AddFrame(fVerticalFrame, fExpandLayout);
411 fVerticalFrame->AddFrame(fHorizontalFrame, fExpandLayout);
414 fHorizontalFrame->AddFrame(fTreeFrame, fLeftLayout);
415 fTreeFrame->AddFrame(fTreeCanvas, fExpandLayout);
416 fTreeCanvas->AddFrame(fTree, fExpandLayout);
417 fTree->Connect("Clicked(TGListTreeItem*,Int_t)", "AliMonitorClient",
418 this, "OnTreeClicked(TGListTreeItem*,Int_t)");
419 fTree->Connect("ReturnPressed(TGListTreeItem*)", "AliMonitorClient",
420 this, "OnTreeReturnPressed(TGListTreeItem*)");
423 fTreeFrame->Resize(100, fTreeFrame->GetDefaultHeight());
425 // tree / histogram splitter
426 fTreeSplitter->SetFrame(fTreeFrame, kTRUE);
427 fHorizontalFrame->AddFrame(fTreeSplitter, fLeftLayout);
430 fHorizontalFrame->AddFrame(fDrawFrame, fExpandLayout);
431 fDrawFrame->AddFrame(fDrawCanvas, fExpandLayout);
434 fVerticalFrame->AddFrame(fDescriptionFrame, fBottomLayout);
435 fDescriptionFrame->AddFrame(fDescription, fExpandLayout);
437 // histogram / description splitter
438 fVerticalFrame->AddFrame(fDescriptionSplitter, fBottomLayout);
439 fDescriptionSplitter->SetFrame(fDescriptionFrame, kFALSE);
442 Connect("CloseWindow()", "AliMonitorClient", this, "CloseWindow()");
443 SetWindowName("Monitor Client");
444 SetWMSize(GetWidth(), GetHeight());
446 SetWMPosition(100, 100);
452 // default data members
454 fFolder = CreateTopFolder();
456 fReference = CreateTopFolder();
457 AliMonitorHisto::SetThreshold(5.0);
459 // load saved settings
463 //_____________________________________________________________________________
464 AliMonitorClient::~AliMonitorClient()
468 delete fMenuBarLayout;
469 delete fMenuBarItemLayout;
470 delete fMenuBarHelpLayout;
473 delete fMenuFavorites;
474 delete fMenuReference;
479 delete fEventNumberLayout;
481 delete fToolBarLayout;
485 delete fBottomLayout;
487 delete fExpandLayout;
492 delete fTreeSplitter;
497 delete fDescriptionSplitter;
499 delete fDescriptionFrame;
501 delete fVerticalFrame;
502 delete fHorizontalFrame;
505 fSocketHandler->Remove();
506 fSocket->Send("disconnect");
509 delete fSocketHandler;
512 if (fFolder) delete fFolder;
515 fLoopTimer->TurnOff();
519 if (fReference) delete fReference;
523 //_____________________________________________________________________________
524 void AliMonitorClient::CloseWindow()
526 // terminate the application when the window is closed
528 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
531 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
535 fSocketHandler->Remove();
536 fSocket->Send("disconnect");
540 delete fSocketHandler;
541 fSocketHandler = NULL;
544 gApplication->Terminate(0);
548 //_____________________________________________________________________________
549 void AliMonitorClient::OnNewData()
551 // called when data has arrived from the monitor server
553 if (CheckForNewData()) UpdateAll();
557 //_____________________________________________________________________________
558 void AliMonitorClient::OnMenuActivated(Int_t id)
560 // called when a menu item was selected
564 case kMenuFileConnect: {
565 if (ConnectToServer()) UpdateAll();
569 case kMenuFileDisconnect: {
570 DisconnectFromServer();
574 case kMenuFileOpen: {
575 if (OpenFile()) UpdateAll();
579 case kMenuFileExit: {
584 case kMenuViewToolBar: {
585 ViewToolBar(!fMenuView->IsEntryChecked(kMenuViewToolBar));
589 case kMenuViewTree: {
590 ViewTree(!fMenuView->IsEntryChecked(kMenuViewTree));
594 case kMenuViewDescription: {
595 ViewDescription(!fMenuView->IsEntryChecked(kMenuViewDescription));
599 case kMenuViewReference: {
600 ViewReference(!fMenuView->IsEntryChecked(kMenuViewReference));
605 case kMenuViewStatistics: {
606 ViewStatistics(!fMenuView->IsEntryChecked(kMenuViewStatistics));
613 fMenuFavorites->EnableEntry(kMenuFavSave);
614 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
619 case kMenuFavDelete: {
620 if (DeleteFavorite()) {
623 fMenuFavorites->DisableEntry(kMenuFavDelete);
624 fMenuFavorites->EnableEntry(kMenuFavSave);
625 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
631 if (LoadFavorites()) {
634 fMenuFavorites->DisableEntry(kMenuFavSave);
635 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
641 if (SaveFavorites()) {
642 fMenuFavorites->DisableEntry(kMenuFavSave);
647 case kMenuFavSaveAs: {
648 if (SaveFavoritesAs()) {
649 fMenuFavorites->DisableEntry(kMenuFavSave);
654 case kMenuFavSaveOnExit: {
655 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
656 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
658 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
664 if (LoadReference()) {
667 UpdateComparisonTree();
668 fMenuReference->EnableEntry(kMenuRefSaveAs);
673 case kMenuRefThreshold: {
674 Float_t threshold = AliMonitorHisto::GetThreshold();
675 new AliMonitorNumberDlg(threshold, this,
676 "Comparison with Reference Histograms",
677 "threshold for comparison:", 0.);
678 if (threshold < 0) break;
680 AliMonitorHisto::SetThreshold(threshold);
682 UpdateComparisonTree();
686 case kMenuRefTakeCurrent: {
687 if (TakeCurrentReference()) {
689 UpdateComparisonTree();
690 fMenuReference->EnableEntry(kMenuRefSave);
691 fMenuReference->EnableEntry(kMenuRefSaveAs);
697 if (SaveReference()) {
698 fMenuReference->DisableEntry(kMenuRefSave);
703 case kMenuRefSaveAs: {
704 if (SaveReferenceAs()) {
705 fMenuReference->DisableEntry(kMenuRefSave);
711 Float_t interval = fLoopInterval * 0.001;
712 new AliMonitorNumberDlg(interval, this, "Loop Interval",
713 "loop time in seconds:", 0.1);
714 if (interval < 0) break;
716 fLoopInterval = Int_t(1000 * interval);
719 fLoopTimer->Start(fLoopInterval);
724 case kMenuOptPrint: {
725 TString printCommand(fPrintCommand);
726 new AliMonitorStringDlg(printCommand, this, "Print Command",
727 "shell command for printing:");
728 if (printCommand.IsNull()) break;
730 fPrintCommand = printCommand;
734 case kMenuOptSaveOnExit: {
735 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
736 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
738 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
748 case kMenuHelpAbout: {
750 new TGMsgBox(gClient->GetRoot(), this,
751 "About", "AliMonitorClient $Revision$",
752 kMBIconAsterisk, kMBOk, &result);
758 new TGMsgBox(gClient->GetRoot(), this,
759 "AliMonitorClient", "not yet implemented",
760 kMBIconExclamation, kMBOk, &result);
766 //_____________________________________________________________________________
767 void AliMonitorClient::OnEventNumberChanged()
769 // called when the event number in the tool button was changed
771 if (!fRunButton->IsDown()) {
773 UpdateComparisonTree();
777 //_____________________________________________________________________________
778 void AliMonitorClient::OnEventButtonPressed()
780 // called when the event tool button was clicked
782 fSumButton->SetDown(kFALSE);
783 fRunButton->SetDown(kFALSE);
785 UpdateComparisonTree();
788 //_____________________________________________________________________________
789 void AliMonitorClient::OnSumButtonPressed()
791 // called when the sum tool button was clicked
793 fEventButton->SetDown(kFALSE);
794 fRunButton->SetDown(kFALSE);
796 UpdateComparisonTree();
799 //_____________________________________________________________________________
800 void AliMonitorClient::OnRunButtonPressed()
802 // called when the run tool button was clicked
804 fEventButton->SetDown(kFALSE);
805 fSumButton->SetDown(kFALSE);
807 UpdateComparisonTree();
810 //_____________________________________________________________________________
811 void AliMonitorClient::OnLoopButtonClicked()
813 // called when the loop tool button was clicked
815 // if loop is not running, start the loop timer and
816 // set the stop loop button picture
819 if (!GetBaseItem()) return;
821 fLoopTimer = new TTimer(fLoopInterval);
822 fLoopTimer->Connect("Timeout()", "AliMonitorClient", this,
824 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOffPicture);
825 fLoopTimer->TurnOn();
827 // if the loop is running, stop it
833 //_____________________________________________________________________________
834 void AliMonitorClient::OnPreviousButtonClicked()
836 // called when the previous tool button was clicked
839 if (!GetBaseItem()) return;
845 //_____________________________________________________________________________
846 void AliMonitorClient::OnNextButtonClicked()
848 // called when the next tool button was clicked
851 if (!GetBaseItem()) return;
857 //_____________________________________________________________________________
858 void AliMonitorClient::OnCopyButtonClicked()
860 // called when the copy tool button was clicked
862 fDrawCanvas->GetCanvas()->DrawClone();
865 //_____________________________________________________________________________
866 void AliMonitorClient::OnSaveButtonClicked()
868 // called when the save tool button was clicked
870 // display a file save dialog
871 static TGFileInfo fileInfo;
872 static const char* fileTypes[] = {"PostScript", "*.ps",
873 "Encapsulated PostScript", "*.eps",
875 "Gif files", "*.gif",
876 "Macro files", "*.C",
877 "ROOT files", "*.root",
880 fileInfo.fFileTypes = fileTypes;
881 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
882 if (!fileInfo.fFilename) return;
884 fDrawCanvas->GetCanvas()->SaveAs(fileInfo.fFilename);
887 //_____________________________________________________________________________
888 void AliMonitorClient::OnPrintButtonClicked()
890 // called when the print tool button was clicked
892 // save the canvas to a temporary postscript file
893 char fileName[L_tmpnam+4];
894 sprintf(fileName, "%s.ps", tmpnam(NULL));
895 fDrawCanvas->GetCanvas()->SaveAs(fileName);
897 // call the print command and delete the temporary file
899 sprintf(command, "%s %s", fPrintCommand.Data(), fileName);
900 gSystem->Exec(command);
901 gSystem->Unlink(fileName);
905 //_____________________________________________________________________________
906 void AliMonitorClient::OnTreeClicked(TGListTreeItem* item, Int_t)
908 // called when an item in the histogram tree is clicked
910 OnTreeReturnPressed(item);
913 //_____________________________________________________________________________
914 void AliMonitorClient::OnTreeReturnPressed(TGListTreeItem* item)
916 // called when return is pressed at an item in the histogram tree
925 //_____________________________________________________________________________
926 void AliMonitorClient::OnLoopTimer()
928 // called by the loop timer when a new histogram should be displayed
931 if (!GetBaseItem()) return;
937 //_____________________________________________________________________________
938 TFolder* AliMonitorClient::CreateTopFolder() const
940 // create a top folder for monitor histograms
942 return (new TFolder("Monitor", "monitor histograms"));
945 //_____________________________________________________________________________
946 AliMonitorHisto* AliMonitorClient::GetHisto(const char* folderName,
947 const char* histoName)
949 // find the monitor histogram with the given name in the given folder
951 TGListTreeItem* folderItem = fTree->FindChildByName(fAllItem, folderName);
953 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
954 if (histoItem) return (AliMonitorHisto*) histoItem->GetUserData();
959 //_____________________________________________________________________________
960 TGListTreeItem* AliMonitorClient::GetItem(TGListTreeItem* base,
961 const char* folderName,
962 const char* histoName,
965 // find the tree item with given name in the given folder
966 // if create is kTRUE it is created if it is not there
968 // get or create the folder
969 TGListTreeItem* folderItem = fTree->FindChildByName(base, folderName);
971 if (!create) return NULL;
972 folderItem = fTree->AddItem(base, folderName);
975 // get or create the histo
976 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
978 if (!create) return NULL;
979 histoItem = fTree->AddItem(folderItem, histoName,
980 fClient->GetPicture("h1_t.xpm"),
981 fClient->GetPicture("h1_t.xpm"));
987 //_____________________________________________________________________________
988 Bool_t AliMonitorClient::ConnectToServer()
990 // display the dialog for the server name or ip and try to connect to it
992 TString serverName(fServerName);
995 // ask for the server name or ip
996 new AliMonitorStringDlg(serverName, this, "Connection to monitor process",
997 "monitor server name or ip:");
998 if (serverName.IsNull()) return kFALSE;
1000 // connect to the server
1001 fSocket = new TSocket(serverName, AliMonitorProcess::GetPort());
1002 if (!fSocket || !fSocket->IsValid() || (fSocket->Send("client") <= 0)) {
1003 if (fSocket) delete fSocket;
1006 new TGMsgBox(gClient->GetRoot(), this, "Connect",
1007 "connection to monitor server failed",
1008 kMBIconExclamation, kMBOk, &result);
1010 } else { // set up a handler for notifying when new data is there
1011 fServerName = serverName;
1012 fSocketHandler = new TFileHandler(fSocket->GetDescriptor(),
1013 TFileHandler::kRead);
1014 fSocketHandler->Connect("Notified()", "AliMonitorClient", this,
1016 fSocketHandler->Add();
1017 TInetAddress adr = fSocket->GetInetAddress();
1018 AliInfo(Form("connected to server: %s (%s), port %d",
1019 adr.GetHostName(), adr.GetHostAddress(), adr.GetPort()));
1020 fMenuFile->HideEntry(kMenuFileConnect);
1021 fMenuFile->HideEntry(kMenuFileOpen);
1022 fMenuFile->EnableEntry(kMenuFileDisconnect);
1027 // delete the old monitor histos
1028 if (fFolder) delete fFolder;
1029 fFolder = CreateTopFolder();
1033 //_____________________________________________________________________________
1034 void AliMonitorClient::DisconnectFromServer()
1036 // disconnect from the monitor server
1038 // are-you-really-sure-dialog
1040 new TGMsgBox(gClient->GetRoot(), this, "Disconnect",
1041 "Do you really want to disconnect from the monitor server?",
1042 kMBIconQuestion, kMBYes | kMBNo, &result);
1043 if (result == kMBNo) return;
1045 // disconnect from the server
1046 fSocketHandler->Remove();
1047 fSocket->Send("disconnect");
1051 fMenuFile->HideEntry(kMenuFileDisconnect);
1052 fMenuFile->EnableEntry(kMenuFileConnect);
1053 fMenuFile->EnableEntry(kMenuFileOpen);
1056 //_____________________________________________________________________________
1057 Bool_t AliMonitorClient::OpenFile()
1059 // open a file with monitor histograms
1061 // display a file open dialog
1062 static TGFileInfo fileInfo;
1063 static const char* fileTypes[] = {"ROOT files", "*.root",
1066 fileInfo.fFileTypes = fileTypes;
1067 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1068 if (!fileInfo.fFilename) return kFALSE;
1070 // open the root file
1071 TFile* file = TFile::Open(fileInfo.fFilename);
1072 if (!file || !file->IsOpen()) {
1074 new TGMsgBox(gClient->GetRoot(), this, "Open",
1075 "The file could not be opened.",
1076 kMBIconExclamation, kMBOk, &result);
1080 // get the folder with the monitor histograms
1081 TFolder* folder = (TFolder*) file->Get("Monitor");
1082 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1084 new TGMsgBox(gClient->GetRoot(), this, "Open",
1085 "The file does not contain monitor histograms.",
1086 kMBIconExclamation, kMBOk, &result);
1092 // replace the old folder with the new one
1096 if (fFolder) delete fFolder;
1102 //_____________________________________________________________________________
1103 void AliMonitorClient::ViewToolBar(Bool_t visible)
1105 // en- or disable the view of the tool bar
1108 ShowFrame(fToolBarSep);
1109 ShowFrame(fToolBar);
1110 fMenuView->CheckEntry(kMenuViewToolBar);
1112 HideFrame(fToolBarSep);
1113 HideFrame(fToolBar);
1114 fMenuView->UnCheckEntry(kMenuViewToolBar);
1118 //_____________________________________________________________________________
1119 void AliMonitorClient::ViewTree(Bool_t visible)
1121 // en- or disable the view of the tree
1124 fHorizontalFrame->ShowFrame(fTreeFrame);
1125 fHorizontalFrame->ShowFrame(fTreeSplitter);
1126 fMenuView->CheckEntry(kMenuViewTree);
1128 fHorizontalFrame->HideFrame(fTreeFrame);
1129 fHorizontalFrame->HideFrame(fTreeSplitter);
1130 fMenuView->UnCheckEntry(kMenuViewTree);
1134 //_____________________________________________________________________________
1135 void AliMonitorClient::ViewDescription(Bool_t visible)
1137 // en- or disable the view of the histogram description
1140 fVerticalFrame->ShowFrame(fDescriptionFrame);
1141 fVerticalFrame->ShowFrame(fDescriptionSplitter);
1142 fMenuView->CheckEntry(kMenuViewDescription);
1144 fVerticalFrame->HideFrame(fDescriptionFrame);
1145 fVerticalFrame->HideFrame(fDescriptionSplitter);
1146 fMenuView->UnCheckEntry(kMenuViewDescription);
1150 //_____________________________________________________________________________
1151 void AliMonitorClient::ViewReference(Bool_t visible)
1153 // en- or disable the view of the reference histos
1156 AliMonitorHisto::SetDrawRef(kTRUE);
1157 fMenuView->CheckEntry(kMenuViewReference);
1159 AliMonitorHisto::SetDrawRef(kFALSE);
1160 fMenuView->UnCheckEntry(kMenuViewReference);
1164 //_____________________________________________________________________________
1165 void AliMonitorClient::ViewStatistics(Bool_t visible)
1167 // en- or disable the view of the statistics box
1170 gStyle->SetOptStat(1110);
1171 fMenuView->CheckEntry(kMenuViewStatistics);
1173 gStyle->SetOptStat(0);
1174 fMenuView->UnCheckEntry(kMenuViewStatistics);
1179 //_____________________________________________________________________________
1180 Bool_t AliMonitorClient::AddFavorite()
1182 // add the current histogram or folder to the list of favorites
1184 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1186 // get the folder item
1187 TGListTreeItem* folderItem = fCurrentItem->GetParent();
1188 if (fCurrentItem->GetFirstChild()) folderItem = fCurrentItem;
1190 Bool_t result = kFALSE;
1193 if (fCurrentItem->GetFirstChild()) {
1194 TGListTreeItem* histoItem = fCurrentItem->GetFirstChild();
1196 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1197 histoItem->GetText(), kFALSE)) result = kTRUE;
1198 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1199 histoItem->GetText(), kTRUE);
1200 item->SetUserData(histoItem->GetUserData());
1201 histoItem = histoItem->GetNextSibling();
1206 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1207 fCurrentItem->GetText(), kFALSE)) result = kTRUE;
1208 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1209 fCurrentItem->GetText(), kTRUE);
1210 item->SetUserData(fCurrentItem->GetUserData());
1213 if (result) gClient->NeedRedraw(fTree);
1217 //_____________________________________________________________________________
1218 Bool_t AliMonitorClient::DeleteFavorite()
1220 // delete the current histogram or folder from the list of favorites
1222 // check that the current item is a favorites histo or folder
1223 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1224 TGListTreeItem* base = fCurrentItem;
1225 while (base->GetParent()) base = base->GetParent();
1226 if (base != fFavoritesItem) return kFALSE;
1229 TGListTreeItem* parent = fCurrentItem->GetParent();
1230 fTree->DeleteItem(fCurrentItem);
1231 fCurrentItem = NULL;
1233 // delete the parent folder if it is empty now
1234 if (parent->GetParent() != NULL) {
1235 if (!parent->GetFirstChild()) fTree->DeleteItem(parent);
1238 gClient->NeedRedraw(fTree);
1242 //_____________________________________________________________________________
1243 Bool_t AliMonitorClient::LoadFavorites(Bool_t dialog)
1245 // load the list of favorites from a file
1247 // display a file open dialog
1248 TGFileInfo fileInfo;
1249 static const char* fileTypes[] = {"Favorites files", "*.fav",
1252 fileInfo.fFileTypes = fileTypes;
1253 fileInfo.fIniDir = StrDup(".");
1254 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1256 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1257 if (!fileInfo.fFilename) return kFALSE;
1260 // open the text file
1261 FILE* file = fopen(fileInfo.fFilename, "rt");
1264 new TGMsgBox(gClient->GetRoot(), this, "Load Favorites",
1265 "The file could not be opened.",
1266 kMBIconExclamation, kMBOk, &result);
1270 // delete the old favorites
1271 TGListTreeItem* favFolderItem = fFavoritesItem->GetFirstChild();
1272 while (favFolderItem) {
1273 TGListTreeItem* deleteItem = favFolderItem;
1274 favFolderItem = favFolderItem->GetNextSibling();
1275 fTree->DeleteItem(deleteItem);
1278 // scan the text file and add the favorites histos
1280 while (!feof(file)) {
1281 if (fgets(buffer, 255, file) == NULL) break;
1282 char* folder = strtok(buffer, "/");
1283 char* item = strtok(NULL, "\n");
1284 if (item[strlen(item)-1] == '\n') item[strlen(item)-1] = 0;
1285 if (!folder || !item) continue;
1287 AliMonitorHisto* histo = GetHisto(folder, item);
1288 TGListTreeItem* histoItem = GetItem(fFavoritesItem, folder, item, kTRUE);
1289 histoItem->SetUserData(histo);
1296 //_____________________________________________________________________________
1297 Bool_t AliMonitorClient::SaveFavorites()
1299 // save the list of favorites in a file with the name fFavoritesFileName
1301 // if no file name is given use a default one
1302 if (fFavoritesFileName.IsNull()) {
1303 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1304 "AliMonitorClient.fav");
1305 fFavoritesFileName = fileName;
1309 // open the text file
1310 FILE* file = fopen(fFavoritesFileName.Data(), "wt");
1313 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1314 "The file could not be opened.",
1315 kMBIconExclamation, kMBOk, &result);
1319 // loop over folders
1320 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1321 while (folderItem) {
1324 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1327 // write the favorites
1328 if (fprintf(file, "%s/%s\n", folderItem->GetText(),
1329 histoItem->GetText()) <= 0) {
1331 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1332 "An error occured while sving the favorites.",
1333 kMBIconExclamation, kMBOk, &result);
1337 histoItem = histoItem->GetNextSibling();
1340 folderItem = folderItem->GetNextSibling();
1344 AliInfo(Form("favorites saved to file %s", fFavoritesFileName.Data()));
1348 //_____________________________________________________________________________
1349 Bool_t AliMonitorClient::SaveFavoritesAs()
1351 // ask for a file name and save the favorites to this file
1353 // display a save file dialog
1354 TGFileInfo fileInfo;
1355 static const char* fileTypes[] = {"Favorites files", "*.fav",
1358 fileInfo.fFileTypes = fileTypes;
1359 fileInfo.fIniDir = StrDup(".");
1360 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1361 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1362 if (!fileInfo.fFilename) return kFALSE;
1364 // save the favorites
1365 fFavoritesFileName = fileInfo.fFilename;
1366 return SaveFavorites();
1370 //_____________________________________________________________________________
1371 Bool_t AliMonitorClient::LoadReference(Bool_t dialog)
1373 // load reference histograms from a file
1375 // display a file open dialog
1376 TGFileInfo fileInfo;
1377 static const char* fileTypes[] = {"ROOT files", "*.root",
1380 fileInfo.fFileTypes = fileTypes;
1381 fileInfo.fIniDir = StrDup(".");
1382 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1384 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1385 if (!fileInfo.fFilename) return kFALSE;
1388 // open the root file
1389 TFile* file = TFile::Open(fileInfo.fFilename);
1390 if (!file || !file->IsOpen()) {
1392 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1393 "The file could not be opened.",
1394 kMBIconExclamation, kMBOk, &result);
1398 // get the folder with the monitor histograms
1399 TFolder* folder = (TFolder*) file->Get("Monitor");
1400 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1402 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1403 "The file does not contain monitor histograms.",
1404 kMBIconExclamation, kMBOk, &result);
1410 // replace the old reference folder with the new one
1411 fReferenceFileName = fileInfo.fFilename;
1415 if (fReference) delete fReference;
1416 fReference = folder;
1420 //_____________________________________________________________________________
1421 void AliMonitorClient::SetReference()
1423 // set the reference histograms for all monitor histograms
1426 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1427 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1428 TFolder* refFolder = (TFolder*) fReference->FindObject(folder->GetName());
1429 if (!refFolder) continue;
1432 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1433 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1434 AliMonitorHisto* refHisto =
1435 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1436 if (!refHisto) continue;
1437 histo->SetReference(refHisto);
1445 //_____________________________________________________________________________
1446 Bool_t AliMonitorClient::TakeCurrentReference()
1448 // take the current monitor histogram or folder as reference
1450 // check that a histo or folder is selected
1451 if (!fCurrentItem) return kFALSE;
1452 AliMonitorHisto* histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
1453 if (!histo && !fCurrentItem->GetFirstChild()) return kFALSE;
1458 sprintf(message, "Do you want to take the current histogram %s/%s "
1459 "as reference histogram?", fCurrentItem->GetParent()->GetText(),
1462 sprintf(message, "Do you want to take all current histogram of the "
1463 "folder %s as reference histogram?", fCurrentItem->GetText());
1466 new TGMsgBox(gClient->GetRoot(), this, "Take Current as Reference",
1467 message, kMBIconQuestion, kMBYes | kMBNo, &result);
1468 if (result != kMBYes) return kFALSE;
1471 if (histo) { // ... a histo
1472 TakeReferenceHisto(fCurrentItem->GetParent()->GetText(), histo);
1473 } else if (fCurrentItem->GetParent()) { // ... a folder
1474 TakeReferenceFolder(fCurrentItem);
1475 } else { // ... a top folder
1476 TGListTreeItem* folderItem = fCurrentItem->GetFirstChild();
1477 while (folderItem) {
1478 TakeReferenceFolder(folderItem);
1479 folderItem = folderItem->GetNextSibling();
1485 //_____________________________________________________________________________
1486 void AliMonitorClient::TakeReferenceHisto(const char* folderName,
1487 AliMonitorHisto* histo)
1489 // take the given monitor histogram as reference histogram
1491 // get or create the reference folder
1492 TFolder* refFolder = (TFolder*) fReference->FindObject(folderName);
1493 if (!refFolder) refFolder = fReference->AddFolder(folderName, folderName);
1495 // delete the old reference histo
1496 AliMonitorHisto* refHisto =
1497 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1499 refFolder->Remove(refHisto);
1503 // add the new one and use it as reference
1504 refFolder->Add(new AliMonitorHisto(*histo));
1505 histo->SetReference(histo);
1508 //_____________________________________________________________________________
1509 void AliMonitorClient::TakeReferenceFolder(TGListTreeItem* item)
1511 // take all monitor histogram in the given folder as reference histograms
1514 TGListTreeItem* histoItem = item->GetFirstChild();
1516 AliMonitorHisto* histo = (AliMonitorHisto*) histoItem->GetUserData();
1517 if (histo) TakeReferenceHisto(item->GetText(), histo);
1518 histoItem = histoItem->GetNextSibling();
1522 //_____________________________________________________________________________
1523 Bool_t AliMonitorClient::SaveReference()
1525 // save the reference histograms to the file with name fReferenceFileName
1527 // if no file name is given use a default one
1528 if (fFavoritesFileName.IsNull()) {
1529 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1530 "AliMonitorClientRef.root");
1531 fFavoritesFileName = fileName;
1535 // open the root file
1536 TFile* file = TFile::Open(fReferenceFileName, "RECREATE");
1537 if (!file || !file->IsOpen()) {
1539 new TGMsgBox(gClient->GetRoot(), this, "Save Reference",
1540 "The file could not be opened.",
1541 kMBIconExclamation, kMBOk, &result);
1542 if (file) delete file;
1546 // write the reference folder
1547 fReference->Write();
1550 AliInfo(Form("reference histograms saved to file %s",
1551 fReferenceFileName.Data()));
1555 //_____________________________________________________________________________
1556 Bool_t AliMonitorClient::SaveReferenceAs()
1558 // ask for a file name and save the reference histograms to this file
1560 // display a save file dialog
1561 TGFileInfo fileInfo;
1562 static const char* fileTypes[] = {"ROOT files", "*.root",
1565 fileInfo.fFileTypes = fileTypes;
1566 fileInfo.fIniDir = StrDup(".");
1567 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1568 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1569 if (!fileInfo.fFilename) return kFALSE;
1571 // save the references
1572 fReferenceFileName = fileInfo.fFilename;
1573 return SaveReference();
1577 //_____________________________________________________________________________
1578 void AliMonitorClient::StopLoop()
1580 // stop looping over histograms
1582 // stop the timer and reset the loop button picture
1584 fLoopTimer->TurnOff();
1587 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOnPicture);
1591 //_____________________________________________________________________________
1592 void AliMonitorClient::LoadSettings()
1594 // load setting from the file with the name fgSettingFileName and apply them
1596 // open the text file
1597 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1598 fgSettingsFileName);
1599 FILE* file = fopen(fileName, "rt");
1605 // scan the text file and apply the settings
1607 while (!feof(file)) {
1608 if (fgets(buffer, 255, file) == NULL) break;
1609 char* token = strtok(buffer, "=");
1610 char* value = strtok(NULL, "\n");
1611 if (!token || !value) continue;
1612 if (value[strlen(value)-1] == '\n') value[strlen(value)-1] = 0;
1614 if (strcmp(token, "ServerName") == 0) {
1615 fServerName = value;
1617 } else if (strcmp(token, "ViewToolBar") == 0) {
1618 ViewToolBar(strcmp(value, "0") != 0);
1619 } else if (strcmp(token, "ViewTree") == 0) {
1620 ViewTree(strcmp(value, "0") != 0);
1621 } else if (strcmp(token, "ViewDescription") == 0) {
1622 ViewDescription(strcmp(value, "0") != 0);
1623 } else if (strcmp(token, "ViewReference") == 0) {
1624 ViewReference(strcmp(value, "0") != 0);
1625 } else if (strcmp(token, "ViewStatistics") == 0) {
1626 ViewStatistics(strcmp(value, "0") != 0);
1628 } else if (strcmp(token, "FavoritesFileName") == 0) {
1629 fFavoritesFileName = value;
1630 LoadFavorites(kFALSE);
1631 } else if (strcmp(token, "FavoritesSaveOnExit") == 0) {
1632 if (strcmp(value, "0") != 0) {
1633 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
1635 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
1638 } else if (strcmp(token, "ReferenceFileName") == 0) {
1639 fReferenceFileName = value;
1640 LoadReference(kFALSE);
1641 } else if (strcmp(token, "ReferenceThreshold") == 0) {
1642 AliMonitorHisto::SetThreshold(atof(value));
1644 } else if (strcmp(token, "LoopInterval") == 0) {
1645 fLoopInterval = atoi(value);
1646 } else if (strcmp(token, "PrintCommand") == 0) {
1647 fPrintCommand = value;
1648 } else if (strcmp(token, "SettingsSaveOnExit") == 0) {
1649 if (strcmp(value, "0") != 0) {
1650 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
1652 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
1658 AliDebug(1, Form("settings from file %s applied", fileName));
1662 //_____________________________________________________________________________
1663 void AliMonitorClient::SaveSettings()
1665 // save setting to the file with the name fgSettingFileName
1667 // open the text file
1668 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1669 fgSettingsFileName);
1670 FILE* file = fopen(fileName, "wt");
1673 new TGMsgBox(gClient->GetRoot(), this, "Save Settings",
1674 "The file could not be opened.",
1675 kMBIconExclamation, kMBOk, &result);
1680 // write the settings
1681 fprintf(file, "ServerName=%s\n", fServerName.Data());
1683 fprintf(file, "ViewToolBar=%d\n",
1684 fMenuView->IsEntryChecked(kMenuViewToolBar));
1685 fprintf(file, "ViewTree=%d\n",
1686 fMenuView->IsEntryChecked(kMenuViewTree));
1687 fprintf(file, "ViewDescription=%d\n",
1688 fMenuView->IsEntryChecked(kMenuViewDescription));
1689 fprintf(file, "ViewReference=%d\n",
1690 fMenuView->IsEntryChecked(kMenuViewReference));
1691 fprintf(file, "ViewStatistics=%d\n",
1692 fMenuView->IsEntryChecked(kMenuViewStatistics));
1694 if (!fFavoritesFileName.IsNull()) {
1695 fprintf(file, "FavoritesFileName=%s\n", fFavoritesFileName.Data());
1697 fprintf(file, "FavoritesSaveOnExit=%d\n",
1698 fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit));
1700 if (!fReferenceFileName.IsNull()) {
1701 fprintf(file, "ReferenceFileName=%s\n", fReferenceFileName.Data());
1703 fprintf(file, "ReferenceThreshold=%.1f\n", AliMonitorHisto::GetThreshold());
1705 fprintf(file, "LoopInterval=%d\n", fLoopInterval);
1706 fprintf(file, "PrintCommand=%s\n", fPrintCommand.Data());
1707 fprintf(file, "SettingsSaveOnExit=%d\n",
1708 fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit));
1711 AliInfo(Form("settings saved to file %s", fileName));
1716 //_____________________________________________________________________________
1717 Bool_t AliMonitorClient::GetBaseItem()
1719 // get the base item for looping over histograms
1722 // the base item is a folder
1723 fBaseItem = fCurrentItem;
1724 // if the current item is a histo, its parent is the base folder
1725 if (fBaseItem->GetParent() && fBaseItem->GetParent()->GetParent()) {
1726 fBaseItem = fBaseItem->GetParent();
1729 } else { // if no item is selected the All item is the base item
1730 fBaseItem = fAllItem;
1731 fCurrentItem = fBaseItem->GetFirstChild();
1732 if (!fCurrentItem) return kFALSE;
1738 //_____________________________________________________________________________
1739 Bool_t AliMonitorClient::GoToNextItem()
1741 // go to the next histogram in the loop
1743 if (!fCurrentItem) return kFALSE;
1744 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1746 // remember the start item to avoid an endless loop
1747 TGListTreeItem* startItem = fCurrentItem;
1750 // folder -> first child
1751 if (fCurrentItem->GetFirstChild()) {
1752 fCurrentItem = fCurrentItem->GetFirstChild();
1754 // histo -> next histo
1755 } else if ((fCurrentItem != fBaseItem) &&
1756 (fCurrentItem->GetNextSibling())) {
1757 fCurrentItem = fCurrentItem->GetNextSibling();
1759 // last histo in folder -> next folder
1760 } else if ((fCurrentItem != fBaseItem) &&
1761 (fCurrentItem->GetParent() != fBaseItem) &&
1762 fCurrentItem->GetParent()->GetNextSibling()) {
1763 fCurrentItem = fCurrentItem->GetParent()->GetNextSibling();
1765 // last histo in last folder -> first folder
1767 fCurrentItem = fBaseItem->GetFirstChild();
1770 // abort if no next item found
1771 if (fCurrentItem == startItem) return kFALSE;
1773 // end loop if an item with a monitor histo was found
1774 } while (!fCurrentItem->GetUserData());
1780 //_____________________________________________________________________________
1781 Bool_t AliMonitorClient::GoToPreviousItem()
1783 // go to the previous histogram in the loop
1785 if (!fCurrentItem) return kFALSE;
1786 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1788 // remember the start item to avoid an endless loop
1789 TGListTreeItem* startItem = fCurrentItem;
1792 // folder -> last child
1793 if (fCurrentItem->GetFirstChild()) {
1794 fCurrentItem = fCurrentItem->GetFirstChild();
1795 while (fCurrentItem->GetNextSibling()) {
1796 fCurrentItem = fCurrentItem->GetNextSibling();
1799 // histo -> previous histo
1800 } else if ((fCurrentItem != fBaseItem) &&
1801 (fCurrentItem->GetPrevSibling())) {
1802 fCurrentItem = fCurrentItem->GetPrevSibling();
1804 // first histo in folder -> previous folder
1805 } else if ((fCurrentItem != fBaseItem) &&
1806 (fCurrentItem->GetParent() != fBaseItem) &&
1807 fCurrentItem->GetParent()->GetPrevSibling()) {
1808 fCurrentItem = fCurrentItem->GetParent()->GetPrevSibling();
1810 // first histo in first folder -> last folder
1812 fCurrentItem = fBaseItem->GetFirstChild();
1813 while (fCurrentItem->GetNextSibling()) {
1814 fCurrentItem = fCurrentItem->GetNextSibling();
1818 // abort if no next item found
1819 if (fCurrentItem == startItem) return kFALSE;
1821 // end loop if an item with a monitor histo was found
1822 } while (!fCurrentItem->GetUserData());
1828 //_____________________________________________________________________________
1829 void AliMonitorClient::UpdateItem(Bool_t highlight)
1831 // update the displayed tree for currently selected item
1833 if (highlight) { // highlight the selected item and open its parent folders
1834 TGListTreeItem* parent = fCurrentItem->GetParent();
1836 if (!parent->IsOpen()) fTree->OpenItem(parent);
1837 parent = parent->GetParent();
1839 fTree->HighlightItem(fCurrentItem);
1840 gClient->NeedRedraw(fTree);
1843 // update displayed histo
1844 UpdateDescription();
1847 // en- or disable the "Reference/Take Current" menu item
1848 TGListTreeItem* base = fCurrentItem;
1849 while (base->GetParent()) base = base->GetParent();
1850 if (base != fComparisonItem) {
1851 fMenuReference->EnableEntry(kMenuRefTakeCurrent);
1853 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
1856 // en- or disable the "Favorites/Add" and "Favorites/Delete" menu items
1857 if (fCurrentItem->GetParent()) {
1858 if (base == fFavoritesItem) {
1859 fMenuFavorites->DisableEntry(kMenuFavAdd);
1860 fMenuFavorites->EnableEntry(kMenuFavDelete);
1862 fMenuFavorites->EnableEntry(kMenuFavAdd);
1863 fMenuFavorites->DisableEntry(kMenuFavDelete);
1866 fMenuFavorites->DisableEntry(kMenuFavAdd);
1867 fMenuFavorites->DisableEntry(kMenuFavDelete);
1872 //_____________________________________________________________________________
1873 Bool_t AliMonitorClient::CheckForNewData()
1875 // check whether the monitor process server sent new data
1877 // disable the socket handler in this method
1878 if (!fSocket || !fSocket->IsValid()) return kFALSE;
1879 fSocketHandler->Remove();
1881 // receive a control message from the server
1882 char controlMessage[256];
1883 if (fSocket->Recv(controlMessage, 255) <= 0) {
1884 fSocketHandler->Add();
1888 // if it is new histogram data, send ok
1889 if ((strcmp(controlMessage, "histograms") != 0) ||
1890 (fSocket->Send("ok") <= 0)) {
1891 fSocketHandler->Add();
1895 // get the histogram data
1896 TMessage* message = NULL;
1897 if (fSocket->Recv(message) <= 0) {
1898 fSocketHandler->Add();
1902 // replace the old folder of monitor histos with the new one
1903 if (message->GetClass()->InheritsFrom(TFolder::Class())) {
1904 if (fFolder) delete fFolder;
1905 fFolder = (TFolder*) message->ReadObject(message->GetClass());
1907 fSocketHandler->Add();
1912 fSocketHandler->Add();
1916 //_____________________________________________________________________________
1917 void AliMonitorClient::ClearItems(TGListTreeItem* base) const
1919 // remove the references to the histograms from all subitems of the
1922 // loop over folders
1923 TGListTreeItem* folderItem = base->GetFirstChild();
1924 while (folderItem) {
1927 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1929 histoItem->SetUserData(NULL);
1930 histoItem = histoItem->GetNextSibling();
1933 folderItem = folderItem->GetNextSibling();
1937 //_____________________________________________________________________________
1938 void AliMonitorClient::CleanUpTree(TGListTreeItem* base)
1940 // remove items without monitor histograms and
1941 // folders without monitor histograms
1943 // loop over folders
1944 TGListTreeItem* folderItem = base->GetFirstChild();
1945 while (folderItem) {
1948 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1950 TGListTreeItem* deleteItem = NULL;
1951 if (!histoItem->GetUserData()) deleteItem = histoItem;
1952 histoItem = histoItem->GetNextSibling();
1953 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1954 if (deleteItem) fTree->DeleteItem(deleteItem);
1957 folderItem = folderItem->GetNextSibling();
1960 // loop over folders and remove empty folders
1961 folderItem = base->GetFirstChild();
1962 while (folderItem) {
1963 TGListTreeItem* deleteItem = NULL;
1964 if (!folderItem->GetFirstChild()) deleteItem = folderItem;
1965 folderItem = folderItem->GetNextSibling();
1966 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1967 if (deleteItem) fTree->DeleteItem(deleteItem);
1971 //_____________________________________________________________________________
1972 void AliMonitorClient::UpdateTree()
1974 // update the tree of monitor histograms
1976 // delete references to old monitor histograms
1977 ClearItems(fAllItem);
1980 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1981 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1984 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1985 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1987 // add new monitor histograms
1988 TGListTreeItem* histoItem = GetItem(fAllItem, folder->GetName(),
1989 histo->GetName(), kTRUE);
1990 histoItem->SetUserData(histo);
1997 // remove items and folders without monitor histograms
1998 CleanUpTree(fAllItem);
2000 gClient->NeedRedraw(fTree);
2003 //_____________________________________________________________________________
2004 void AliMonitorClient::UpdateFavoritesTree()
2006 // update the tree of favorite monitor histograms
2008 // loop over folders
2009 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
2010 while (folderItem) {
2013 TGListTreeItem* histoItem = folderItem->GetFirstChild();
2016 // set monitor histo
2017 histoItem->SetUserData(GetHisto(folderItem->GetText(),
2018 histoItem->GetText()));
2019 histoItem = histoItem->GetNextSibling();
2022 folderItem = folderItem->GetNextSibling();
2026 //_____________________________________________________________________________
2027 void AliMonitorClient::UpdateComparisonTree()
2029 // update the tree of monitor histograms with significant deviation
2030 // from the reference histograms
2032 if (!fFolder) return;
2034 // delete references to old monitor histograms
2035 ClearItems(fComparisonItem);
2037 // add monitor histograms where the comparison returns a deviation
2038 // loop over folders
2039 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
2040 while (TFolder* folder = (TFolder*) iFolder->Next()) {
2043 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
2044 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
2046 // compare the histo to its reference
2047 Bool_t comparison = kTRUE;
2048 if (fEventButton->IsDown()) {
2049 comparison = histo->CompareEvent(fEventNumber->GetIntNumber());
2050 } else if (fSumButton->IsDown()) {
2051 comparison = histo->CompareSum(fEventNumber->GetIntNumber());
2053 comparison = histo->CompareRun();
2056 // add it to the comparison tree in case of a bad comparison result
2058 TGListTreeItem* histoItem = GetItem(fComparisonItem, folder->GetName(),
2059 histo->GetName(), kTRUE);
2060 histoItem->SetUserData(histo);
2068 // remove items and folders without monitor histograms
2069 CleanUpTree(fComparisonItem);
2071 gClient->NeedRedraw(fTree);
2074 //_____________________________________________________________________________
2075 void AliMonitorClient::UpdateDescription()
2077 // update the description of the current monitor histogram
2079 fDescription->Clear();
2080 AliMonitorHisto* histo = NULL;
2081 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2082 if (histo) fDescription->LoadBuffer(histo->GetDescription().Data());
2084 gClient->NeedRedraw(fDescription);
2087 //_____________________________________________________________________________
2088 void AliMonitorClient::UpdateHisto()
2090 // update the current monitor histogram
2092 // clear the canvas if no histo is selected
2093 AliMonitorHisto* histo = NULL;
2094 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2096 fDrawCanvas->GetCanvas()->Clear();
2097 fDrawCanvas->GetCanvas()->Update();
2101 // draw the histo for a single event or summed over several events or a run
2102 fDrawCanvas->GetCanvas()->cd();
2103 if (fEventButton->IsDown()) {
2104 histo->DrawEvent(fEventNumber->GetIntNumber());
2105 } else if (fSumButton->IsDown()) {
2106 histo->DrawSum(fEventNumber->GetIntNumber());
2112 //_____________________________________________________________________________
2113 void AliMonitorClient::UpdateAll()
2115 // update the trees, the histogram and the description
2118 UpdateFavoritesTree();
2119 UpdateComparisonTree();
2120 UpdateDescription();