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 ///////////////////////////////////////////////////////////////////////////////
28 #include <TApplication.h>
36 #include <TGFileDialog.h>
38 #include <TGListTree.h>
41 #include <TGNumberEntry.h>
42 #include <TGSplitter.h>
43 #include <TGTextEntry.h>
44 #include <TGTextView.h>
45 #include <TGToolBar.h>
47 #include <TRootEmbeddedCanvas.h>
53 #include "AliMonitorClient.h"
54 #include "AliMonitorHisto.h"
55 #include "AliMonitorProcess.h"
57 ClassImp(AliMonitorClient)
60 const char* AliMonitorClient::fgSettingsFileName = ".AliMonitorClient";
63 //_____________________________________________________________________________
64 AliMonitorClient::AliMonitorStringDlg::AliMonitorStringDlg(TString& string,
68 AliMonitorDialog(main, 300, 80),
69 fStringLayout(new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2)),
70 fStringLabel(new TGLabel(fFrame, label)),
71 fStringEntry(new TGTextEntry(fFrame, string.Data())),
74 // create a dialog for connecting to a monitor process
76 fFrame->AddFrame(fStringLabel, fStringLayout);
77 fStringEntry->Resize(100, fStringEntry->GetDefaultHeight());
78 fFrame->AddFrame(fStringEntry, fStringLayout);
82 fMain->SetWindowName(title);
83 fMain->MapSubwindows();
85 gClient->WaitFor(fMain);
88 //_____________________________________________________________________________
89 AliMonitorClient::AliMonitorStringDlg::~AliMonitorStringDlg()
98 //_____________________________________________________________________________
99 void AliMonitorClient::AliMonitorStringDlg::OnOkClicked()
101 fString = fStringEntry->GetText();
105 //_____________________________________________________________________________
106 AliMonitorClient::AliMonitorNumberDlg::AliMonitorNumberDlg(Float_t& value,
111 AliMonitorDialog(main, 250, 80),
112 fNumberLayout(new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2)),
113 fNumberLabel(new TGLabel(fFrame, label)),
114 fNumberEntry(new TGNumberEntry(fFrame, value, 4, -1, TGNumberFormat::kNESRealOne)),
117 // create a dialog for getting a number
119 fFrame->AddFrame(fNumberLabel, fNumberLayout);
120 fNumberEntry->SetLimits(TGNumberFormat::kNELLimitMin, min, 0);
121 fFrame->AddFrame(fNumberEntry, fNumberLayout);
125 fMain->SetWindowName(title);
126 fMain->MapSubwindows();
128 gClient->WaitFor(fMain);
131 //_____________________________________________________________________________
132 AliMonitorClient::AliMonitorNumberDlg::~AliMonitorNumberDlg()
137 delete fNumberLayout;
141 //_____________________________________________________________________________
142 void AliMonitorClient::AliMonitorNumberDlg::OnOkClicked()
144 fNumber = fNumberEntry->GetNumber();
149 // constants for menu entries
150 enum {kMenuFileConnect, kMenuFileDisconnect, kMenuFileOpen, kMenuFileExit,
151 kMenuViewToolBar, kMenuViewTree, kMenuViewDescription,
152 kMenuViewReference, kMenuViewStatistics,
153 kMenuFavAdd, kMenuFavDelete,
154 kMenuFavLoad, kMenuFavSave, kMenuFavSaveAs, kMenuFavSaveOnExit,
155 kMenuRefLoad, kMenuRefThreshold,
156 kMenuRefTakeCurrent, kMenuRefSave, kMenuRefSaveAs,
157 kMenuOptLoop, kMenuOptPrint,
158 kMenuOptSave, kMenuOptSaveOnExit,
159 kMenuHelpDoc, kMenuHelpAbout
162 //_____________________________________________________________________________
163 AliMonitorClient::AliMonitorClient():
164 TGMainFrame(gClient->GetRoot(), 500, 300),
166 fMenuBarLayout(new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1)),
167 fMenuBarItemLayout(new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)),
168 fMenuBarHelpLayout(new TGLayoutHints(kLHintsTop | kLHintsRight)),
169 fMenuFile(new TGPopupMenu(gClient->GetRoot())),
170 fMenuView(new TGPopupMenu(gClient->GetRoot())),
171 fMenuFavorites(new TGPopupMenu(gClient->GetRoot())),
172 fMenuReference(new TGPopupMenu(gClient->GetRoot())),
173 fMenuOptions(new TGPopupMenu(gClient->GetRoot())),
174 fMenuHelp(new TGPopupMenu(gClient->GetRoot())),
175 fMenuBar(new TGMenuBar(this, 1, 1, kHorizontalFrame)),
176 fToolBarLayout(new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 2, 2)),
177 fToolBarSep(new TGHorizontal3DLine(this)),
178 fToolBar(new TGToolBar(this, 60, 20, kHorizontalFrame)),
179 fEventNumberLayout(new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 10, 2, 10, 5)),
180 fEventNumber(new TGNumberEntry(fToolBar, 1, 4, 10, TGNumberFormat::kNESInteger)),
185 fLoopOnPicture(NULL),
186 fLoopOffPicture(NULL),
187 fPreviousButton(NULL),
192 fBottomLayout(new TGLayoutHints(kLHintsExpandX | kLHintsBottom)),
193 fLeftLayout(new TGLayoutHints(kLHintsLeft | kLHintsExpandY)),
194 fExpandLayout(new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)),
195 fVerticalFrame(new TGVerticalFrame(this, 10, 10)),
196 fHorizontalFrame(new TGHorizontalFrame(fVerticalFrame, 10, 10)),
197 fTreeFrame(new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame | kFixedWidth)),
198 fTreeCanvas(new TGCanvas(fTreeFrame, 10, 10)),
199 fTree(new TGListTree(fTreeCanvas, kHorizontalFrame)),
200 fHistoPicture(fClient->GetPicture("h1_t.xpm")),
201 fAllItem(fTree->AddItem(NULL, "All")),
202 fFavoritesItem(fTree->AddItem(NULL, "Favorites")),
203 fComparisonItem(fTree->AddItem(NULL, "Comparison")),
204 fTreeSplitter(new TGVSplitter(fHorizontalFrame, 4)),
205 fDrawFrame(new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame)),
206 fDrawCanvas(new TRootEmbeddedCanvas("current monitor histogram", fDrawFrame, 10, 10)),
207 fDescriptionSplitter(new TGHSplitter(fVerticalFrame, 4, 4)),
208 fDescriptionFrame(new TGCompositeFrame(fVerticalFrame, 10, 60, kSunkenFrame | kFixedHeight)),
209 fDescription(new TGTextView(fDescriptionFrame, 10, 60, "")),
210 fServerName("localhost"),
212 fSocketHandler(NULL),
213 fFolder(CreateTopFolder()),
218 fFavoritesFileName(""),
219 fReferenceFileName(""),
220 fReference(CreateTopFolder()),
223 // initialize the monitoring client window
226 fMenuFile->AddEntry("&Connect...", kMenuFileConnect);
227 fMenuFile->AddEntry("&Disconnect...", kMenuFileDisconnect);
228 fMenuFile->HideEntry(kMenuFileDisconnect);
229 fMenuFile->AddEntry("&Open...", kMenuFileOpen);
230 fMenuFile->AddSeparator();
231 fMenuFile->AddEntry("E&xit", kMenuFileExit);
232 fMenuFile->Connect("Activated(Int_t)", "AliMonitorClient", this,
233 "OnMenuActivated(Int_t)");
236 fMenuView->AddEntry("Tool&bar", kMenuViewToolBar);
237 fMenuView->CheckEntry(kMenuViewToolBar);
238 fMenuView->AddEntry("&Tree", kMenuViewTree);
239 fMenuView->CheckEntry(kMenuViewTree);
240 fMenuView->AddEntry("&Description", kMenuViewDescription);
241 fMenuView->CheckEntry(kMenuViewDescription);
242 fMenuView->AddSeparator();
243 fMenuView->AddEntry("&Reference", kMenuViewReference);
244 fMenuView->CheckEntry(kMenuViewReference);
245 AliMonitorHisto::SetDrawRef(kTRUE);
246 fMenuView->AddEntry("&Statistics", kMenuViewStatistics);
247 fMenuView->CheckEntry(kMenuViewStatistics);
248 gStyle->SetOptStat(1110);
249 fMenuView->Connect("Activated(Int_t)", "AliMonitorClient", this,
250 "OnMenuActivated(Int_t)");
253 fMenuFavorites->AddEntry("&Add", kMenuFavAdd);
254 fMenuFavorites->DisableEntry(kMenuFavAdd);
255 fMenuFavorites->AddEntry("&Delete", kMenuFavDelete);
256 fMenuFavorites->DisableEntry(kMenuFavDelete);
257 fMenuFavorites->AddSeparator();
258 fMenuFavorites->AddEntry("&Load...", kMenuFavLoad);
259 fMenuFavorites->AddEntry("&Save", kMenuFavSave);
260 fMenuFavorites->DisableEntry(kMenuFavSave);
261 fMenuFavorites->AddEntry("&Save As...", kMenuFavSaveAs);
262 fMenuFavorites->DisableEntry(kMenuFavSaveAs);
263 fMenuFavorites->AddEntry("Save On &Exit", kMenuFavSaveOnExit);
264 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
265 fMenuFavorites->Connect("Activated(Int_t)", "AliMonitorClient", this,
266 "OnMenuActivated(Int_t)");
269 fMenuReference->AddEntry("&Load...", kMenuRefLoad);
270 fMenuReference->AddEntry("&Threshold...", kMenuRefThreshold);
271 fMenuReference->AddSeparator();
272 fMenuReference->AddEntry("Take &Current", kMenuRefTakeCurrent);
273 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
274 fMenuReference->AddEntry("&Save", kMenuRefSave);
275 fMenuReference->DisableEntry(kMenuRefSave);
276 fMenuReference->AddEntry("Save &As...", kMenuRefSaveAs);
277 fMenuReference->DisableEntry(kMenuRefSaveAs);
278 fMenuReference->Connect("Activated(Int_t)", "AliMonitorClient", this,
279 "OnMenuActivated(Int_t)");
282 fMenuOptions->AddEntry("&Loop Interval...", kMenuOptLoop);
283 fMenuOptions->AddEntry("&Print Command...", kMenuOptPrint);
284 fMenuOptions->AddSeparator();
285 fMenuOptions->AddEntry("&Save Settings", kMenuOptSave);
286 fMenuOptions->AddEntry("Save Settings on &Exit", kMenuOptSaveOnExit);
287 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
288 fMenuOptions->Connect("Activated(Int_t)", "AliMonitorClient", this,
289 "OnMenuActivated(Int_t)");
292 fMenuHelp->AddEntry("&Documentation...", kMenuHelpDoc);
293 fMenuHelp->AddEntry("A&bout...", kMenuHelpAbout);
294 fMenuHelp->Connect("Activated(Int_t)", "AliMonitorClient", this,
295 "OnMenuActivated(Int_t)");
298 fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
299 fMenuBar->AddPopup("&View", fMenuView, fMenuBarItemLayout);
300 fMenuBar->AddPopup("F&avorites", fMenuFavorites, fMenuBarItemLayout);
301 fMenuBar->AddPopup("&Reference", fMenuReference, fMenuBarItemLayout);
302 fMenuBar->AddPopup("&Options", fMenuOptions, fMenuBarItemLayout);
303 fMenuBar->AddPopup("&Help", fMenuHelp, fMenuBarHelpLayout);
305 AddFrame(fMenuBar, fMenuBarLayout);
309 AddFrame(fToolBarSep, fToolBarLayout);
310 AddFrame(fToolBar, fToolBarLayout);
312 // event number field
313 fEventNumber->SetLimits(TGNumberFormat::kNELLimitMin, 1, 0);
314 fToolBar->AddFrame(fEventNumber, fEventNumberLayout);
315 fEventNumber->GetNumberEntry()->Connect("ReturnPressed()",
316 "AliMonitorClient", this,
317 "OnEventNumberChanged()");
318 fEventNumber->GetButtonUp()->Connect("Clicked()",
319 "AliMonitorClient", this,
320 "OnEventNumberChanged()");
321 fEventNumber->GetButtonDown()->Connect("Clicked()",
322 "AliMonitorClient", this,
323 "OnEventNumberChanged()");
326 ToolBarData_t eventButton = {"h1_s.xpm", "draw event histogram",
328 fToolBar->AddButton(this, &eventButton, 5);
329 fEventButton = eventButton.fButton;
330 fEventButton->Connect("Pressed()", "AliMonitorClient", this,
331 "OnEventButtonPressed()");
334 ToolBarData_t sumButton = {"h2_s.xpm", "draw sum histogram",
336 fToolBar->AddButton(this, &sumButton, 5);
337 fSumButton = sumButton.fButton;
338 fSumButton->Connect("Pressed()", "AliMonitorClient", this,
339 "OnSumButtonPressed()");
342 ToolBarData_t runButton = {"h3_s.xpm", "draw run histogram",
344 fToolBar->AddButton(this, &runButton, 5);
345 fRunButton = runButton.fButton;
346 fRunButton->SetDown(kTRUE);
347 fRunButton->Connect("Pressed()", "AliMonitorClient", this,
348 "OnRunButtonPressed()");
352 sprintf(fileName, "%s/MONITOR/loop_on.xpm", gSystem->Getenv("ALICE_ROOT"));
353 ToolBarData_t loopButton = {fileName, "loop over histograms",
355 fToolBar->AddButton(this, &loopButton, 25);
356 fLoopButton = loopButton.fButton;
357 fLoopButton->Connect("Clicked()", "AliMonitorClient", this,
358 "OnLoopButtonClicked()");
359 fLoopOnPicture = gClient->GetPicture(fileName);
360 sprintf(fileName, "%s/MONITOR/loop_off2.xpm", gSystem->Getenv("ALICE_ROOT"));
361 fLoopOffPicture = gClient->GetPicture(fileName);
364 sprintf(fileName, "%s/MONITOR/previous_s.xpm",
365 gSystem->Getenv("ALICE_ROOT"));
366 ToolBarData_t previousButton = {fileName, "go to previous histogram",
368 fToolBar->AddButton(this, &previousButton, 5);
369 fPreviousButton = previousButton.fButton;
370 fPreviousButton->Connect("Clicked()", "AliMonitorClient", this,
371 "OnPreviousButtonClicked()");
374 sprintf(fileName, "%s/MONITOR/next_s.xpm", gSystem->Getenv("ALICE_ROOT"));
375 ToolBarData_t nextButton = {fileName, "go to next histogram",
377 fToolBar->AddButton(this, &nextButton, 5);
378 fNextButton = nextButton.fButton;
379 fNextButton->Connect("Clicked()", "AliMonitorClient", this,
380 "OnNextButtonClicked()");
383 sprintf(fileName, "%s/MONITOR/copy_s.xpm", gSystem->Getenv("ALICE_ROOT"));
384 ToolBarData_t copyButton = {fileName,
385 "copy the current histogram to a new canvas",
387 fToolBar->AddButton(this, ©Button, 25);
388 fCopyButton = copyButton.fButton;
389 fCopyButton->Connect("Clicked()", "AliMonitorClient", this,
390 "OnCopyButtonClicked()");
393 sprintf(fileName, "%s/MONITOR/save_s.xpm", gSystem->Getenv("ALICE_ROOT"));
394 ToolBarData_t saveButton = {fileName, "save the current histogram",
396 fToolBar->AddButton(this, &saveButton, 5);
397 fSaveButton = saveButton.fButton;
398 fSaveButton->Connect("Clicked()", "AliMonitorClient", this,
399 "OnSaveButtonClicked()");
402 ToolBarData_t printButton = {"printer_s.xpm", "print the current histogram",
404 fToolBar->AddButton(this, &printButton, 5);
405 fPrintButton = printButton.fButton;
406 fPrintButton->Connect("Clicked()", "AliMonitorClient", this,
407 "OnPrintButtonClicked()");
410 AddFrame(fVerticalFrame, fExpandLayout);
412 fVerticalFrame->AddFrame(fHorizontalFrame, fExpandLayout);
415 fHorizontalFrame->AddFrame(fTreeFrame, fLeftLayout);
416 fTreeFrame->AddFrame(fTreeCanvas, fExpandLayout);
417 fTreeCanvas->AddFrame(fTree, fExpandLayout);
418 fTree->Connect("Clicked(TGListTreeItem*,Int_t)", "AliMonitorClient",
419 this, "OnTreeClicked(TGListTreeItem*,Int_t)");
420 fTree->Connect("ReturnPressed(TGListTreeItem*)", "AliMonitorClient",
421 this, "OnTreeReturnPressed(TGListTreeItem*)");
424 fTreeFrame->Resize(100, fTreeFrame->GetDefaultHeight());
426 // tree / histogram splitter
427 fTreeSplitter->SetFrame(fTreeFrame, kTRUE);
428 fHorizontalFrame->AddFrame(fTreeSplitter, fLeftLayout);
431 fHorizontalFrame->AddFrame(fDrawFrame, fExpandLayout);
432 fDrawFrame->AddFrame(fDrawCanvas, fExpandLayout);
435 fVerticalFrame->AddFrame(fDescriptionFrame, fBottomLayout);
436 fDescriptionFrame->AddFrame(fDescription, fExpandLayout);
438 // histogram / description splitter
439 fVerticalFrame->AddFrame(fDescriptionSplitter, fBottomLayout);
440 fDescriptionSplitter->SetFrame(fDescriptionFrame, kFALSE);
443 Connect("CloseWindow()", "AliMonitorClient", this, "CloseWindow()");
444 SetWindowName("Monitor Client");
445 SetWMSize(GetWidth(), GetHeight());
447 SetWMPosition(100, 100);
453 // default data members
455 fFolder = CreateTopFolder();
457 fReference = CreateTopFolder();
458 AliMonitorHisto::SetThreshold(5.0);
460 // load saved settings
464 //_____________________________________________________________________________
465 AliMonitorClient::~AliMonitorClient()
469 delete fMenuBarLayout;
470 delete fMenuBarItemLayout;
471 delete fMenuBarHelpLayout;
474 delete fMenuFavorites;
475 delete fMenuReference;
480 delete fEventNumberLayout;
482 delete fToolBarLayout;
486 delete fBottomLayout;
488 delete fExpandLayout;
493 delete fTreeSplitter;
498 delete fDescriptionSplitter;
500 delete fDescriptionFrame;
502 delete fVerticalFrame;
503 delete fHorizontalFrame;
506 fSocketHandler->Remove();
507 fSocket->Send("disconnect");
510 delete fSocketHandler;
513 if (fFolder) delete fFolder;
516 fLoopTimer->TurnOff();
520 if (fReference) delete fReference;
524 //_____________________________________________________________________________
525 void AliMonitorClient::CloseWindow()
527 // terminate the application when the window is closed
529 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
532 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
536 fSocketHandler->Remove();
537 fSocket->Send("disconnect");
541 delete fSocketHandler;
542 fSocketHandler = NULL;
545 gApplication->Terminate(0);
549 //_____________________________________________________________________________
550 void AliMonitorClient::OnNewData()
552 // called when data has arrived from the monitor server
554 if (CheckForNewData()) UpdateAll();
558 //_____________________________________________________________________________
559 void AliMonitorClient::OnMenuActivated(Int_t id)
561 // called when a menu item was selected
565 case kMenuFileConnect: {
566 if (ConnectToServer()) UpdateAll();
570 case kMenuFileDisconnect: {
571 DisconnectFromServer();
575 case kMenuFileOpen: {
576 if (OpenFile()) UpdateAll();
580 case kMenuFileExit: {
585 case kMenuViewToolBar: {
586 ViewToolBar(!fMenuView->IsEntryChecked(kMenuViewToolBar));
590 case kMenuViewTree: {
591 ViewTree(!fMenuView->IsEntryChecked(kMenuViewTree));
595 case kMenuViewDescription: {
596 ViewDescription(!fMenuView->IsEntryChecked(kMenuViewDescription));
600 case kMenuViewReference: {
601 ViewReference(!fMenuView->IsEntryChecked(kMenuViewReference));
606 case kMenuViewStatistics: {
607 ViewStatistics(!fMenuView->IsEntryChecked(kMenuViewStatistics));
614 fMenuFavorites->EnableEntry(kMenuFavSave);
615 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
620 case kMenuFavDelete: {
621 if (DeleteFavorite()) {
624 fMenuFavorites->DisableEntry(kMenuFavDelete);
625 fMenuFavorites->EnableEntry(kMenuFavSave);
626 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
632 if (LoadFavorites()) {
635 fMenuFavorites->DisableEntry(kMenuFavSave);
636 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
642 if (SaveFavorites()) {
643 fMenuFavorites->DisableEntry(kMenuFavSave);
648 case kMenuFavSaveAs: {
649 if (SaveFavoritesAs()) {
650 fMenuFavorites->DisableEntry(kMenuFavSave);
655 case kMenuFavSaveOnExit: {
656 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
657 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
659 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
665 if (LoadReference()) {
668 UpdateComparisonTree();
669 fMenuReference->EnableEntry(kMenuRefSaveAs);
674 case kMenuRefThreshold: {
675 Float_t threshold = AliMonitorHisto::GetThreshold();
676 new AliMonitorNumberDlg(threshold, this,
677 "Comparison with Reference Histograms",
678 "threshold for comparison:", 0.);
679 if (threshold < 0) break;
681 AliMonitorHisto::SetThreshold(threshold);
683 UpdateComparisonTree();
687 case kMenuRefTakeCurrent: {
688 if (TakeCurrentReference()) {
690 UpdateComparisonTree();
691 fMenuReference->EnableEntry(kMenuRefSave);
692 fMenuReference->EnableEntry(kMenuRefSaveAs);
698 if (SaveReference()) {
699 fMenuReference->DisableEntry(kMenuRefSave);
704 case kMenuRefSaveAs: {
705 if (SaveReferenceAs()) {
706 fMenuReference->DisableEntry(kMenuRefSave);
712 Float_t interval = fLoopInterval * 0.001;
713 new AliMonitorNumberDlg(interval, this, "Loop Interval",
714 "loop time in seconds:", 0.1);
715 if (interval < 0) break;
717 fLoopInterval = Int_t(1000 * interval);
720 fLoopTimer->Start(fLoopInterval);
725 case kMenuOptPrint: {
726 TString printCommand(fPrintCommand);
727 new AliMonitorStringDlg(printCommand, this, "Print Command",
728 "shell command for printing:");
729 if (printCommand.IsNull()) break;
731 fPrintCommand = printCommand;
735 case kMenuOptSaveOnExit: {
736 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
737 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
739 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
749 case kMenuHelpAbout: {
751 new TGMsgBox(gClient->GetRoot(), this,
752 "About", "AliMonitorClient $Revision$",
753 kMBIconAsterisk, kMBOk, &result);
759 new TGMsgBox(gClient->GetRoot(), this,
760 "AliMonitorClient", "not yet implemented",
761 kMBIconExclamation, kMBOk, &result);
767 //_____________________________________________________________________________
768 void AliMonitorClient::OnEventNumberChanged()
770 // called when the event number in the tool button was changed
772 if (!fRunButton->IsDown()) {
774 UpdateComparisonTree();
778 //_____________________________________________________________________________
779 void AliMonitorClient::OnEventButtonPressed()
781 // called when the event tool button was clicked
783 fSumButton->SetDown(kFALSE);
784 fRunButton->SetDown(kFALSE);
786 UpdateComparisonTree();
789 //_____________________________________________________________________________
790 void AliMonitorClient::OnSumButtonPressed()
792 // called when the sum tool button was clicked
794 fEventButton->SetDown(kFALSE);
795 fRunButton->SetDown(kFALSE);
797 UpdateComparisonTree();
800 //_____________________________________________________________________________
801 void AliMonitorClient::OnRunButtonPressed()
803 // called when the run tool button was clicked
805 fEventButton->SetDown(kFALSE);
806 fSumButton->SetDown(kFALSE);
808 UpdateComparisonTree();
811 //_____________________________________________________________________________
812 void AliMonitorClient::OnLoopButtonClicked()
814 // called when the loop tool button was clicked
816 // if loop is not running, start the loop timer and
817 // set the stop loop button picture
820 if (!GetBaseItem()) return;
822 fLoopTimer = new TTimer(fLoopInterval);
823 fLoopTimer->Connect("Timeout()", "AliMonitorClient", this,
825 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOffPicture);
826 fLoopTimer->TurnOn();
828 // if the loop is running, stop it
834 //_____________________________________________________________________________
835 void AliMonitorClient::OnPreviousButtonClicked()
837 // called when the previous tool button was clicked
840 if (!GetBaseItem()) return;
846 //_____________________________________________________________________________
847 void AliMonitorClient::OnNextButtonClicked()
849 // called when the next tool button was clicked
852 if (!GetBaseItem()) return;
858 //_____________________________________________________________________________
859 void AliMonitorClient::OnCopyButtonClicked()
861 // called when the copy tool button was clicked
863 fDrawCanvas->GetCanvas()->DrawClone();
866 //_____________________________________________________________________________
867 void AliMonitorClient::OnSaveButtonClicked()
869 // called when the save tool button was clicked
871 // display a file save dialog
872 static TGFileInfo fileInfo;
873 static const char* fileTypes[] = {"PostScript", "*.ps",
874 "Encapsulated PostScript", "*.eps",
876 "Gif files", "*.gif",
877 "Macro files", "*.C",
878 "ROOT files", "*.root",
881 fileInfo.fFileTypes = fileTypes;
882 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
883 if (!fileInfo.fFilename) return;
885 fDrawCanvas->GetCanvas()->SaveAs(fileInfo.fFilename);
888 //_____________________________________________________________________________
889 void AliMonitorClient::OnPrintButtonClicked()
891 // called when the print tool button was clicked
893 // save the canvas to a temporary postscript file
894 char fileName[L_tmpnam+4];
895 sprintf(fileName, "%s.ps", tmpnam(NULL));
896 fDrawCanvas->GetCanvas()->SaveAs(fileName);
898 // call the print command and delete the temporary file
900 sprintf(command, "%s %s", fPrintCommand.Data(), fileName);
901 gSystem->Exec(command);
902 gSystem->Unlink(fileName);
906 //_____________________________________________________________________________
907 void AliMonitorClient::OnTreeClicked(TGListTreeItem* item, Int_t)
909 // called when an item in the histogram tree is clicked
911 OnTreeReturnPressed(item);
914 //_____________________________________________________________________________
915 void AliMonitorClient::OnTreeReturnPressed(TGListTreeItem* item)
917 // called when return is pressed at an item in the histogram tree
926 //_____________________________________________________________________________
927 void AliMonitorClient::OnLoopTimer()
929 // called by the loop timer when a new histogram should be displayed
932 if (!GetBaseItem()) return;
938 //_____________________________________________________________________________
939 TFolder* AliMonitorClient::CreateTopFolder() const
941 // create a top folder for monitor histograms
943 return (new TFolder("Monitor", "monitor histograms"));
946 //_____________________________________________________________________________
947 AliMonitorHisto* AliMonitorClient::GetHisto(const char* folderName,
948 const char* histoName)
950 // find the monitor histogram with the given name in the given folder
952 TGListTreeItem* folderItem = fTree->FindChildByName(fAllItem, folderName);
954 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
955 if (histoItem) return (AliMonitorHisto*) histoItem->GetUserData();
960 //_____________________________________________________________________________
961 TGListTreeItem* AliMonitorClient::GetItem(TGListTreeItem* base,
962 const char* folderName,
963 const char* histoName,
966 // find the tree item with given name in the given folder
967 // if create is kTRUE it is created if it is not there
969 // get or create the folder
970 TGListTreeItem* folderItem = fTree->FindChildByName(base, folderName);
972 if (!create) return NULL;
973 folderItem = fTree->AddItem(base, folderName);
976 // get or create the histo
977 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
979 if (!create) return NULL;
980 histoItem = fTree->AddItem(folderItem, histoName,
981 fClient->GetPicture("h1_t.xpm"),
982 fClient->GetPicture("h1_t.xpm"));
988 //_____________________________________________________________________________
989 Bool_t AliMonitorClient::ConnectToServer()
991 // display the dialog for the server name or ip and try to connect to it
993 TString serverName(fServerName);
996 // ask for the server name or ip
997 new AliMonitorStringDlg(serverName, this, "Connection to monitor process",
998 "monitor server name or ip:");
999 if (serverName.IsNull()) return kFALSE;
1001 // connect to the server
1002 fSocket = new TSocket(serverName, AliMonitorProcess::GetPort());
1003 if (!fSocket || !fSocket->IsValid() || (fSocket->Send("client") <= 0)) {
1004 if (fSocket) delete fSocket;
1007 new TGMsgBox(gClient->GetRoot(), this, "Connect",
1008 "connection to monitor server failed",
1009 kMBIconExclamation, kMBOk, &result);
1011 } else { // set up a handler for notifying when new data is there
1012 fServerName = serverName;
1013 fSocketHandler = new TFileHandler(fSocket->GetDescriptor(),
1014 TFileHandler::kRead);
1015 fSocketHandler->Connect("Notified()", "AliMonitorClient", this,
1017 fSocketHandler->Add();
1018 TInetAddress adr = fSocket->GetInetAddress();
1019 AliInfo(Form("connected to server: %s (%s), port %d",
1020 adr.GetHostName(), adr.GetHostAddress(), adr.GetPort()));
1021 fMenuFile->HideEntry(kMenuFileConnect);
1022 fMenuFile->HideEntry(kMenuFileOpen);
1023 fMenuFile->EnableEntry(kMenuFileDisconnect);
1028 // delete the old monitor histos
1029 if (fFolder) delete fFolder;
1030 fFolder = CreateTopFolder();
1034 //_____________________________________________________________________________
1035 void AliMonitorClient::DisconnectFromServer()
1037 // disconnect from the monitor server
1039 // are-you-really-sure-dialog
1041 new TGMsgBox(gClient->GetRoot(), this, "Disconnect",
1042 "Do you really want to disconnect from the monitor server?",
1043 kMBIconQuestion, kMBYes | kMBNo, &result);
1044 if (result == kMBNo) return;
1046 // disconnect from the server
1047 fSocketHandler->Remove();
1048 fSocket->Send("disconnect");
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 AliInfo(Form("favorites saved to file %s", fFavoritesFileName.Data()));
1349 //_____________________________________________________________________________
1350 Bool_t AliMonitorClient::SaveFavoritesAs()
1352 // ask for a file name and save the favorites to this file
1354 // display a save file dialog
1355 TGFileInfo fileInfo;
1356 static const char* fileTypes[] = {"Favorites files", "*.fav",
1359 fileInfo.fFileTypes = fileTypes;
1360 fileInfo.fIniDir = StrDup(".");
1361 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1362 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1363 if (!fileInfo.fFilename) return kFALSE;
1365 // save the favorites
1366 fFavoritesFileName = fileInfo.fFilename;
1367 return SaveFavorites();
1371 //_____________________________________________________________________________
1372 Bool_t AliMonitorClient::LoadReference(Bool_t dialog)
1374 // load reference histograms from a file
1376 // display a file open dialog
1377 TGFileInfo fileInfo;
1378 static const char* fileTypes[] = {"ROOT files", "*.root",
1381 fileInfo.fFileTypes = fileTypes;
1382 fileInfo.fIniDir = StrDup(".");
1383 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1385 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1386 if (!fileInfo.fFilename) return kFALSE;
1389 // open the root file
1390 TFile* file = TFile::Open(fileInfo.fFilename);
1391 if (!file || !file->IsOpen()) {
1393 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1394 "The file could not be opened.",
1395 kMBIconExclamation, kMBOk, &result);
1399 // get the folder with the monitor histograms
1400 TFolder* folder = (TFolder*) file->Get("Monitor");
1401 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1403 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1404 "The file does not contain monitor histograms.",
1405 kMBIconExclamation, kMBOk, &result);
1411 // replace the old reference folder with the new one
1412 fReferenceFileName = fileInfo.fFilename;
1416 if (fReference) delete fReference;
1417 fReference = folder;
1421 //_____________________________________________________________________________
1422 void AliMonitorClient::SetReference()
1424 // set the reference histograms for all monitor histograms
1427 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1428 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1429 TFolder* refFolder = (TFolder*) fReference->FindObject(folder->GetName());
1430 if (!refFolder) continue;
1433 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1434 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1435 AliMonitorHisto* refHisto =
1436 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1437 if (!refHisto) continue;
1438 histo->SetReference(refHisto);
1446 //_____________________________________________________________________________
1447 Bool_t AliMonitorClient::TakeCurrentReference()
1449 // take the current monitor histogram or folder as reference
1451 // check that a histo or folder is selected
1452 if (!fCurrentItem) return kFALSE;
1453 AliMonitorHisto* histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
1454 if (!histo && !fCurrentItem->GetFirstChild()) return kFALSE;
1459 sprintf(message, "Do you want to take the current histogram %s/%s "
1460 "as reference histogram?", fCurrentItem->GetParent()->GetText(),
1463 sprintf(message, "Do you want to take all current histogram of the "
1464 "folder %s as reference histogram?", fCurrentItem->GetText());
1467 new TGMsgBox(gClient->GetRoot(), this, "Take Current as Reference",
1468 message, kMBIconQuestion, kMBYes | kMBNo, &result);
1469 if (result != kMBYes) return kFALSE;
1472 if (histo) { // ... a histo
1473 TakeReferenceHisto(fCurrentItem->GetParent()->GetText(), histo);
1474 } else if (fCurrentItem->GetParent()) { // ... a folder
1475 TakeReferenceFolder(fCurrentItem);
1476 } else { // ... a top folder
1477 TGListTreeItem* folderItem = fCurrentItem->GetFirstChild();
1478 while (folderItem) {
1479 TakeReferenceFolder(folderItem);
1480 folderItem = folderItem->GetNextSibling();
1486 //_____________________________________________________________________________
1487 void AliMonitorClient::TakeReferenceHisto(const char* folderName,
1488 AliMonitorHisto* histo)
1490 // take the given monitor histogram as reference histogram
1492 // get or create the reference folder
1493 TFolder* refFolder = (TFolder*) fReference->FindObject(folderName);
1494 if (!refFolder) refFolder = fReference->AddFolder(folderName, folderName);
1496 // delete the old reference histo
1497 AliMonitorHisto* refHisto =
1498 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1500 refFolder->Remove(refHisto);
1504 // add the new one and use it as reference
1505 refFolder->Add(new AliMonitorHisto(*histo));
1506 histo->SetReference(histo);
1509 //_____________________________________________________________________________
1510 void AliMonitorClient::TakeReferenceFolder(TGListTreeItem* item)
1512 // take all monitor histogram in the given folder as reference histograms
1515 TGListTreeItem* histoItem = item->GetFirstChild();
1517 AliMonitorHisto* histo = (AliMonitorHisto*) histoItem->GetUserData();
1518 if (histo) TakeReferenceHisto(item->GetText(), histo);
1519 histoItem = histoItem->GetNextSibling();
1523 //_____________________________________________________________________________
1524 Bool_t AliMonitorClient::SaveReference()
1526 // save the reference histograms to the file with name fReferenceFileName
1528 // if no file name is given use a default one
1529 if (fFavoritesFileName.IsNull()) {
1530 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1531 "AliMonitorClientRef.root");
1532 fFavoritesFileName = fileName;
1536 // open the root file
1537 TFile* file = TFile::Open(fReferenceFileName, "RECREATE");
1538 if (!file || !file->IsOpen()) {
1540 new TGMsgBox(gClient->GetRoot(), this, "Save Reference",
1541 "The file could not be opened.",
1542 kMBIconExclamation, kMBOk, &result);
1543 if (file) delete file;
1547 // write the reference folder
1548 fReference->Write();
1551 AliInfo(Form("reference histograms saved to file %s",
1552 fReferenceFileName.Data()));
1556 //_____________________________________________________________________________
1557 Bool_t AliMonitorClient::SaveReferenceAs()
1559 // ask for a file name and save the reference histograms to this file
1561 // display a save file dialog
1562 TGFileInfo fileInfo;
1563 static const char* fileTypes[] = {"ROOT files", "*.root",
1566 fileInfo.fFileTypes = fileTypes;
1567 fileInfo.fIniDir = StrDup(".");
1568 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1569 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1570 if (!fileInfo.fFilename) return kFALSE;
1572 // save the references
1573 fReferenceFileName = fileInfo.fFilename;
1574 return SaveReference();
1578 //_____________________________________________________________________________
1579 void AliMonitorClient::StopLoop()
1581 // stop looping over histograms
1583 // stop the timer and reset the loop button picture
1585 fLoopTimer->TurnOff();
1588 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOnPicture);
1592 //_____________________________________________________________________________
1593 void AliMonitorClient::LoadSettings()
1595 // load setting from the file with the name fgSettingFileName and apply them
1597 // open the text file
1598 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1599 fgSettingsFileName);
1600 FILE* file = fopen(fileName, "rt");
1606 // scan the text file and apply the settings
1608 while (!feof(file)) {
1609 if (fgets(buffer, 255, file) == NULL) break;
1610 char* token = strtok(buffer, "=");
1611 char* value = strtok(NULL, "\n");
1612 if (!token || !value) continue;
1613 if (value[strlen(value)-1] == '\n') value[strlen(value)-1] = 0;
1615 if (strcmp(token, "ServerName") == 0) {
1616 fServerName = value;
1618 } else if (strcmp(token, "ViewToolBar") == 0) {
1619 ViewToolBar(strcmp(value, "0") != 0);
1620 } else if (strcmp(token, "ViewTree") == 0) {
1621 ViewTree(strcmp(value, "0") != 0);
1622 } else if (strcmp(token, "ViewDescription") == 0) {
1623 ViewDescription(strcmp(value, "0") != 0);
1624 } else if (strcmp(token, "ViewReference") == 0) {
1625 ViewReference(strcmp(value, "0") != 0);
1626 } else if (strcmp(token, "ViewStatistics") == 0) {
1627 ViewStatistics(strcmp(value, "0") != 0);
1629 } else if (strcmp(token, "FavoritesFileName") == 0) {
1630 fFavoritesFileName = value;
1631 LoadFavorites(kFALSE);
1632 } else if (strcmp(token, "FavoritesSaveOnExit") == 0) {
1633 if (strcmp(value, "0") != 0) {
1634 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
1636 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
1639 } else if (strcmp(token, "ReferenceFileName") == 0) {
1640 fReferenceFileName = value;
1641 LoadReference(kFALSE);
1642 } else if (strcmp(token, "ReferenceThreshold") == 0) {
1643 AliMonitorHisto::SetThreshold(atof(value));
1645 } else if (strcmp(token, "LoopInterval") == 0) {
1646 fLoopInterval = atoi(value);
1647 } else if (strcmp(token, "PrintCommand") == 0) {
1648 fPrintCommand = value;
1649 } else if (strcmp(token, "SettingsSaveOnExit") == 0) {
1650 if (strcmp(value, "0") != 0) {
1651 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
1653 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
1659 AliDebug(1, Form("settings from file %s applied", fileName));
1663 //_____________________________________________________________________________
1664 void AliMonitorClient::SaveSettings()
1666 // save setting to the file with the name fgSettingFileName
1668 // open the text file
1669 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1670 fgSettingsFileName);
1671 FILE* file = fopen(fileName, "wt");
1674 new TGMsgBox(gClient->GetRoot(), this, "Save Settings",
1675 "The file could not be opened.",
1676 kMBIconExclamation, kMBOk, &result);
1681 // write the settings
1682 fprintf(file, "ServerName=%s\n", fServerName.Data());
1684 fprintf(file, "ViewToolBar=%d\n",
1685 fMenuView->IsEntryChecked(kMenuViewToolBar));
1686 fprintf(file, "ViewTree=%d\n",
1687 fMenuView->IsEntryChecked(kMenuViewTree));
1688 fprintf(file, "ViewDescription=%d\n",
1689 fMenuView->IsEntryChecked(kMenuViewDescription));
1690 fprintf(file, "ViewReference=%d\n",
1691 fMenuView->IsEntryChecked(kMenuViewReference));
1692 fprintf(file, "ViewStatistics=%d\n",
1693 fMenuView->IsEntryChecked(kMenuViewStatistics));
1695 if (!fFavoritesFileName.IsNull()) {
1696 fprintf(file, "FavoritesFileName=%s\n", fFavoritesFileName.Data());
1698 fprintf(file, "FavoritesSaveOnExit=%d\n",
1699 fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit));
1701 if (!fReferenceFileName.IsNull()) {
1702 fprintf(file, "ReferenceFileName=%s\n", fReferenceFileName.Data());
1704 fprintf(file, "ReferenceThreshold=%.1f\n", AliMonitorHisto::GetThreshold());
1706 fprintf(file, "LoopInterval=%d\n", fLoopInterval);
1707 fprintf(file, "PrintCommand=%s\n", fPrintCommand.Data());
1708 fprintf(file, "SettingsSaveOnExit=%d\n",
1709 fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit));
1712 AliInfo(Form("settings saved to file %s", fileName));
1717 //_____________________________________________________________________________
1718 Bool_t AliMonitorClient::GetBaseItem()
1720 // get the base item for looping over histograms
1723 // the base item is a folder
1724 fBaseItem = fCurrentItem;
1725 // if the current item is a histo, its parent is the base folder
1726 if (fBaseItem->GetParent() && fBaseItem->GetParent()->GetParent()) {
1727 fBaseItem = fBaseItem->GetParent();
1730 } else { // if no item is selected the All item is the base item
1731 fBaseItem = fAllItem;
1732 fCurrentItem = fBaseItem->GetFirstChild();
1733 if (!fCurrentItem) return kFALSE;
1739 //_____________________________________________________________________________
1740 Bool_t AliMonitorClient::GoToNextItem()
1742 // go to the next histogram in the loop
1744 if (!fCurrentItem) return kFALSE;
1745 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1747 // remember the start item to avoid an endless loop
1748 TGListTreeItem* startItem = fCurrentItem;
1751 // folder -> first child
1752 if (fCurrentItem->GetFirstChild()) {
1753 fCurrentItem = fCurrentItem->GetFirstChild();
1755 // histo -> next histo
1756 } else if ((fCurrentItem != fBaseItem) &&
1757 (fCurrentItem->GetNextSibling())) {
1758 fCurrentItem = fCurrentItem->GetNextSibling();
1760 // last histo in folder -> next folder
1761 } else if ((fCurrentItem != fBaseItem) &&
1762 (fCurrentItem->GetParent() != fBaseItem) &&
1763 fCurrentItem->GetParent()->GetNextSibling()) {
1764 fCurrentItem = fCurrentItem->GetParent()->GetNextSibling();
1766 // last histo in last folder -> first folder
1768 fCurrentItem = fBaseItem->GetFirstChild();
1771 // abort if no next item found
1772 if (fCurrentItem == startItem) return kFALSE;
1774 // end loop if an item with a monitor histo was found
1775 } while (!fCurrentItem->GetUserData());
1781 //_____________________________________________________________________________
1782 Bool_t AliMonitorClient::GoToPreviousItem()
1784 // go to the previous histogram in the loop
1786 if (!fCurrentItem) return kFALSE;
1787 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1789 // remember the start item to avoid an endless loop
1790 TGListTreeItem* startItem = fCurrentItem;
1793 // folder -> last child
1794 if (fCurrentItem->GetFirstChild()) {
1795 fCurrentItem = fCurrentItem->GetFirstChild();
1796 while (fCurrentItem->GetNextSibling()) {
1797 fCurrentItem = fCurrentItem->GetNextSibling();
1800 // histo -> previous histo
1801 } else if ((fCurrentItem != fBaseItem) &&
1802 (fCurrentItem->GetPrevSibling())) {
1803 fCurrentItem = fCurrentItem->GetPrevSibling();
1805 // first histo in folder -> previous folder
1806 } else if ((fCurrentItem != fBaseItem) &&
1807 (fCurrentItem->GetParent() != fBaseItem) &&
1808 fCurrentItem->GetParent()->GetPrevSibling()) {
1809 fCurrentItem = fCurrentItem->GetParent()->GetPrevSibling();
1811 // first histo in first folder -> last folder
1813 fCurrentItem = fBaseItem->GetFirstChild();
1814 while (fCurrentItem->GetNextSibling()) {
1815 fCurrentItem = fCurrentItem->GetNextSibling();
1819 // abort if no next item found
1820 if (fCurrentItem == startItem) return kFALSE;
1822 // end loop if an item with a monitor histo was found
1823 } while (!fCurrentItem->GetUserData());
1829 //_____________________________________________________________________________
1830 void AliMonitorClient::UpdateItem(Bool_t highlight)
1832 // update the displayed tree for currently selected item
1834 if (highlight) { // highlight the selected item and open its parent folders
1835 TGListTreeItem* parent = fCurrentItem->GetParent();
1837 if (!parent->IsOpen()) fTree->OpenItem(parent);
1838 parent = parent->GetParent();
1840 fTree->HighlightItem(fCurrentItem);
1841 gClient->NeedRedraw(fTree);
1844 // update displayed histo
1845 UpdateDescription();
1848 // en- or disable the "Reference/Take Current" menu item
1849 TGListTreeItem* base = fCurrentItem;
1850 while (base->GetParent()) base = base->GetParent();
1851 if (base != fComparisonItem) {
1852 fMenuReference->EnableEntry(kMenuRefTakeCurrent);
1854 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
1857 // en- or disable the "Favorites/Add" and "Favorites/Delete" menu items
1858 if (fCurrentItem->GetParent()) {
1859 if (base == fFavoritesItem) {
1860 fMenuFavorites->DisableEntry(kMenuFavAdd);
1861 fMenuFavorites->EnableEntry(kMenuFavDelete);
1863 fMenuFavorites->EnableEntry(kMenuFavAdd);
1864 fMenuFavorites->DisableEntry(kMenuFavDelete);
1867 fMenuFavorites->DisableEntry(kMenuFavAdd);
1868 fMenuFavorites->DisableEntry(kMenuFavDelete);
1873 //_____________________________________________________________________________
1874 Bool_t AliMonitorClient::CheckForNewData()
1876 // check whether the monitor process server sent new data
1878 // disable the socket handler in this method
1879 if (!fSocket || !fSocket->IsValid()) return kFALSE;
1880 fSocketHandler->Remove();
1882 // receive a control message from the server
1883 char controlMessage[256];
1884 if (fSocket->Recv(controlMessage, 255) <= 0) {
1885 fSocketHandler->Add();
1889 // if it is new histogram data, send ok
1890 if ((strcmp(controlMessage, "histograms") != 0) ||
1891 (fSocket->Send("ok") <= 0)) {
1892 fSocketHandler->Add();
1896 // get the histogram data
1897 TMessage* message = NULL;
1898 if (fSocket->Recv(message) <= 0) {
1899 fSocketHandler->Add();
1903 // replace the old folder of monitor histos with the new one
1904 if (message->GetClass()->InheritsFrom(TFolder::Class())) {
1905 if (fFolder) delete fFolder;
1906 fFolder = (TFolder*) message->ReadObject(message->GetClass());
1908 fSocketHandler->Add();
1913 fSocketHandler->Add();
1917 //_____________________________________________________________________________
1918 void AliMonitorClient::ClearItems(TGListTreeItem* base) const
1920 // remove the references to the histograms from all subitems of the
1923 // loop over folders
1924 TGListTreeItem* folderItem = base->GetFirstChild();
1925 while (folderItem) {
1928 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1930 histoItem->SetUserData(NULL);
1931 histoItem = histoItem->GetNextSibling();
1934 folderItem = folderItem->GetNextSibling();
1938 //_____________________________________________________________________________
1939 void AliMonitorClient::CleanUpTree(TGListTreeItem* base)
1941 // remove items without monitor histograms and
1942 // folders without monitor histograms
1944 // loop over folders
1945 TGListTreeItem* folderItem = base->GetFirstChild();
1946 while (folderItem) {
1949 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1951 TGListTreeItem* deleteItem = NULL;
1952 if (!histoItem->GetUserData()) deleteItem = histoItem;
1953 histoItem = histoItem->GetNextSibling();
1954 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1955 if (deleteItem) fTree->DeleteItem(deleteItem);
1958 folderItem = folderItem->GetNextSibling();
1961 // loop over folders and remove empty folders
1962 folderItem = base->GetFirstChild();
1963 while (folderItem) {
1964 TGListTreeItem* deleteItem = NULL;
1965 if (!folderItem->GetFirstChild()) deleteItem = folderItem;
1966 folderItem = folderItem->GetNextSibling();
1967 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1968 if (deleteItem) fTree->DeleteItem(deleteItem);
1972 //_____________________________________________________________________________
1973 void AliMonitorClient::UpdateTree()
1975 // update the tree of monitor histograms
1977 // delete references to old monitor histograms
1978 ClearItems(fAllItem);
1981 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1982 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1985 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1986 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1988 // add new monitor histograms
1989 TGListTreeItem* histoItem = GetItem(fAllItem, folder->GetName(),
1990 histo->GetName(), kTRUE);
1991 histoItem->SetUserData(histo);
1998 // remove items and folders without monitor histograms
1999 CleanUpTree(fAllItem);
2001 gClient->NeedRedraw(fTree);
2004 //_____________________________________________________________________________
2005 void AliMonitorClient::UpdateFavoritesTree()
2007 // update the tree of favorite monitor histograms
2009 // loop over folders
2010 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
2011 while (folderItem) {
2014 TGListTreeItem* histoItem = folderItem->GetFirstChild();
2017 // set monitor histo
2018 histoItem->SetUserData(GetHisto(folderItem->GetText(),
2019 histoItem->GetText()));
2020 histoItem = histoItem->GetNextSibling();
2023 folderItem = folderItem->GetNextSibling();
2027 //_____________________________________________________________________________
2028 void AliMonitorClient::UpdateComparisonTree()
2030 // update the tree of monitor histograms with significant deviation
2031 // from the reference histograms
2033 if (!fFolder) return;
2035 // delete references to old monitor histograms
2036 ClearItems(fComparisonItem);
2038 // add monitor histograms where the comparison returns a deviation
2039 // loop over folders
2040 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
2041 while (TFolder* folder = (TFolder*) iFolder->Next()) {
2044 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
2045 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
2047 // compare the histo to its reference
2048 Bool_t comparison = kTRUE;
2049 if (fEventButton->IsDown()) {
2050 comparison = histo->CompareEvent(fEventNumber->GetIntNumber());
2051 } else if (fSumButton->IsDown()) {
2052 comparison = histo->CompareSum(fEventNumber->GetIntNumber());
2054 comparison = histo->CompareRun();
2057 // add it to the comparison tree in case of a bad comparison result
2059 TGListTreeItem* histoItem = GetItem(fComparisonItem, folder->GetName(),
2060 histo->GetName(), kTRUE);
2061 histoItem->SetUserData(histo);
2069 // remove items and folders without monitor histograms
2070 CleanUpTree(fComparisonItem);
2072 gClient->NeedRedraw(fTree);
2075 //_____________________________________________________________________________
2076 void AliMonitorClient::UpdateDescription()
2078 // update the description of the current monitor histogram
2080 fDescription->Clear();
2081 AliMonitorHisto* histo = NULL;
2082 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2083 if (histo) fDescription->LoadBuffer(histo->GetDescription().Data());
2085 gClient->NeedRedraw(fDescription);
2088 //_____________________________________________________________________________
2089 void AliMonitorClient::UpdateHisto()
2091 // update the current monitor histogram
2093 // clear the canvas if no histo is selected
2094 AliMonitorHisto* histo = NULL;
2095 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2097 fDrawCanvas->GetCanvas()->Clear();
2098 fDrawCanvas->GetCanvas()->Update();
2102 // draw the histo for a single event or summed over several events or a run
2103 fDrawCanvas->GetCanvas()->cd();
2104 if (fEventButton->IsDown()) {
2105 histo->DrawEvent(fEventNumber->GetIntNumber());
2106 } else if (fSumButton->IsDown()) {
2107 histo->DrawSum(fEventNumber->GetIntNumber());
2113 //_____________________________________________________________________________
2114 void AliMonitorClient::UpdateAll()
2116 // update the trees, the histogram and the description
2119 UpdateFavoritesTree();
2120 UpdateComparisonTree();
2121 UpdateDescription();