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 "AliMonitorClient.h"
28 #include "AliMonitorDialog.h"
29 #include "AliMonitorProcess.h"
31 #include <TGFileDialog.h>
35 #include <TApplication.h>
39 ClassImp(AliMonitorClient)
42 const char* AliMonitorClient::fgSettingsFileName = ".AliMonitorClient";
44 //_____________________________________________________________________________
45 class AliMonitorStringDlg : public AliMonitorDialog {
48 AliMonitorStringDlg(TString& string, TGFrame* main, const char* title,
50 virtual ~AliMonitorStringDlg();
52 virtual void OnOkClicked();
55 TGLayoutHints* fStringLayout;
56 TGLabel* fStringLabel;
57 TGTextEntry* fStringEntry;
63 //_____________________________________________________________________________
64 AliMonitorStringDlg::AliMonitorStringDlg(TString& string, TGFrame* main,
67 AliMonitorDialog(main, 300, 80), fString(string)
69 // create a dialog for connecting to a monitor process
71 fStringLayout = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2);
72 fStringLabel = new TGLabel(fFrame, label);
73 fFrame->AddFrame(fStringLabel, fStringLayout);
74 fStringEntry = new TGTextEntry(fFrame, string.Data());
75 fStringEntry->Resize(100, fStringEntry->GetDefaultHeight());
76 fFrame->AddFrame(fStringEntry, fStringLayout);
80 fMain->SetWindowName(title);
81 fMain->MapSubwindows();
83 gClient->WaitFor(fMain);
86 //_____________________________________________________________________________
87 AliMonitorStringDlg::~AliMonitorStringDlg()
96 //_____________________________________________________________________________
97 void AliMonitorStringDlg::OnOkClicked()
99 fString = fStringEntry->GetText();
104 //_____________________________________________________________________________
105 class AliMonitorNumberDlg : public AliMonitorDialog {
108 AliMonitorNumberDlg(Float_t& value, TGFrame* main, const char* title,
109 const char* label, Float_t min);
110 virtual ~AliMonitorNumberDlg();
112 virtual void OnOkClicked();
115 TGLayoutHints* fNumberLayout;
116 TGLabel* fNumberLabel;
117 TGNumberEntry* fNumberEntry;
123 //_____________________________________________________________________________
124 AliMonitorNumberDlg::AliMonitorNumberDlg(Float_t& value, TGFrame* main,
125 const char* title, const char* label,
127 AliMonitorDialog(main, 250, 80), fNumber(value)
129 // create a dialog for getting a number
131 fNumberLayout = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2);
132 fNumberLabel = new TGLabel(fFrame, label);
133 fFrame->AddFrame(fNumberLabel, fNumberLayout);
134 fNumberEntry = new TGNumberEntry(fFrame, value, 4, -1,
135 TGNumberFormat::kNESRealOne);
136 fNumberEntry->SetLimits(TGNumberFormat::kNELLimitMin, min, 0);
137 fFrame->AddFrame(fNumberEntry, fNumberLayout);
141 fMain->SetWindowName(title);
142 fMain->MapSubwindows();
144 gClient->WaitFor(fMain);
147 //_____________________________________________________________________________
148 AliMonitorNumberDlg::~AliMonitorNumberDlg()
153 delete fNumberLayout;
157 //_____________________________________________________________________________
158 void AliMonitorNumberDlg::OnOkClicked()
160 fNumber = fNumberEntry->GetNumber();
165 // constants for menu entries
166 enum {kMenuFileConnect, kMenuFileDisconnect, kMenuFileOpen, kMenuFileExit,
167 kMenuViewToolBar, kMenuViewTree, kMenuViewDescription,
168 kMenuViewReference, kMenuViewStatistics,
169 kMenuFavAdd, kMenuFavDelete,
170 kMenuFavLoad, kMenuFavSave, kMenuFavSaveAs, kMenuFavSaveOnExit,
171 kMenuRefLoad, kMenuRefThreshold,
172 kMenuRefTakeCurrent, kMenuRefSave, kMenuRefSaveAs,
173 kMenuOptLoop, kMenuOptPrint,
174 kMenuOptSave, kMenuOptSaveOnExit,
175 kMenuHelpDoc, kMenuHelpAbout
178 //_____________________________________________________________________________
179 AliMonitorClient::AliMonitorClient():
180 TGMainFrame(gClient->GetRoot(), 500, 300)
182 // initialize the monitoring client window
185 fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX,
187 fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
188 fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
191 fMenuFile = new TGPopupMenu(gClient->GetRoot());
192 fMenuFile->AddEntry("&Connect...", kMenuFileConnect);
193 fMenuFile->AddEntry("&Disconnect...", kMenuFileDisconnect);
194 fMenuFile->HideEntry(kMenuFileDisconnect);
195 fMenuFile->AddEntry("&Open...", kMenuFileOpen);
196 fMenuFile->AddSeparator();
197 fMenuFile->AddEntry("E&xit", kMenuFileExit);
198 fMenuFile->Connect("Activated(Int_t)", "AliMonitorClient", this,
199 "OnMenuActivated(Int_t)");
202 fMenuView = new TGPopupMenu(gClient->GetRoot());
203 fMenuView->AddEntry("Tool&bar", kMenuViewToolBar);
204 fMenuView->CheckEntry(kMenuViewToolBar);
205 fMenuView->AddEntry("&Tree", kMenuViewTree);
206 fMenuView->CheckEntry(kMenuViewTree);
207 fMenuView->AddEntry("&Description", kMenuViewDescription);
208 fMenuView->CheckEntry(kMenuViewDescription);
209 fMenuView->AddSeparator();
210 fMenuView->AddEntry("&Reference", kMenuViewReference);
211 fMenuView->CheckEntry(kMenuViewReference);
212 AliMonitorHisto::SetDrawRef(kTRUE);
213 fMenuView->AddEntry("&Statistics", kMenuViewStatistics);
214 fMenuView->CheckEntry(kMenuViewStatistics);
215 gStyle->SetOptStat(1110);
216 fMenuView->Connect("Activated(Int_t)", "AliMonitorClient", this,
217 "OnMenuActivated(Int_t)");
220 fMenuFavorites = new TGPopupMenu(gClient->GetRoot());
221 fMenuFavorites->AddEntry("&Add", kMenuFavAdd);
222 fMenuFavorites->DisableEntry(kMenuFavAdd);
223 fMenuFavorites->AddEntry("&Delete", kMenuFavDelete);
224 fMenuFavorites->DisableEntry(kMenuFavDelete);
225 fMenuFavorites->AddSeparator();
226 fMenuFavorites->AddEntry("&Load...", kMenuFavLoad);
227 fMenuFavorites->AddEntry("&Save", kMenuFavSave);
228 fMenuFavorites->DisableEntry(kMenuFavSave);
229 fMenuFavorites->AddEntry("&Save As...", kMenuFavSaveAs);
230 fMenuFavorites->DisableEntry(kMenuFavSaveAs);
231 fMenuFavorites->AddEntry("Save On &Exit", kMenuFavSaveOnExit);
232 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
233 fMenuFavorites->Connect("Activated(Int_t)", "AliMonitorClient", this,
234 "OnMenuActivated(Int_t)");
237 fMenuReference = new TGPopupMenu(gClient->GetRoot());
238 fMenuReference->AddEntry("&Load...", kMenuRefLoad);
239 fMenuReference->AddEntry("&Threshold...", kMenuRefThreshold);
240 fMenuReference->AddSeparator();
241 fMenuReference->AddEntry("Take &Current", kMenuRefTakeCurrent);
242 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
243 fMenuReference->AddEntry("&Save", kMenuRefSave);
244 fMenuReference->DisableEntry(kMenuRefSave);
245 fMenuReference->AddEntry("Save &As...", kMenuRefSaveAs);
246 fMenuReference->DisableEntry(kMenuRefSaveAs);
247 fMenuReference->Connect("Activated(Int_t)", "AliMonitorClient", this,
248 "OnMenuActivated(Int_t)");
251 fMenuOptions = new TGPopupMenu(gClient->GetRoot());
252 fMenuOptions->AddEntry("&Loop Interval...", kMenuOptLoop);
253 fMenuOptions->AddEntry("&Print Command...", kMenuOptPrint);
254 fMenuOptions->AddSeparator();
255 fMenuOptions->AddEntry("&Save Settings", kMenuOptSave);
256 fMenuOptions->AddEntry("Save Settings on &Exit", kMenuOptSaveOnExit);
257 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
258 fMenuOptions->Connect("Activated(Int_t)", "AliMonitorClient", this,
259 "OnMenuActivated(Int_t)");
262 fMenuHelp = new TGPopupMenu(gClient->GetRoot());
263 fMenuHelp->AddEntry("&Documentation...", kMenuHelpDoc);
264 fMenuHelp->AddEntry("A&bout...", kMenuHelpAbout);
265 fMenuHelp->Connect("Activated(Int_t)", "AliMonitorClient", this,
266 "OnMenuActivated(Int_t)");
269 fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
270 fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
271 fMenuBar->AddPopup("&View", fMenuView, fMenuBarItemLayout);
272 fMenuBar->AddPopup("F&avorites", fMenuFavorites, fMenuBarItemLayout);
273 fMenuBar->AddPopup("&Reference", fMenuReference, fMenuBarItemLayout);
274 fMenuBar->AddPopup("&Options", fMenuOptions, fMenuBarItemLayout);
275 fMenuBar->AddPopup("&Help", fMenuHelp, fMenuBarHelpLayout);
277 AddFrame(fMenuBar, fMenuBarLayout);
281 fToolBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 2, 2);
282 fToolBarSep = new TGHorizontal3DLine(this);
283 AddFrame(fToolBarSep, fToolBarLayout);
284 fToolBar = new TGToolBar(this, 60, 20, kHorizontalFrame);
285 AddFrame(fToolBar, fToolBarLayout);
287 // event number field
288 fEventNumberLayout = new TGLayoutHints(kLHintsCenterY | kLHintsLeft,
290 fEventNumber = new TGNumberEntry(fToolBar, 1, 4, 10,
291 TGNumberFormat::kNESInteger);
292 fEventNumber->SetLimits(TGNumberFormat::kNELLimitMin, 1, 0);
293 fToolBar->AddFrame(fEventNumber, fEventNumberLayout);
294 fEventNumber->GetNumberEntry()->Connect("ReturnPressed()",
295 "AliMonitorClient", this,
296 "OnEventNumberChanged()");
297 fEventNumber->GetButtonUp()->Connect("Clicked()",
298 "AliMonitorClient", this,
299 "OnEventNumberChanged()");
300 fEventNumber->GetButtonDown()->Connect("Clicked()",
301 "AliMonitorClient", this,
302 "OnEventNumberChanged()");
305 ToolBarData_t eventButton = {"h1_s.xpm", "draw event histogram",
307 fToolBar->AddButton(this, &eventButton, 5);
308 fEventButton = eventButton.fButton;
309 fEventButton->Connect("Pressed()", "AliMonitorClient", this,
310 "OnEventButtonPressed()");
313 ToolBarData_t sumButton = {"h2_s.xpm", "draw sum histogram",
315 fToolBar->AddButton(this, &sumButton, 5);
316 fSumButton = sumButton.fButton;
317 fSumButton->Connect("Pressed()", "AliMonitorClient", this,
318 "OnSumButtonPressed()");
321 ToolBarData_t runButton = {"h3_s.xpm", "draw run histogram",
323 fToolBar->AddButton(this, &runButton, 5);
324 fRunButton = runButton.fButton;
325 fRunButton->SetDown(kTRUE);
326 fRunButton->Connect("Pressed()", "AliMonitorClient", this,
327 "OnRunButtonPressed()");
331 sprintf(fileName, "%s/MONITOR/loop_on.xpm", gSystem->Getenv("ALICE_ROOT"));
332 ToolBarData_t loopButton = {fileName, "loop over histograms",
334 fToolBar->AddButton(this, &loopButton, 25);
335 fLoopButton = loopButton.fButton;
336 fLoopButton->Connect("Clicked()", "AliMonitorClient", this,
337 "OnLoopButtonClicked()");
338 fLoopOnPicture = gClient->GetPicture(fileName);
339 sprintf(fileName, "%s/MONITOR/loop_off2.xpm", gSystem->Getenv("ALICE_ROOT"));
340 fLoopOffPicture = gClient->GetPicture(fileName);
343 sprintf(fileName, "%s/MONITOR/previous_s.xpm",
344 gSystem->Getenv("ALICE_ROOT"));
345 ToolBarData_t previousButton = {fileName, "go to previous histogram",
347 fToolBar->AddButton(this, &previousButton, 5);
348 fPreviousButton = previousButton.fButton;
349 fPreviousButton->Connect("Clicked()", "AliMonitorClient", this,
350 "OnPreviousButtonClicked()");
353 sprintf(fileName, "%s/MONITOR/next_s.xpm", gSystem->Getenv("ALICE_ROOT"));
354 ToolBarData_t nextButton = {fileName, "go to next histogram",
356 fToolBar->AddButton(this, &nextButton, 5);
357 fNextButton = nextButton.fButton;
358 fNextButton->Connect("Clicked()", "AliMonitorClient", this,
359 "OnNextButtonClicked()");
362 sprintf(fileName, "%s/MONITOR/copy_s.xpm", gSystem->Getenv("ALICE_ROOT"));
363 ToolBarData_t copyButton = {fileName,
364 "copy the current histogram to a new canvas",
366 fToolBar->AddButton(this, ©Button, 25);
367 fCopyButton = copyButton.fButton;
368 fCopyButton->Connect("Clicked()", "AliMonitorClient", this,
369 "OnCopyButtonClicked()");
372 sprintf(fileName, "%s/MONITOR/save_s.xpm", gSystem->Getenv("ALICE_ROOT"));
373 ToolBarData_t saveButton = {fileName, "save the current histogram",
375 fToolBar->AddButton(this, &saveButton, 5);
376 fSaveButton = saveButton.fButton;
377 fSaveButton->Connect("Clicked()", "AliMonitorClient", this,
378 "OnSaveButtonClicked()");
381 ToolBarData_t printButton = {"printer_s.xpm", "print the current histogram",
383 fToolBar->AddButton(this, &printButton, 5);
384 fPrintButton = printButton.fButton;
385 fPrintButton->Connect("Clicked()", "AliMonitorClient", this,
386 "OnPrintButtonClicked()");
389 fBottomLayout = new TGLayoutHints(kLHintsExpandX | kLHintsBottom);
390 fLeftLayout = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
391 fExpandLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
393 fVerticalFrame = new TGVerticalFrame(this, 10, 10);
394 AddFrame(fVerticalFrame, fExpandLayout);
396 fHorizontalFrame = new TGHorizontalFrame(fVerticalFrame, 10, 10);
397 fVerticalFrame->AddFrame(fHorizontalFrame, fExpandLayout);
400 fTreeFrame = new TGCompositeFrame(fHorizontalFrame, 10, 10,
401 kSunkenFrame | kFixedWidth);
402 fHorizontalFrame->AddFrame(fTreeFrame, fLeftLayout);
403 fTreeCanvas = new TGCanvas(fTreeFrame, 10, 10);
404 fTreeFrame->AddFrame(fTreeCanvas, fExpandLayout);
405 fTree = new TGListTree(fTreeCanvas, kHorizontalFrame);
406 fTreeCanvas->AddFrame(fTree, fExpandLayout);
407 fTree->Connect("Clicked(TGListTreeItem*,Int_t)", "AliMonitorClient",
408 this, "OnTreeClicked(TGListTreeItem*,Int_t)");
409 fTree->Connect("ReturnPressed(TGListTreeItem*)", "AliMonitorClient",
410 this, "OnTreeReturnPressed(TGListTreeItem*)");
413 fAllItem = fTree->AddItem(NULL, "All");
414 fFavoritesItem = fTree->AddItem(NULL, "Favorites");
415 fComparisonItem = fTree->AddItem(NULL, "Comparison");
416 fHistoPicture = fClient->GetPicture("h1_t.xpm");
417 fTreeFrame->Resize(100, fTreeFrame->GetDefaultHeight());
419 // tree / histogram splitter
420 fTreeSplitter = new TGVSplitter(fHorizontalFrame, 4);
421 fTreeSplitter->SetFrame(fTreeFrame, kTRUE);
422 fHorizontalFrame->AddFrame(fTreeSplitter, fLeftLayout);
425 fDrawFrame = new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame);
426 fHorizontalFrame->AddFrame(fDrawFrame, fExpandLayout);
427 fDrawCanvas = new TRootEmbeddedCanvas("current monitor histogram",
429 fDrawFrame->AddFrame(fDrawCanvas, fExpandLayout);
432 fDescriptionFrame = new TGCompositeFrame(fVerticalFrame, 10, 60,
433 kSunkenFrame | kFixedHeight);
434 fVerticalFrame->AddFrame(fDescriptionFrame, fBottomLayout);
435 fDescription = new TGTextView(fDescriptionFrame, 10, 60, "");
436 fDescriptionFrame->AddFrame(fDescription, fExpandLayout);
438 // histogram / description splitter
439 fDescriptionSplitter = new TGHSplitter(fVerticalFrame, 4, 4);
440 fVerticalFrame->AddFrame(fDescriptionSplitter, fBottomLayout);
441 fDescriptionSplitter->SetFrame(fDescriptionFrame, kFALSE);
444 Connect("CloseWindow()", "AliMonitorClient", this, "CloseWindow()");
445 SetWindowName("Monitor Client");
446 SetWMSize(GetWidth(), GetHeight());
448 SetWMPosition(100, 100);
454 // default data members
455 fServerName = "localhost";
457 fSocketHandler = NULL;
459 fFolder = CreateTopFolder();
464 fLoopInterval = 1000;
466 fFavoritesFileName = "";
468 fReferenceFileName = "";
469 fReference = CreateTopFolder();
470 AliMonitorHisto::SetThreshold(5.0);
472 fPrintCommand = "gv";
474 // load saved settings
478 //_____________________________________________________________________________
479 AliMonitorClient::~AliMonitorClient()
483 delete fMenuBarLayout;
484 delete fMenuBarItemLayout;
485 delete fMenuBarHelpLayout;
488 delete fMenuFavorites;
489 delete fMenuReference;
494 delete fEventNumberLayout;
496 delete fToolBarLayout;
500 delete fBottomLayout;
502 delete fExpandLayout;
507 delete fTreeSplitter;
512 delete fDescriptionSplitter;
514 delete fDescriptionFrame;
516 delete fVerticalFrame;
517 delete fHorizontalFrame;
522 delete fSocketHandler;
525 if (fFolder) delete fFolder;
528 fLoopTimer->TurnOff();
532 if (fReference) delete fReference;
536 //_____________________________________________________________________________
537 void AliMonitorClient::CloseWindow()
539 // terminate the application when the window is closed
541 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
544 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
547 gApplication->Terminate(0);
551 //_____________________________________________________________________________
552 void AliMonitorClient::OnNewData()
554 // called when data has arrived from the monitor server
556 if (CheckForNewData()) UpdateAll();
560 //_____________________________________________________________________________
561 void AliMonitorClient::OnMenuActivated(Int_t id)
563 // called when a menu item was selected
567 case kMenuFileConnect: {
568 if (ConnectToServer()) UpdateAll();
572 case kMenuFileDisconnect: {
573 DisconnectFromServer();
577 case kMenuFileOpen: {
578 if (OpenFile()) UpdateAll();
582 case kMenuFileExit: {
587 case kMenuViewToolBar: {
588 ViewToolBar(!fMenuView->IsEntryChecked(kMenuViewToolBar));
592 case kMenuViewTree: {
593 ViewTree(!fMenuView->IsEntryChecked(kMenuViewTree));
597 case kMenuViewDescription: {
598 ViewDescription(!fMenuView->IsEntryChecked(kMenuViewDescription));
602 case kMenuViewReference: {
603 ViewReference(!fMenuView->IsEntryChecked(kMenuViewReference));
608 case kMenuViewStatistics: {
609 ViewStatistics(!fMenuView->IsEntryChecked(kMenuViewStatistics));
616 fMenuFavorites->EnableEntry(kMenuFavSave);
617 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
622 case kMenuFavDelete: {
623 if (DeleteFavorite()) {
626 fMenuFavorites->DisableEntry(kMenuFavDelete);
627 fMenuFavorites->EnableEntry(kMenuFavSave);
628 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
634 if (LoadFavorites()) {
637 fMenuFavorites->DisableEntry(kMenuFavSave);
638 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
644 if (SaveFavorites()) {
645 fMenuFavorites->DisableEntry(kMenuFavSave);
650 case kMenuFavSaveAs: {
651 if (SaveFavoritesAs()) {
652 fMenuFavorites->DisableEntry(kMenuFavSave);
657 case kMenuFavSaveOnExit: {
658 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
659 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
661 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
667 if (LoadReference()) {
670 UpdateComparisonTree();
671 fMenuReference->EnableEntry(kMenuRefSaveAs);
676 case kMenuRefThreshold: {
677 Float_t threshold = AliMonitorHisto::GetThreshold();
678 new AliMonitorNumberDlg(threshold, this,
679 "Comparison with Reference Histograms",
680 "threshold for comparison:", 0.);
681 if (threshold < 0) break;
683 AliMonitorHisto::SetThreshold(threshold);
685 UpdateComparisonTree();
689 case kMenuRefTakeCurrent: {
690 if (TakeCurrentReference()) {
692 UpdateComparisonTree();
693 fMenuReference->EnableEntry(kMenuRefSave);
694 fMenuReference->EnableEntry(kMenuRefSaveAs);
700 if (SaveReference()) {
701 fMenuReference->DisableEntry(kMenuRefSave);
706 case kMenuRefSaveAs: {
707 if (SaveReferenceAs()) {
708 fMenuReference->DisableEntry(kMenuRefSave);
714 Float_t interval = fLoopInterval * 0.001;
715 new AliMonitorNumberDlg(interval, this, "Loop Interval",
716 "loop time in seconds:", 0.1);
717 if (interval < 0) break;
719 fLoopInterval = Int_t(1000 * interval);
722 fLoopTimer->Start(fLoopInterval);
727 case kMenuOptPrint: {
728 TString printCommand(fPrintCommand);
729 new AliMonitorStringDlg(printCommand, this, "Print Command",
730 "shell command for printing:");
731 if (printCommand.IsNull()) break;
733 fPrintCommand = printCommand;
737 case kMenuOptSaveOnExit: {
738 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
739 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
741 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
751 case kMenuHelpAbout: {
753 new TGMsgBox(gClient->GetRoot(), this,
754 "About", "AliMonitorClient $Revision$",
755 kMBIconAsterisk, kMBOk, &result);
761 new TGMsgBox(gClient->GetRoot(), this,
762 "AliMonitorClient", "not yet implemented",
763 kMBIconExclamation, kMBOk, &result);
769 //_____________________________________________________________________________
770 void AliMonitorClient::OnEventNumberChanged()
772 // called when the event number in the tool button was changed
774 if (!fRunButton->IsDown()) {
776 UpdateComparisonTree();
780 //_____________________________________________________________________________
781 void AliMonitorClient::OnEventButtonPressed()
783 // called when the event tool button was clicked
785 fSumButton->SetDown(kFALSE);
786 fRunButton->SetDown(kFALSE);
788 UpdateComparisonTree();
791 //_____________________________________________________________________________
792 void AliMonitorClient::OnSumButtonPressed()
794 // called when the sum tool button was clicked
796 fEventButton->SetDown(kFALSE);
797 fRunButton->SetDown(kFALSE);
799 UpdateComparisonTree();
802 //_____________________________________________________________________________
803 void AliMonitorClient::OnRunButtonPressed()
805 // called when the run tool button was clicked
807 fEventButton->SetDown(kFALSE);
808 fSumButton->SetDown(kFALSE);
810 UpdateComparisonTree();
813 //_____________________________________________________________________________
814 void AliMonitorClient::OnLoopButtonClicked()
816 // called when the loop tool button was clicked
818 // if loop is not running, start the loop timer and
819 // set the stop loop button picture
822 if (!GetBaseItem()) return;
824 fLoopTimer = new TTimer(fLoopInterval);
825 fLoopTimer->Connect("Timeout()", "AliMonitorClient", this,
827 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOffPicture);
828 fLoopTimer->TurnOn();
830 // if the loop is running, stop it
836 //_____________________________________________________________________________
837 void AliMonitorClient::OnPreviousButtonClicked()
839 // called when the previous tool button was clicked
842 if (!GetBaseItem()) return;
848 //_____________________________________________________________________________
849 void AliMonitorClient::OnNextButtonClicked()
851 // called when the next tool button was clicked
854 if (!GetBaseItem()) return;
860 //_____________________________________________________________________________
861 void AliMonitorClient::OnCopyButtonClicked()
863 // called when the copy tool button was clicked
865 fDrawCanvas->GetCanvas()->DrawClone();
868 //_____________________________________________________________________________
869 void AliMonitorClient::OnSaveButtonClicked()
871 // called when the save tool button was clicked
873 // display a file save dialog
874 static TGFileInfo fileInfo;
875 static const char* fileTypes[] = {"PostScript", "*.ps",
876 "Encapsulated PostScript", "*.eps",
878 "Gif files", "*.gif",
879 "Macro files", "*.C",
880 "ROOT files", "*.root",
883 fileInfo.fFileTypes = fileTypes;
884 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
885 if (!fileInfo.fFilename) return;
887 fDrawCanvas->GetCanvas()->SaveAs(fileInfo.fFilename);
890 //_____________________________________________________________________________
891 void AliMonitorClient::OnPrintButtonClicked()
893 // called when the print tool button was clicked
895 // save the canvas to a temporary postscript file
896 char fileName[L_tmpnam+4];
897 sprintf(fileName, "%s.ps", tmpnam(NULL));
898 fDrawCanvas->GetCanvas()->SaveAs(fileName);
900 // call the print command and delete the temporary file
902 sprintf(command, "%s %s", fPrintCommand.Data(), fileName);
903 gSystem->Exec(command);
904 gSystem->Unlink(fileName);
908 //_____________________________________________________________________________
909 void AliMonitorClient::OnTreeClicked(TGListTreeItem* item, Int_t)
911 // called when an item in the histogram tree is clicked
913 OnTreeReturnPressed(item);
916 //_____________________________________________________________________________
917 void AliMonitorClient::OnTreeReturnPressed(TGListTreeItem* item)
919 // called when return is pressed at an item in the histogram tree
928 //_____________________________________________________________________________
929 void AliMonitorClient::OnLoopTimer()
931 // called by the loop timer when a new histogram should be displayed
934 if (!GetBaseItem()) return;
940 //_____________________________________________________________________________
941 TFolder* AliMonitorClient::CreateTopFolder()
943 // create a top folder for monitor histograms
945 return (new TFolder("Monitor", "monitor histograms"));
948 //_____________________________________________________________________________
949 AliMonitorHisto* AliMonitorClient::GetHisto(const char* folderName,
950 const char* histoName)
952 // find the monitor histogram with the given name in the given folder
954 TGListTreeItem* folderItem = fTree->FindChildByName(fAllItem, folderName);
956 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
957 if (histoItem) return (AliMonitorHisto*) histoItem->GetUserData();
962 //_____________________________________________________________________________
963 TGListTreeItem* AliMonitorClient::GetItem(TGListTreeItem* base,
964 const char* folderName,
965 const char* histoName,
968 // find the tree item with given name in the given folder
969 // if create is kTRUE it is created if it is not there
971 // get or create the folder
972 TGListTreeItem* folderItem = fTree->FindChildByName(base, folderName);
974 if (!create) return NULL;
975 folderItem = fTree->AddItem(base, folderName);
978 // get or create the histo
979 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
981 if (!create) return NULL;
982 histoItem = fTree->AddItem(folderItem, histoName,
983 fClient->GetPicture("h1_t.xpm"),
984 fClient->GetPicture("h1_t.xpm"));
990 //_____________________________________________________________________________
991 Bool_t AliMonitorClient::ConnectToServer()
993 // display the dialog for the server name or ip and try to connect to it
995 TString serverName(fServerName);
998 // ask for the server name or ip
999 new AliMonitorStringDlg(serverName, this, "Connection to monitor process",
1000 "monitor server name or ip:");
1001 if (serverName.IsNull()) return kFALSE;
1003 // connect to the server
1004 fSocket = new TSocket(serverName, AliMonitorProcess::kgPort);
1005 if (!fSocket || !fSocket->IsValid() || (fSocket->Send("client") <= 0)) {
1006 if (fSocket) delete fSocket;
1009 new TGMsgBox(gClient->GetRoot(), this, "Connect",
1010 "connection to monitor server failed",
1011 kMBIconExclamation, kMBOk, &result);
1013 } else { // set up a handler for notifying when new data is there
1014 fServerName = serverName;
1015 fSocketHandler = new TFileHandler(fSocket->GetDescriptor(),
1016 TFileHandler::kRead);
1017 fSocketHandler->Connect("Notified()", "AliMonitorClient", this,
1019 fSocketHandler->Add();
1020 TInetAddress adr = fSocket->GetInetAddress();
1021 Info("ConnectToServer", "connected to server:\n %s (%s), port %d\n",
1022 adr.GetHostName(), adr.GetHostAddress(), adr.GetPort());
1023 fMenuFile->HideEntry(kMenuFileConnect);
1024 fMenuFile->HideEntry(kMenuFileOpen);
1025 fMenuFile->EnableEntry(kMenuFileDisconnect);
1030 // delete the old monitor histos
1031 if (fFolder) delete fFolder;
1032 fFolder = CreateTopFolder();
1036 //_____________________________________________________________________________
1037 void AliMonitorClient::DisconnectFromServer()
1039 // disconnect from the monitor server
1041 // are-you-really-sure-dialog
1043 new TGMsgBox(gClient->GetRoot(), this, "Disconnect",
1044 "Do you really want to disconnect from the monitor server?",
1045 kMBIconQuestion, kMBYes | kMBNo, &result);
1046 if (result == kMBNo) return;
1048 // disconnect from the server
1052 fMenuFile->HideEntry(kMenuFileDisconnect);
1053 fMenuFile->EnableEntry(kMenuFileConnect);
1054 fMenuFile->EnableEntry(kMenuFileOpen);
1057 //_____________________________________________________________________________
1058 Bool_t AliMonitorClient::OpenFile()
1060 // open a file with monitor histograms
1062 // display a file open dialog
1063 static TGFileInfo fileInfo;
1064 static const char* fileTypes[] = {"ROOT files", "*.root",
1067 fileInfo.fFileTypes = fileTypes;
1068 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1069 if (!fileInfo.fFilename) return kFALSE;
1071 // open the root file
1072 TFile* file = TFile::Open(fileInfo.fFilename);
1073 if (!file || !file->IsOpen()) {
1075 new TGMsgBox(gClient->GetRoot(), this, "Open",
1076 "The file could not be opened.",
1077 kMBIconExclamation, kMBOk, &result);
1081 // get the folder with the monitor histograms
1082 TFolder* folder = (TFolder*) file->Get("Monitor");
1083 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1085 new TGMsgBox(gClient->GetRoot(), this, "Open",
1086 "The file does not contain monitor histograms.",
1087 kMBIconExclamation, kMBOk, &result);
1093 // replace the old folder with the new one
1097 if (fFolder) delete fFolder;
1103 //_____________________________________________________________________________
1104 void AliMonitorClient::ViewToolBar(Bool_t visible)
1106 // en- or disable the view of the tool bar
1109 ShowFrame(fToolBarSep);
1110 ShowFrame(fToolBar);
1111 fMenuView->CheckEntry(kMenuViewToolBar);
1113 HideFrame(fToolBarSep);
1114 HideFrame(fToolBar);
1115 fMenuView->UnCheckEntry(kMenuViewToolBar);
1119 //_____________________________________________________________________________
1120 void AliMonitorClient::ViewTree(Bool_t visible)
1122 // en- or disable the view of the tree
1125 fHorizontalFrame->ShowFrame(fTreeFrame);
1126 fHorizontalFrame->ShowFrame(fTreeSplitter);
1127 fMenuView->CheckEntry(kMenuViewTree);
1129 fHorizontalFrame->HideFrame(fTreeFrame);
1130 fHorizontalFrame->HideFrame(fTreeSplitter);
1131 fMenuView->UnCheckEntry(kMenuViewTree);
1135 //_____________________________________________________________________________
1136 void AliMonitorClient::ViewDescription(Bool_t visible)
1138 // en- or disable the view of the histogram description
1141 fVerticalFrame->ShowFrame(fDescriptionFrame);
1142 fVerticalFrame->ShowFrame(fDescriptionSplitter);
1143 fMenuView->CheckEntry(kMenuViewDescription);
1145 fVerticalFrame->HideFrame(fDescriptionFrame);
1146 fVerticalFrame->HideFrame(fDescriptionSplitter);
1147 fMenuView->UnCheckEntry(kMenuViewDescription);
1151 //_____________________________________________________________________________
1152 void AliMonitorClient::ViewReference(Bool_t visible)
1154 // en- or disable the view of the reference histos
1157 AliMonitorHisto::SetDrawRef(kTRUE);
1158 fMenuView->CheckEntry(kMenuViewReference);
1160 AliMonitorHisto::SetDrawRef(kFALSE);
1161 fMenuView->UnCheckEntry(kMenuViewReference);
1165 //_____________________________________________________________________________
1166 void AliMonitorClient::ViewStatistics(Bool_t visible)
1168 // en- or disable the view of the statistics box
1171 gStyle->SetOptStat(1110);
1172 fMenuView->CheckEntry(kMenuViewStatistics);
1174 gStyle->SetOptStat(0);
1175 fMenuView->UnCheckEntry(kMenuViewStatistics);
1180 //_____________________________________________________________________________
1181 Bool_t AliMonitorClient::AddFavorite()
1183 // add the current histogram or folder to the list of favorites
1185 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1187 // get the folder item
1188 TGListTreeItem* folderItem = fCurrentItem->GetParent();
1189 if (fCurrentItem->GetFirstChild()) folderItem = fCurrentItem;
1191 Bool_t result = kFALSE;
1194 if (fCurrentItem->GetFirstChild()) {
1195 TGListTreeItem* histoItem = fCurrentItem->GetFirstChild();
1197 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1198 histoItem->GetText(), kFALSE)) result = kTRUE;
1199 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1200 histoItem->GetText(), kTRUE);
1201 item->SetUserData(histoItem->GetUserData());
1202 histoItem = histoItem->GetNextSibling();
1207 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1208 fCurrentItem->GetText(), kFALSE)) result = kTRUE;
1209 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1210 fCurrentItem->GetText(), kTRUE);
1211 item->SetUserData(fCurrentItem->GetUserData());
1214 if (result) gClient->NeedRedraw(fTree);
1218 //_____________________________________________________________________________
1219 Bool_t AliMonitorClient::DeleteFavorite()
1221 // delete the current histogram or folder from the list of favorites
1223 // check that the current item is a favorites histo or folder
1224 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1225 TGListTreeItem* base = fCurrentItem;
1226 while (base->GetParent()) base = base->GetParent();
1227 if (base != fFavoritesItem) return kFALSE;
1230 TGListTreeItem* parent = fCurrentItem->GetParent();
1231 fTree->DeleteItem(fCurrentItem);
1232 fCurrentItem = NULL;
1234 // delete the parent folder if it is empty now
1235 if (parent->GetParent() != NULL) {
1236 if (!parent->GetFirstChild()) fTree->DeleteItem(parent);
1239 gClient->NeedRedraw(fTree);
1243 //_____________________________________________________________________________
1244 Bool_t AliMonitorClient::LoadFavorites(Bool_t dialog)
1246 // load the list of favorites from a file
1248 // display a file open dialog
1249 TGFileInfo fileInfo;
1250 static const char* fileTypes[] = {"Favorites files", "*.fav",
1253 fileInfo.fFileTypes = fileTypes;
1254 fileInfo.fIniDir = StrDup(".");
1255 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1257 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1258 if (!fileInfo.fFilename) return kFALSE;
1261 // open the text file
1262 FILE* file = fopen(fileInfo.fFilename, "rt");
1265 new TGMsgBox(gClient->GetRoot(), this, "Load Favorites",
1266 "The file could not be opened.",
1267 kMBIconExclamation, kMBOk, &result);
1271 // delete the old favorites
1272 TGListTreeItem* favFolderItem = fFavoritesItem->GetFirstChild();
1273 while (favFolderItem) {
1274 TGListTreeItem* deleteItem = favFolderItem;
1275 favFolderItem = favFolderItem->GetNextSibling();
1276 fTree->DeleteItem(deleteItem);
1279 // scan the text file and add the favorites histos
1281 while (!feof(file)) {
1282 if (fgets(buffer, 255, file) == NULL) break;
1283 char* folder = strtok(buffer, "/");
1284 char* item = strtok(NULL, "\n");
1285 if (item[strlen(item)-1] == '\n') item[strlen(item)-1] = 0;
1286 if (!folder || !item) continue;
1288 AliMonitorHisto* histo = GetHisto(folder, item);
1289 TGListTreeItem* histoItem = GetItem(fFavoritesItem, folder, item, kTRUE);
1290 histoItem->SetUserData(histo);
1297 //_____________________________________________________________________________
1298 Bool_t AliMonitorClient::SaveFavorites()
1300 // save the list of favorites in a file with the name fFavoritesFileName
1302 // if no file name is given use a default one
1303 if (fFavoritesFileName.IsNull()) {
1304 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1305 "AliMonitorClient.fav");
1306 fFavoritesFileName = fileName;
1310 // open the text file
1311 FILE* file = fopen(fFavoritesFileName.Data(), "wt");
1314 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1315 "The file could not be opened.",
1316 kMBIconExclamation, kMBOk, &result);
1320 // loop over folders
1321 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1322 while (folderItem) {
1325 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1328 // write the favorites
1329 if (fprintf(file, "%s/%s\n", folderItem->GetText(),
1330 histoItem->GetText()) <= 0) {
1332 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1333 "An error occured while sving the favorites.",
1334 kMBIconExclamation, kMBOk, &result);
1338 histoItem = histoItem->GetNextSibling();
1341 folderItem = folderItem->GetNextSibling();
1345 Info("SaveFavorites", "favorites saved to file %s",
1346 fFavoritesFileName.Data());
1350 //_____________________________________________________________________________
1351 Bool_t AliMonitorClient::SaveFavoritesAs()
1353 // ask for a file name and save the favorites to this file
1355 // display a save file dialog
1356 TGFileInfo fileInfo;
1357 static const char* fileTypes[] = {"Favorites files", "*.fav",
1360 fileInfo.fFileTypes = fileTypes;
1361 fileInfo.fIniDir = StrDup(".");
1362 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1363 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1364 if (!fileInfo.fFilename) return kFALSE;
1366 // save the favorites
1367 fFavoritesFileName = fileInfo.fFilename;
1368 return SaveFavorites();
1372 //_____________________________________________________________________________
1373 Bool_t AliMonitorClient::LoadReference(Bool_t dialog)
1375 // load reference histograms from a file
1377 // display a file open dialog
1378 TGFileInfo fileInfo;
1379 static const char* fileTypes[] = {"ROOT files", "*.root",
1382 fileInfo.fFileTypes = fileTypes;
1383 fileInfo.fIniDir = StrDup(".");
1384 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1386 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1387 if (!fileInfo.fFilename) return kFALSE;
1390 // open the root file
1391 TFile* file = TFile::Open(fileInfo.fFilename);
1392 if (!file || !file->IsOpen()) {
1394 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1395 "The file could not be opened.",
1396 kMBIconExclamation, kMBOk, &result);
1400 // get the folder with the monitor histograms
1401 TFolder* folder = (TFolder*) file->Get("Monitor");
1402 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1404 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1405 "The file does not contain monitor histograms.",
1406 kMBIconExclamation, kMBOk, &result);
1412 // replace the old reference folder with the new one
1413 fReferenceFileName = fileInfo.fFilename;
1417 if (fReference) delete fReference;
1418 fReference = folder;
1422 //_____________________________________________________________________________
1423 void AliMonitorClient::SetReference()
1425 // set the reference histograms for all monitor histograms
1428 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1429 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1430 TFolder* refFolder = (TFolder*) fReference->FindObject(folder->GetName());
1431 if (!refFolder) continue;
1434 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1435 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1436 AliMonitorHisto* refHisto =
1437 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1438 if (!refHisto) continue;
1439 histo->SetReference(refHisto);
1447 //_____________________________________________________________________________
1448 Bool_t AliMonitorClient::TakeCurrentReference()
1450 // take the current monitor histogram or folder as reference
1452 // check that a histo or folder is selected
1453 if (!fCurrentItem) return kFALSE;
1454 AliMonitorHisto* histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
1455 if (!histo && !fCurrentItem->GetFirstChild()) return kFALSE;
1460 sprintf(message, "Do you want to take the current histogram %s/%s "
1461 "as reference histogram?", fCurrentItem->GetParent()->GetText(),
1464 sprintf(message, "Do you want to take all current histogram of the "
1465 "folder %s as reference histogram?", fCurrentItem->GetText());
1468 new TGMsgBox(gClient->GetRoot(), this, "Take Current as Reference",
1469 message, kMBIconQuestion, kMBYes | kMBNo, &result);
1470 if (result != kMBYes) return kFALSE;
1473 if (histo) { // ... a histo
1474 TakeReferenceHisto(fCurrentItem->GetParent()->GetText(), histo);
1475 } else if (fCurrentItem->GetParent()) { // ... a folder
1476 TakeReferenceFolder(fCurrentItem);
1477 } else { // ... a top folder
1478 TGListTreeItem* folderItem = fCurrentItem->GetFirstChild();
1479 while (folderItem) {
1480 TakeReferenceFolder(folderItem);
1481 folderItem = folderItem->GetNextSibling();
1487 //_____________________________________________________________________________
1488 void AliMonitorClient::TakeReferenceHisto(const char* folderName,
1489 AliMonitorHisto* histo)
1491 // take the given monitor histogram as reference histogram
1493 // get or create the reference folder
1494 TFolder* refFolder = (TFolder*) fReference->FindObject(folderName);
1495 if (!refFolder) refFolder = fReference->AddFolder(folderName, folderName);
1497 // delete the old reference histo
1498 AliMonitorHisto* refHisto =
1499 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1501 refFolder->Remove(refHisto);
1505 // add the new one and use it as reference
1506 refFolder->Add(new AliMonitorHisto(*histo));
1507 histo->SetReference(histo);
1510 //_____________________________________________________________________________
1511 void AliMonitorClient::TakeReferenceFolder(TGListTreeItem* item)
1513 // take all monitor histogram in the given folder as reference histograms
1516 TGListTreeItem* histoItem = item->GetFirstChild();
1518 AliMonitorHisto* histo = (AliMonitorHisto*) histoItem->GetUserData();
1519 if (histo) TakeReferenceHisto(item->GetText(), histo);
1520 histoItem = histoItem->GetNextSibling();
1524 //_____________________________________________________________________________
1525 Bool_t AliMonitorClient::SaveReference()
1527 // save the reference histograms to the file with name fReferenceFileName
1529 // if no file name is given use a default one
1530 if (fFavoritesFileName.IsNull()) {
1531 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1532 "AliMonitorClientRef.root");
1533 fFavoritesFileName = fileName;
1537 // open the root file
1538 TFile* file = TFile::Open(fReferenceFileName, "RECREATE");
1539 if (!file || !file->IsOpen()) {
1541 new TGMsgBox(gClient->GetRoot(), this, "Save Reference",
1542 "The file could not be opened.",
1543 kMBIconExclamation, kMBOk, &result);
1544 if (file) delete file;
1548 // write the reference folder
1549 fReference->Write();
1552 Info("SaveReference", "reference histograms saved to file %s",
1553 fReferenceFileName.Data());
1557 //_____________________________________________________________________________
1558 Bool_t AliMonitorClient::SaveReferenceAs()
1560 // ask for a file name and save the reference histograms to this file
1562 // display a save file dialog
1563 TGFileInfo fileInfo;
1564 static const char* fileTypes[] = {"ROOT files", "*.root",
1567 fileInfo.fFileTypes = fileTypes;
1568 fileInfo.fIniDir = StrDup(".");
1569 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1570 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1571 if (!fileInfo.fFilename) return kFALSE;
1573 // save the references
1574 fReferenceFileName = fileInfo.fFilename;
1575 return SaveReference();
1579 //_____________________________________________________________________________
1580 void AliMonitorClient::StopLoop()
1582 // stop looping over histograms
1584 // stop the timer and reset the loop button picture
1586 fLoopTimer->TurnOff();
1589 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOnPicture);
1593 //_____________________________________________________________________________
1594 void AliMonitorClient::LoadSettings()
1596 // load setting from the file with the name fgSettingFileName and apply them
1598 // open the text file
1599 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1600 fgSettingsFileName);
1601 FILE* file = fopen(fileName, "rt");
1607 // scan the text file and apply the settings
1609 while (!feof(file)) {
1610 if (fgets(buffer, 255, file) == NULL) break;
1611 char* token = strtok(buffer, "=");
1612 char* value = strtok(NULL, "\n");
1613 if (!token || !value) continue;
1614 if (value[strlen(value)-1] == '\n') value[strlen(value)-1] = 0;
1616 if (strcmp(token, "ServerName") == 0) {
1617 fServerName = value;
1619 } else if (strcmp(token, "ViewToolBar") == 0) {
1620 ViewToolBar(strcmp(value, "0") != 0);
1621 } else if (strcmp(token, "ViewTree") == 0) {
1622 ViewTree(strcmp(value, "0") != 0);
1623 } else if (strcmp(token, "ViewDescription") == 0) {
1624 ViewDescription(strcmp(value, "0") != 0);
1625 } else if (strcmp(token, "ViewReference") == 0) {
1626 ViewReference(strcmp(value, "0") != 0);
1627 } else if (strcmp(token, "ViewStatistics") == 0) {
1628 ViewStatistics(strcmp(value, "0") != 0);
1630 } else if (strcmp(token, "FavoritesFileName") == 0) {
1631 fFavoritesFileName = value;
1632 LoadFavorites(kFALSE);
1633 } else if (strcmp(token, "FavoritesSaveOnExit") == 0) {
1634 if (strcmp(value, "0") != 0) {
1635 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
1637 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
1640 } else if (strcmp(token, "ReferenceFileName") == 0) {
1641 fReferenceFileName = value;
1642 LoadReference(kFALSE);
1643 } else if (strcmp(token, "ReferenceThreshold") == 0) {
1644 AliMonitorHisto::SetThreshold(atof(value));
1646 } else if (strcmp(token, "LoopInterval") == 0) {
1647 fLoopInterval = atoi(value);
1648 } else if (strcmp(token, "PrintCommand") == 0) {
1649 fPrintCommand = value;
1650 } else if (strcmp(token, "SettingsSaveOnExit") == 0) {
1651 if (strcmp(value, "0") != 0) {
1652 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
1654 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
1660 Info("LoadSettings", "settings from file %s applied", fileName);
1664 //_____________________________________________________________________________
1665 void AliMonitorClient::SaveSettings()
1667 // save setting to the file with the name fgSettingFileName
1669 // open the text file
1670 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1671 fgSettingsFileName);
1672 FILE* file = fopen(fileName, "wt");
1675 new TGMsgBox(gClient->GetRoot(), this, "Save Settings",
1676 "The file could not be opened.",
1677 kMBIconExclamation, kMBOk, &result);
1682 // write the settings
1683 fprintf(file, "ServerName=%s\n", fServerName.Data());
1685 fprintf(file, "ViewToolBar=%d\n",
1686 fMenuView->IsEntryChecked(kMenuViewToolBar));
1687 fprintf(file, "ViewTree=%d\n",
1688 fMenuView->IsEntryChecked(kMenuViewTree));
1689 fprintf(file, "ViewDescription=%d\n",
1690 fMenuView->IsEntryChecked(kMenuViewDescription));
1691 fprintf(file, "ViewReference=%d\n",
1692 fMenuView->IsEntryChecked(kMenuViewReference));
1693 fprintf(file, "ViewStatistics=%d\n",
1694 fMenuView->IsEntryChecked(kMenuViewStatistics));
1696 if (!fFavoritesFileName.IsNull()) {
1697 fprintf(file, "FavoritesFileName=%s\n", fFavoritesFileName.Data());
1699 fprintf(file, "FavoritesSaveOnExit=%d\n",
1700 fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit));
1702 if (!fReferenceFileName.IsNull()) {
1703 fprintf(file, "ReferenceFileName=%s\n", fReferenceFileName.Data());
1705 fprintf(file, "ReferenceThreshold=%.1f\n", AliMonitorHisto::GetThreshold());
1707 fprintf(file, "LoopInterval=%d\n", fLoopInterval);
1708 fprintf(file, "PrintCommand=%s\n", fPrintCommand.Data());
1709 fprintf(file, "SettingsSaveOnExit=%d\n",
1710 fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit));
1713 Info("SaveSettings", "settings saved to file %s", fileName);
1718 //_____________________________________________________________________________
1719 Bool_t AliMonitorClient::GetBaseItem()
1721 // get the base item for looping over histograms
1724 // the base item is a folder
1725 fBaseItem = fCurrentItem;
1726 // if the current item is a histo, its parent is the base folder
1727 if (fBaseItem->GetParent() && fBaseItem->GetParent()->GetParent()) {
1728 fBaseItem = fBaseItem->GetParent();
1731 } else { // if no item is selected the All item is the base item
1732 fBaseItem = fAllItem;
1733 fCurrentItem = fBaseItem->GetFirstChild();
1734 if (!fCurrentItem) return kFALSE;
1740 //_____________________________________________________________________________
1741 Bool_t AliMonitorClient::GoToNextItem()
1743 // go to the next histogram in the loop
1745 if (!fCurrentItem) return kFALSE;
1746 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1748 // remember the start item to avoid an endless loop
1749 TGListTreeItem* startItem = fCurrentItem;
1752 // folder -> first child
1753 if (fCurrentItem->GetFirstChild()) {
1754 fCurrentItem = fCurrentItem->GetFirstChild();
1756 // histo -> next histo
1757 } else if ((fCurrentItem != fBaseItem) &&
1758 (fCurrentItem->GetNextSibling())) {
1759 fCurrentItem = fCurrentItem->GetNextSibling();
1761 // last histo in folder -> next folder
1762 } else if ((fCurrentItem != fBaseItem) &&
1763 (fCurrentItem->GetParent() != fBaseItem) &&
1764 fCurrentItem->GetParent()->GetNextSibling()) {
1765 fCurrentItem = fCurrentItem->GetParent()->GetNextSibling();
1767 // last histo in last folder -> first folder
1769 fCurrentItem = fBaseItem->GetFirstChild();
1772 // abort if no next item found
1773 if (fCurrentItem == startItem) return kFALSE;
1775 // end loop if an item with a monitor histo was found
1776 } while (!fCurrentItem->GetUserData());
1782 //_____________________________________________________________________________
1783 Bool_t AliMonitorClient::GoToPreviousItem()
1785 // go to the previous histogram in the loop
1787 if (!fCurrentItem) return kFALSE;
1788 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1790 // remember the start item to avoid an endless loop
1791 TGListTreeItem* startItem = fCurrentItem;
1794 // folder -> last child
1795 if (fCurrentItem->GetFirstChild()) {
1796 fCurrentItem = fCurrentItem->GetFirstChild();
1797 while (fCurrentItem->GetNextSibling()) {
1798 fCurrentItem = fCurrentItem->GetNextSibling();
1801 // histo -> previous histo
1802 } else if ((fCurrentItem != fBaseItem) &&
1803 (fCurrentItem->GetPrevSibling())) {
1804 fCurrentItem = fCurrentItem->GetPrevSibling();
1806 // first histo in folder -> previous folder
1807 } else if ((fCurrentItem != fBaseItem) &&
1808 (fCurrentItem->GetParent() != fBaseItem) &&
1809 fCurrentItem->GetParent()->GetPrevSibling()) {
1810 fCurrentItem = fCurrentItem->GetParent()->GetPrevSibling();
1812 // first histo in first folder -> last folder
1814 fCurrentItem = fBaseItem->GetFirstChild();
1815 while (fCurrentItem->GetNextSibling()) {
1816 fCurrentItem = fCurrentItem->GetNextSibling();
1820 // abort if no next item found
1821 if (fCurrentItem == startItem) return kFALSE;
1823 // end loop if an item with a monitor histo was found
1824 } while (!fCurrentItem->GetUserData());
1830 //_____________________________________________________________________________
1831 void AliMonitorClient::UpdateItem(Bool_t highlight)
1833 // update the displayed tree for currently selected item
1835 if (highlight) { // highlight the selected item and open its parent folders
1836 TGListTreeItem* parent = fCurrentItem->GetParent();
1838 if (!parent->IsOpen()) fTree->OpenItem(parent);
1839 parent = parent->GetParent();
1841 fTree->HighlightItem(fCurrentItem);
1842 gClient->NeedRedraw(fTree);
1845 // update displayed histo
1846 UpdateDescription();
1849 // en- or disable the "Reference/Take Current" menu item
1850 TGListTreeItem* base = fCurrentItem;
1851 while (base->GetParent()) base = base->GetParent();
1852 if (base != fComparisonItem) {
1853 fMenuReference->EnableEntry(kMenuRefTakeCurrent);
1855 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
1858 // en- or disable the "Favorites/Add" and "Favorites/Delete" menu items
1859 if (fCurrentItem->GetParent()) {
1860 if (base == fFavoritesItem) {
1861 fMenuFavorites->DisableEntry(kMenuFavAdd);
1862 fMenuFavorites->EnableEntry(kMenuFavDelete);
1864 fMenuFavorites->EnableEntry(kMenuFavAdd);
1865 fMenuFavorites->DisableEntry(kMenuFavDelete);
1868 fMenuFavorites->DisableEntry(kMenuFavAdd);
1869 fMenuFavorites->DisableEntry(kMenuFavDelete);
1874 //_____________________________________________________________________________
1875 Bool_t AliMonitorClient::CheckForNewData()
1877 // check whether the monitor process server sent new data
1879 // receive a message from the server
1880 if (!fSocket || !fSocket->IsValid()) return kFALSE;
1881 TMessage* message = NULL;
1882 Int_t result = fSocket->Recv(message);
1884 // replace the old folder of monitor histos with the new one
1886 if (fFolder) delete fFolder;
1887 fFolder = (TFolder*) message->ReadObject(message->GetClass());
1894 //_____________________________________________________________________________
1895 void AliMonitorClient::ClearItems(TGListTreeItem* base)
1897 // remove the references to the histograms from all subitems of the
1900 // loop over folders
1901 TGListTreeItem* folderItem = base->GetFirstChild();
1902 while (folderItem) {
1905 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1907 histoItem->SetUserData(NULL);
1908 histoItem = histoItem->GetNextSibling();
1911 folderItem = folderItem->GetNextSibling();
1915 //_____________________________________________________________________________
1916 void AliMonitorClient::CleanUpTree(TGListTreeItem* base)
1918 // remove items without monitor histograms and
1919 // folders without monitor histograms
1921 // loop over folders
1922 TGListTreeItem* folderItem = base->GetFirstChild();
1923 while (folderItem) {
1926 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1928 TGListTreeItem* deleteItem = NULL;
1929 if (!histoItem->GetUserData()) deleteItem = histoItem;
1930 histoItem = histoItem->GetNextSibling();
1931 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1932 if (deleteItem) fTree->DeleteItem(deleteItem);
1935 folderItem = folderItem->GetNextSibling();
1938 // loop over folders and remove empty folders
1939 folderItem = base->GetFirstChild();
1940 while (folderItem) {
1941 TGListTreeItem* deleteItem = NULL;
1942 if (!folderItem->GetFirstChild()) deleteItem = folderItem;
1943 folderItem = folderItem->GetNextSibling();
1944 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1945 if (deleteItem) fTree->DeleteItem(deleteItem);
1949 //_____________________________________________________________________________
1950 void AliMonitorClient::UpdateTree()
1952 // update the tree of monitor histograms
1954 // delete references to old monitor histograms
1955 ClearItems(fAllItem);
1958 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1959 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1962 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1963 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1965 // add new monitor histograms
1966 TGListTreeItem* histoItem = GetItem(fAllItem, folder->GetName(),
1967 histo->GetName(), kTRUE);
1968 histoItem->SetUserData(histo);
1975 // remove items and folders without monitor histograms
1976 CleanUpTree(fAllItem);
1978 gClient->NeedRedraw(fTree);
1981 //_____________________________________________________________________________
1982 void AliMonitorClient::UpdateFavoritesTree()
1984 // update the tree of favorite monitor histograms
1986 // loop over folders
1987 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1988 while (folderItem) {
1991 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1994 // set monitor histo
1995 histoItem->SetUserData(GetHisto(folderItem->GetText(),
1996 histoItem->GetText()));
1997 histoItem = histoItem->GetNextSibling();
2000 folderItem = folderItem->GetNextSibling();
2004 //_____________________________________________________________________________
2005 void AliMonitorClient::UpdateComparisonTree()
2007 // update the tree of monitor histograms with significant deviation
2008 // from the reference histograms
2010 if (!fFolder) return;
2012 // delete references to old monitor histograms
2013 ClearItems(fComparisonItem);
2015 // add monitor histograms where the comparison returns a deviation
2016 // loop over folders
2017 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
2018 while (TFolder* folder = (TFolder*) iFolder->Next()) {
2021 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
2022 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
2024 // compare the histo to its reference
2025 Bool_t comparison = kTRUE;
2026 if (fEventButton->IsDown()) {
2027 comparison = histo->CompareEvent(fEventNumber->GetIntNumber());
2028 } else if (fSumButton->IsDown()) {
2029 comparison = histo->CompareSum(fEventNumber->GetIntNumber());
2031 comparison = histo->CompareRun();
2034 // add it to the comparison tree in case of a bad comparison result
2036 TGListTreeItem* histoItem = GetItem(fComparisonItem, folder->GetName(),
2037 histo->GetName(), kTRUE);
2038 histoItem->SetUserData(histo);
2046 // remove items and folders without monitor histograms
2047 CleanUpTree(fComparisonItem);
2049 gClient->NeedRedraw(fTree);
2052 //_____________________________________________________________________________
2053 void AliMonitorClient::UpdateDescription()
2055 // update the description of the current monitor histogram
2057 fDescription->Clear();
2058 AliMonitorHisto* histo = NULL;
2059 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2060 if (histo) fDescription->LoadBuffer(histo->GetDescription().Data());
2062 gClient->NeedRedraw(fDescription);
2065 //_____________________________________________________________________________
2066 void AliMonitorClient::UpdateHisto()
2068 // update the current monitor histogram
2070 // clear the canvas if no histo is selected
2071 AliMonitorHisto* histo = NULL;
2072 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2074 fDrawCanvas->GetCanvas()->Clear();
2075 fDrawCanvas->GetCanvas()->Update();
2079 // draw the histo for a single event or summed over several events or a run
2080 fDrawCanvas->GetCanvas()->cd();
2081 if (fEventButton->IsDown()) {
2082 histo->DrawEvent(fEventNumber->GetIntNumber());
2083 } else if (fSumButton->IsDown()) {
2084 histo->DrawSum(fEventNumber->GetIntNumber());
2090 //_____________________________________________________________________________
2091 void AliMonitorClient::UpdateAll()
2093 // update the trees, the histogram and the description
2096 UpdateFavoritesTree();
2097 UpdateComparisonTree();
2098 UpdateDescription();