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
1049 fSocketHandler->Remove();
1050 fSocket->Send("Finished");
1054 fMenuFile->HideEntry(kMenuFileDisconnect);
1055 fMenuFile->EnableEntry(kMenuFileConnect);
1056 fMenuFile->EnableEntry(kMenuFileOpen);
1059 //_____________________________________________________________________________
1060 Bool_t AliMonitorClient::OpenFile()
1062 // open a file with monitor histograms
1064 // display a file open dialog
1065 static TGFileInfo fileInfo;
1066 static const char* fileTypes[] = {"ROOT files", "*.root",
1069 fileInfo.fFileTypes = fileTypes;
1070 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1071 if (!fileInfo.fFilename) return kFALSE;
1073 // open the root file
1074 TFile* file = TFile::Open(fileInfo.fFilename);
1075 if (!file || !file->IsOpen()) {
1077 new TGMsgBox(gClient->GetRoot(), this, "Open",
1078 "The file could not be opened.",
1079 kMBIconExclamation, kMBOk, &result);
1083 // get the folder with the monitor histograms
1084 TFolder* folder = (TFolder*) file->Get("Monitor");
1085 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1087 new TGMsgBox(gClient->GetRoot(), this, "Open",
1088 "The file does not contain monitor histograms.",
1089 kMBIconExclamation, kMBOk, &result);
1095 // replace the old folder with the new one
1099 if (fFolder) delete fFolder;
1105 //_____________________________________________________________________________
1106 void AliMonitorClient::ViewToolBar(Bool_t visible)
1108 // en- or disable the view of the tool bar
1111 ShowFrame(fToolBarSep);
1112 ShowFrame(fToolBar);
1113 fMenuView->CheckEntry(kMenuViewToolBar);
1115 HideFrame(fToolBarSep);
1116 HideFrame(fToolBar);
1117 fMenuView->UnCheckEntry(kMenuViewToolBar);
1121 //_____________________________________________________________________________
1122 void AliMonitorClient::ViewTree(Bool_t visible)
1124 // en- or disable the view of the tree
1127 fHorizontalFrame->ShowFrame(fTreeFrame);
1128 fHorizontalFrame->ShowFrame(fTreeSplitter);
1129 fMenuView->CheckEntry(kMenuViewTree);
1131 fHorizontalFrame->HideFrame(fTreeFrame);
1132 fHorizontalFrame->HideFrame(fTreeSplitter);
1133 fMenuView->UnCheckEntry(kMenuViewTree);
1137 //_____________________________________________________________________________
1138 void AliMonitorClient::ViewDescription(Bool_t visible)
1140 // en- or disable the view of the histogram description
1143 fVerticalFrame->ShowFrame(fDescriptionFrame);
1144 fVerticalFrame->ShowFrame(fDescriptionSplitter);
1145 fMenuView->CheckEntry(kMenuViewDescription);
1147 fVerticalFrame->HideFrame(fDescriptionFrame);
1148 fVerticalFrame->HideFrame(fDescriptionSplitter);
1149 fMenuView->UnCheckEntry(kMenuViewDescription);
1153 //_____________________________________________________________________________
1154 void AliMonitorClient::ViewReference(Bool_t visible)
1156 // en- or disable the view of the reference histos
1159 AliMonitorHisto::SetDrawRef(kTRUE);
1160 fMenuView->CheckEntry(kMenuViewReference);
1162 AliMonitorHisto::SetDrawRef(kFALSE);
1163 fMenuView->UnCheckEntry(kMenuViewReference);
1167 //_____________________________________________________________________________
1168 void AliMonitorClient::ViewStatistics(Bool_t visible)
1170 // en- or disable the view of the statistics box
1173 gStyle->SetOptStat(1110);
1174 fMenuView->CheckEntry(kMenuViewStatistics);
1176 gStyle->SetOptStat(0);
1177 fMenuView->UnCheckEntry(kMenuViewStatistics);
1182 //_____________________________________________________________________________
1183 Bool_t AliMonitorClient::AddFavorite()
1185 // add the current histogram or folder to the list of favorites
1187 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1189 // get the folder item
1190 TGListTreeItem* folderItem = fCurrentItem->GetParent();
1191 if (fCurrentItem->GetFirstChild()) folderItem = fCurrentItem;
1193 Bool_t result = kFALSE;
1196 if (fCurrentItem->GetFirstChild()) {
1197 TGListTreeItem* histoItem = fCurrentItem->GetFirstChild();
1199 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1200 histoItem->GetText(), kFALSE)) result = kTRUE;
1201 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1202 histoItem->GetText(), kTRUE);
1203 item->SetUserData(histoItem->GetUserData());
1204 histoItem = histoItem->GetNextSibling();
1209 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1210 fCurrentItem->GetText(), kFALSE)) result = kTRUE;
1211 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1212 fCurrentItem->GetText(), kTRUE);
1213 item->SetUserData(fCurrentItem->GetUserData());
1216 if (result) gClient->NeedRedraw(fTree);
1220 //_____________________________________________________________________________
1221 Bool_t AliMonitorClient::DeleteFavorite()
1223 // delete the current histogram or folder from the list of favorites
1225 // check that the current item is a favorites histo or folder
1226 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1227 TGListTreeItem* base = fCurrentItem;
1228 while (base->GetParent()) base = base->GetParent();
1229 if (base != fFavoritesItem) return kFALSE;
1232 TGListTreeItem* parent = fCurrentItem->GetParent();
1233 fTree->DeleteItem(fCurrentItem);
1234 fCurrentItem = NULL;
1236 // delete the parent folder if it is empty now
1237 if (parent->GetParent() != NULL) {
1238 if (!parent->GetFirstChild()) fTree->DeleteItem(parent);
1241 gClient->NeedRedraw(fTree);
1245 //_____________________________________________________________________________
1246 Bool_t AliMonitorClient::LoadFavorites(Bool_t dialog)
1248 // load the list of favorites from a file
1250 // display a file open dialog
1251 TGFileInfo fileInfo;
1252 static const char* fileTypes[] = {"Favorites files", "*.fav",
1255 fileInfo.fFileTypes = fileTypes;
1256 fileInfo.fIniDir = StrDup(".");
1257 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1259 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1260 if (!fileInfo.fFilename) return kFALSE;
1263 // open the text file
1264 FILE* file = fopen(fileInfo.fFilename, "rt");
1267 new TGMsgBox(gClient->GetRoot(), this, "Load Favorites",
1268 "The file could not be opened.",
1269 kMBIconExclamation, kMBOk, &result);
1273 // delete the old favorites
1274 TGListTreeItem* favFolderItem = fFavoritesItem->GetFirstChild();
1275 while (favFolderItem) {
1276 TGListTreeItem* deleteItem = favFolderItem;
1277 favFolderItem = favFolderItem->GetNextSibling();
1278 fTree->DeleteItem(deleteItem);
1281 // scan the text file and add the favorites histos
1283 while (!feof(file)) {
1284 if (fgets(buffer, 255, file) == NULL) break;
1285 char* folder = strtok(buffer, "/");
1286 char* item = strtok(NULL, "\n");
1287 if (item[strlen(item)-1] == '\n') item[strlen(item)-1] = 0;
1288 if (!folder || !item) continue;
1290 AliMonitorHisto* histo = GetHisto(folder, item);
1291 TGListTreeItem* histoItem = GetItem(fFavoritesItem, folder, item, kTRUE);
1292 histoItem->SetUserData(histo);
1299 //_____________________________________________________________________________
1300 Bool_t AliMonitorClient::SaveFavorites()
1302 // save the list of favorites in a file with the name fFavoritesFileName
1304 // if no file name is given use a default one
1305 if (fFavoritesFileName.IsNull()) {
1306 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1307 "AliMonitorClient.fav");
1308 fFavoritesFileName = fileName;
1312 // open the text file
1313 FILE* file = fopen(fFavoritesFileName.Data(), "wt");
1316 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1317 "The file could not be opened.",
1318 kMBIconExclamation, kMBOk, &result);
1322 // loop over folders
1323 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1324 while (folderItem) {
1327 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1330 // write the favorites
1331 if (fprintf(file, "%s/%s\n", folderItem->GetText(),
1332 histoItem->GetText()) <= 0) {
1334 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1335 "An error occured while sving the favorites.",
1336 kMBIconExclamation, kMBOk, &result);
1340 histoItem = histoItem->GetNextSibling();
1343 folderItem = folderItem->GetNextSibling();
1347 Info("SaveFavorites", "favorites saved to file %s",
1348 fFavoritesFileName.Data());
1352 //_____________________________________________________________________________
1353 Bool_t AliMonitorClient::SaveFavoritesAs()
1355 // ask for a file name and save the favorites to this file
1357 // display a save file dialog
1358 TGFileInfo fileInfo;
1359 static const char* fileTypes[] = {"Favorites files", "*.fav",
1362 fileInfo.fFileTypes = fileTypes;
1363 fileInfo.fIniDir = StrDup(".");
1364 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1365 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1366 if (!fileInfo.fFilename) return kFALSE;
1368 // save the favorites
1369 fFavoritesFileName = fileInfo.fFilename;
1370 return SaveFavorites();
1374 //_____________________________________________________________________________
1375 Bool_t AliMonitorClient::LoadReference(Bool_t dialog)
1377 // load reference histograms from a file
1379 // display a file open dialog
1380 TGFileInfo fileInfo;
1381 static const char* fileTypes[] = {"ROOT files", "*.root",
1384 fileInfo.fFileTypes = fileTypes;
1385 fileInfo.fIniDir = StrDup(".");
1386 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1388 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1389 if (!fileInfo.fFilename) return kFALSE;
1392 // open the root file
1393 TFile* file = TFile::Open(fileInfo.fFilename);
1394 if (!file || !file->IsOpen()) {
1396 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1397 "The file could not be opened.",
1398 kMBIconExclamation, kMBOk, &result);
1402 // get the folder with the monitor histograms
1403 TFolder* folder = (TFolder*) file->Get("Monitor");
1404 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1406 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1407 "The file does not contain monitor histograms.",
1408 kMBIconExclamation, kMBOk, &result);
1414 // replace the old reference folder with the new one
1415 fReferenceFileName = fileInfo.fFilename;
1419 if (fReference) delete fReference;
1420 fReference = folder;
1424 //_____________________________________________________________________________
1425 void AliMonitorClient::SetReference()
1427 // set the reference histograms for all monitor histograms
1430 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1431 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1432 TFolder* refFolder = (TFolder*) fReference->FindObject(folder->GetName());
1433 if (!refFolder) continue;
1436 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1437 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1438 AliMonitorHisto* refHisto =
1439 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1440 if (!refHisto) continue;
1441 histo->SetReference(refHisto);
1449 //_____________________________________________________________________________
1450 Bool_t AliMonitorClient::TakeCurrentReference()
1452 // take the current monitor histogram or folder as reference
1454 // check that a histo or folder is selected
1455 if (!fCurrentItem) return kFALSE;
1456 AliMonitorHisto* histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
1457 if (!histo && !fCurrentItem->GetFirstChild()) return kFALSE;
1462 sprintf(message, "Do you want to take the current histogram %s/%s "
1463 "as reference histogram?", fCurrentItem->GetParent()->GetText(),
1466 sprintf(message, "Do you want to take all current histogram of the "
1467 "folder %s as reference histogram?", fCurrentItem->GetText());
1470 new TGMsgBox(gClient->GetRoot(), this, "Take Current as Reference",
1471 message, kMBIconQuestion, kMBYes | kMBNo, &result);
1472 if (result != kMBYes) return kFALSE;
1475 if (histo) { // ... a histo
1476 TakeReferenceHisto(fCurrentItem->GetParent()->GetText(), histo);
1477 } else if (fCurrentItem->GetParent()) { // ... a folder
1478 TakeReferenceFolder(fCurrentItem);
1479 } else { // ... a top folder
1480 TGListTreeItem* folderItem = fCurrentItem->GetFirstChild();
1481 while (folderItem) {
1482 TakeReferenceFolder(folderItem);
1483 folderItem = folderItem->GetNextSibling();
1489 //_____________________________________________________________________________
1490 void AliMonitorClient::TakeReferenceHisto(const char* folderName,
1491 AliMonitorHisto* histo)
1493 // take the given monitor histogram as reference histogram
1495 // get or create the reference folder
1496 TFolder* refFolder = (TFolder*) fReference->FindObject(folderName);
1497 if (!refFolder) refFolder = fReference->AddFolder(folderName, folderName);
1499 // delete the old reference histo
1500 AliMonitorHisto* refHisto =
1501 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1503 refFolder->Remove(refHisto);
1507 // add the new one and use it as reference
1508 refFolder->Add(new AliMonitorHisto(*histo));
1509 histo->SetReference(histo);
1512 //_____________________________________________________________________________
1513 void AliMonitorClient::TakeReferenceFolder(TGListTreeItem* item)
1515 // take all monitor histogram in the given folder as reference histograms
1518 TGListTreeItem* histoItem = item->GetFirstChild();
1520 AliMonitorHisto* histo = (AliMonitorHisto*) histoItem->GetUserData();
1521 if (histo) TakeReferenceHisto(item->GetText(), histo);
1522 histoItem = histoItem->GetNextSibling();
1526 //_____________________________________________________________________________
1527 Bool_t AliMonitorClient::SaveReference()
1529 // save the reference histograms to the file with name fReferenceFileName
1531 // if no file name is given use a default one
1532 if (fFavoritesFileName.IsNull()) {
1533 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1534 "AliMonitorClientRef.root");
1535 fFavoritesFileName = fileName;
1539 // open the root file
1540 TFile* file = TFile::Open(fReferenceFileName, "RECREATE");
1541 if (!file || !file->IsOpen()) {
1543 new TGMsgBox(gClient->GetRoot(), this, "Save Reference",
1544 "The file could not be opened.",
1545 kMBIconExclamation, kMBOk, &result);
1546 if (file) delete file;
1550 // write the reference folder
1551 fReference->Write();
1554 Info("SaveReference", "reference histograms saved to file %s",
1555 fReferenceFileName.Data());
1559 //_____________________________________________________________________________
1560 Bool_t AliMonitorClient::SaveReferenceAs()
1562 // ask for a file name and save the reference histograms to this file
1564 // display a save file dialog
1565 TGFileInfo fileInfo;
1566 static const char* fileTypes[] = {"ROOT files", "*.root",
1569 fileInfo.fFileTypes = fileTypes;
1570 fileInfo.fIniDir = StrDup(".");
1571 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1572 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1573 if (!fileInfo.fFilename) return kFALSE;
1575 // save the references
1576 fReferenceFileName = fileInfo.fFilename;
1577 return SaveReference();
1581 //_____________________________________________________________________________
1582 void AliMonitorClient::StopLoop()
1584 // stop looping over histograms
1586 // stop the timer and reset the loop button picture
1588 fLoopTimer->TurnOff();
1591 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOnPicture);
1595 //_____________________________________________________________________________
1596 void AliMonitorClient::LoadSettings()
1598 // load setting from the file with the name fgSettingFileName and apply them
1600 // open the text file
1601 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1602 fgSettingsFileName);
1603 FILE* file = fopen(fileName, "rt");
1609 // scan the text file and apply the settings
1611 while (!feof(file)) {
1612 if (fgets(buffer, 255, file) == NULL) break;
1613 char* token = strtok(buffer, "=");
1614 char* value = strtok(NULL, "\n");
1615 if (!token || !value) continue;
1616 if (value[strlen(value)-1] == '\n') value[strlen(value)-1] = 0;
1618 if (strcmp(token, "ServerName") == 0) {
1619 fServerName = value;
1621 } else if (strcmp(token, "ViewToolBar") == 0) {
1622 ViewToolBar(strcmp(value, "0") != 0);
1623 } else if (strcmp(token, "ViewTree") == 0) {
1624 ViewTree(strcmp(value, "0") != 0);
1625 } else if (strcmp(token, "ViewDescription") == 0) {
1626 ViewDescription(strcmp(value, "0") != 0);
1627 } else if (strcmp(token, "ViewReference") == 0) {
1628 ViewReference(strcmp(value, "0") != 0);
1629 } else if (strcmp(token, "ViewStatistics") == 0) {
1630 ViewStatistics(strcmp(value, "0") != 0);
1632 } else if (strcmp(token, "FavoritesFileName") == 0) {
1633 fFavoritesFileName = value;
1634 LoadFavorites(kFALSE);
1635 } else if (strcmp(token, "FavoritesSaveOnExit") == 0) {
1636 if (strcmp(value, "0") != 0) {
1637 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
1639 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
1642 } else if (strcmp(token, "ReferenceFileName") == 0) {
1643 fReferenceFileName = value;
1644 LoadReference(kFALSE);
1645 } else if (strcmp(token, "ReferenceThreshold") == 0) {
1646 AliMonitorHisto::SetThreshold(atof(value));
1648 } else if (strcmp(token, "LoopInterval") == 0) {
1649 fLoopInterval = atoi(value);
1650 } else if (strcmp(token, "PrintCommand") == 0) {
1651 fPrintCommand = value;
1652 } else if (strcmp(token, "SettingsSaveOnExit") == 0) {
1653 if (strcmp(value, "0") != 0) {
1654 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
1656 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
1662 Info("LoadSettings", "settings from file %s applied", fileName);
1666 //_____________________________________________________________________________
1667 void AliMonitorClient::SaveSettings()
1669 // save setting to the file with the name fgSettingFileName
1671 // open the text file
1672 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1673 fgSettingsFileName);
1674 FILE* file = fopen(fileName, "wt");
1677 new TGMsgBox(gClient->GetRoot(), this, "Save Settings",
1678 "The file could not be opened.",
1679 kMBIconExclamation, kMBOk, &result);
1684 // write the settings
1685 fprintf(file, "ServerName=%s\n", fServerName.Data());
1687 fprintf(file, "ViewToolBar=%d\n",
1688 fMenuView->IsEntryChecked(kMenuViewToolBar));
1689 fprintf(file, "ViewTree=%d\n",
1690 fMenuView->IsEntryChecked(kMenuViewTree));
1691 fprintf(file, "ViewDescription=%d\n",
1692 fMenuView->IsEntryChecked(kMenuViewDescription));
1693 fprintf(file, "ViewReference=%d\n",
1694 fMenuView->IsEntryChecked(kMenuViewReference));
1695 fprintf(file, "ViewStatistics=%d\n",
1696 fMenuView->IsEntryChecked(kMenuViewStatistics));
1698 if (!fFavoritesFileName.IsNull()) {
1699 fprintf(file, "FavoritesFileName=%s\n", fFavoritesFileName.Data());
1701 fprintf(file, "FavoritesSaveOnExit=%d\n",
1702 fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit));
1704 if (!fReferenceFileName.IsNull()) {
1705 fprintf(file, "ReferenceFileName=%s\n", fReferenceFileName.Data());
1707 fprintf(file, "ReferenceThreshold=%.1f\n", AliMonitorHisto::GetThreshold());
1709 fprintf(file, "LoopInterval=%d\n", fLoopInterval);
1710 fprintf(file, "PrintCommand=%s\n", fPrintCommand.Data());
1711 fprintf(file, "SettingsSaveOnExit=%d\n",
1712 fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit));
1715 Info("SaveSettings", "settings saved to file %s", fileName);
1720 //_____________________________________________________________________________
1721 Bool_t AliMonitorClient::GetBaseItem()
1723 // get the base item for looping over histograms
1726 // the base item is a folder
1727 fBaseItem = fCurrentItem;
1728 // if the current item is a histo, its parent is the base folder
1729 if (fBaseItem->GetParent() && fBaseItem->GetParent()->GetParent()) {
1730 fBaseItem = fBaseItem->GetParent();
1733 } else { // if no item is selected the All item is the base item
1734 fBaseItem = fAllItem;
1735 fCurrentItem = fBaseItem->GetFirstChild();
1736 if (!fCurrentItem) return kFALSE;
1742 //_____________________________________________________________________________
1743 Bool_t AliMonitorClient::GoToNextItem()
1745 // go to the next histogram in the loop
1747 if (!fCurrentItem) return kFALSE;
1748 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1750 // remember the start item to avoid an endless loop
1751 TGListTreeItem* startItem = fCurrentItem;
1754 // folder -> first child
1755 if (fCurrentItem->GetFirstChild()) {
1756 fCurrentItem = fCurrentItem->GetFirstChild();
1758 // histo -> next histo
1759 } else if ((fCurrentItem != fBaseItem) &&
1760 (fCurrentItem->GetNextSibling())) {
1761 fCurrentItem = fCurrentItem->GetNextSibling();
1763 // last histo in folder -> next folder
1764 } else if ((fCurrentItem != fBaseItem) &&
1765 (fCurrentItem->GetParent() != fBaseItem) &&
1766 fCurrentItem->GetParent()->GetNextSibling()) {
1767 fCurrentItem = fCurrentItem->GetParent()->GetNextSibling();
1769 // last histo in last folder -> first folder
1771 fCurrentItem = fBaseItem->GetFirstChild();
1774 // abort if no next item found
1775 if (fCurrentItem == startItem) return kFALSE;
1777 // end loop if an item with a monitor histo was found
1778 } while (!fCurrentItem->GetUserData());
1784 //_____________________________________________________________________________
1785 Bool_t AliMonitorClient::GoToPreviousItem()
1787 // go to the previous histogram in the loop
1789 if (!fCurrentItem) return kFALSE;
1790 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1792 // remember the start item to avoid an endless loop
1793 TGListTreeItem* startItem = fCurrentItem;
1796 // folder -> last child
1797 if (fCurrentItem->GetFirstChild()) {
1798 fCurrentItem = fCurrentItem->GetFirstChild();
1799 while (fCurrentItem->GetNextSibling()) {
1800 fCurrentItem = fCurrentItem->GetNextSibling();
1803 // histo -> previous histo
1804 } else if ((fCurrentItem != fBaseItem) &&
1805 (fCurrentItem->GetPrevSibling())) {
1806 fCurrentItem = fCurrentItem->GetPrevSibling();
1808 // first histo in folder -> previous folder
1809 } else if ((fCurrentItem != fBaseItem) &&
1810 (fCurrentItem->GetParent() != fBaseItem) &&
1811 fCurrentItem->GetParent()->GetPrevSibling()) {
1812 fCurrentItem = fCurrentItem->GetParent()->GetPrevSibling();
1814 // first histo in first folder -> last folder
1816 fCurrentItem = fBaseItem->GetFirstChild();
1817 while (fCurrentItem->GetNextSibling()) {
1818 fCurrentItem = fCurrentItem->GetNextSibling();
1822 // abort if no next item found
1823 if (fCurrentItem == startItem) return kFALSE;
1825 // end loop if an item with a monitor histo was found
1826 } while (!fCurrentItem->GetUserData());
1832 //_____________________________________________________________________________
1833 void AliMonitorClient::UpdateItem(Bool_t highlight)
1835 // update the displayed tree for currently selected item
1837 if (highlight) { // highlight the selected item and open its parent folders
1838 TGListTreeItem* parent = fCurrentItem->GetParent();
1840 if (!parent->IsOpen()) fTree->OpenItem(parent);
1841 parent = parent->GetParent();
1843 fTree->HighlightItem(fCurrentItem);
1844 gClient->NeedRedraw(fTree);
1847 // update displayed histo
1848 UpdateDescription();
1851 // en- or disable the "Reference/Take Current" menu item
1852 TGListTreeItem* base = fCurrentItem;
1853 while (base->GetParent()) base = base->GetParent();
1854 if (base != fComparisonItem) {
1855 fMenuReference->EnableEntry(kMenuRefTakeCurrent);
1857 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
1860 // en- or disable the "Favorites/Add" and "Favorites/Delete" menu items
1861 if (fCurrentItem->GetParent()) {
1862 if (base == fFavoritesItem) {
1863 fMenuFavorites->DisableEntry(kMenuFavAdd);
1864 fMenuFavorites->EnableEntry(kMenuFavDelete);
1866 fMenuFavorites->EnableEntry(kMenuFavAdd);
1867 fMenuFavorites->DisableEntry(kMenuFavDelete);
1870 fMenuFavorites->DisableEntry(kMenuFavAdd);
1871 fMenuFavorites->DisableEntry(kMenuFavDelete);
1876 //_____________________________________________________________________________
1877 Bool_t AliMonitorClient::CheckForNewData()
1879 // check whether the monitor process server sent new data
1881 // receive a message from the server
1882 if (!fSocket || !fSocket->IsValid()) return kFALSE;
1883 TMessage* message = NULL;
1884 Int_t result = fSocket->Recv(message);
1886 // replace the old folder of monitor histos with the new one
1888 if (fFolder) delete fFolder;
1889 fFolder = (TFolder*) message->ReadObject(message->GetClass());
1896 //_____________________________________________________________________________
1897 void AliMonitorClient::ClearItems(TGListTreeItem* base)
1899 // remove the references to the histograms from all subitems of the
1902 // loop over folders
1903 TGListTreeItem* folderItem = base->GetFirstChild();
1904 while (folderItem) {
1907 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1909 histoItem->SetUserData(NULL);
1910 histoItem = histoItem->GetNextSibling();
1913 folderItem = folderItem->GetNextSibling();
1917 //_____________________________________________________________________________
1918 void AliMonitorClient::CleanUpTree(TGListTreeItem* base)
1920 // remove items without monitor histograms and
1921 // folders without monitor histograms
1923 // loop over folders
1924 TGListTreeItem* folderItem = base->GetFirstChild();
1925 while (folderItem) {
1928 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1930 TGListTreeItem* deleteItem = NULL;
1931 if (!histoItem->GetUserData()) deleteItem = histoItem;
1932 histoItem = histoItem->GetNextSibling();
1933 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1934 if (deleteItem) fTree->DeleteItem(deleteItem);
1937 folderItem = folderItem->GetNextSibling();
1940 // loop over folders and remove empty folders
1941 folderItem = base->GetFirstChild();
1942 while (folderItem) {
1943 TGListTreeItem* deleteItem = NULL;
1944 if (!folderItem->GetFirstChild()) deleteItem = folderItem;
1945 folderItem = folderItem->GetNextSibling();
1946 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1947 if (deleteItem) fTree->DeleteItem(deleteItem);
1951 //_____________________________________________________________________________
1952 void AliMonitorClient::UpdateTree()
1954 // update the tree of monitor histograms
1956 // delete references to old monitor histograms
1957 ClearItems(fAllItem);
1960 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1961 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1964 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1965 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1967 // add new monitor histograms
1968 TGListTreeItem* histoItem = GetItem(fAllItem, folder->GetName(),
1969 histo->GetName(), kTRUE);
1970 histoItem->SetUserData(histo);
1977 // remove items and folders without monitor histograms
1978 CleanUpTree(fAllItem);
1980 gClient->NeedRedraw(fTree);
1983 //_____________________________________________________________________________
1984 void AliMonitorClient::UpdateFavoritesTree()
1986 // update the tree of favorite monitor histograms
1988 // loop over folders
1989 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1990 while (folderItem) {
1993 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1996 // set monitor histo
1997 histoItem->SetUserData(GetHisto(folderItem->GetText(),
1998 histoItem->GetText()));
1999 histoItem = histoItem->GetNextSibling();
2002 folderItem = folderItem->GetNextSibling();
2006 //_____________________________________________________________________________
2007 void AliMonitorClient::UpdateComparisonTree()
2009 // update the tree of monitor histograms with significant deviation
2010 // from the reference histograms
2012 if (!fFolder) return;
2014 // delete references to old monitor histograms
2015 ClearItems(fComparisonItem);
2017 // add monitor histograms where the comparison returns a deviation
2018 // loop over folders
2019 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
2020 while (TFolder* folder = (TFolder*) iFolder->Next()) {
2023 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
2024 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
2026 // compare the histo to its reference
2027 Bool_t comparison = kTRUE;
2028 if (fEventButton->IsDown()) {
2029 comparison = histo->CompareEvent(fEventNumber->GetIntNumber());
2030 } else if (fSumButton->IsDown()) {
2031 comparison = histo->CompareSum(fEventNumber->GetIntNumber());
2033 comparison = histo->CompareRun();
2036 // add it to the comparison tree in case of a bad comparison result
2038 TGListTreeItem* histoItem = GetItem(fComparisonItem, folder->GetName(),
2039 histo->GetName(), kTRUE);
2040 histoItem->SetUserData(histo);
2048 // remove items and folders without monitor histograms
2049 CleanUpTree(fComparisonItem);
2051 gClient->NeedRedraw(fTree);
2054 //_____________________________________________________________________________
2055 void AliMonitorClient::UpdateDescription()
2057 // update the description of the current monitor histogram
2059 fDescription->Clear();
2060 AliMonitorHisto* histo = NULL;
2061 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2062 if (histo) fDescription->LoadBuffer(histo->GetDescription().Data());
2064 gClient->NeedRedraw(fDescription);
2067 //_____________________________________________________________________________
2068 void AliMonitorClient::UpdateHisto()
2070 // update the current monitor histogram
2072 // clear the canvas if no histo is selected
2073 AliMonitorHisto* histo = NULL;
2074 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2076 fDrawCanvas->GetCanvas()->Clear();
2077 fDrawCanvas->GetCanvas()->Update();
2081 // draw the histo for a single event or summed over several events or a run
2082 fDrawCanvas->GetCanvas()->cd();
2083 if (fEventButton->IsDown()) {
2084 histo->DrawEvent(fEventNumber->GetIntNumber());
2085 } else if (fSumButton->IsDown()) {
2086 histo->DrawSum(fEventNumber->GetIntNumber());
2092 //_____________________________________________________________________________
2093 void AliMonitorClient::UpdateAll()
2095 // update the trees, the histogram and the description
2098 UpdateFavoritesTree();
2099 UpdateComparisonTree();
2100 UpdateDescription();