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 "AliMonitorProcess.h"
31 #include <TGFileDialog.h>
34 #include <TApplication.h>
39 #include <TGTextEntry.h>
40 #include <TGToolBar.h>
42 #include <TGNumberEntry.h>
44 #include <TGSplitter.h>
45 #include <TGListTree.h>
46 #include <TRootEmbeddedCanvas.h>
47 #include <TGTextView.h>
52 #include "AliMonitorHisto.h"
55 ClassImp(AliMonitorClient)
58 const char* AliMonitorClient::fgSettingsFileName = ".AliMonitorClient";
61 //_____________________________________________________________________________
62 AliMonitorClient::AliMonitorStringDlg::AliMonitorStringDlg(TString& string,
66 AliMonitorDialog(main, 300, 80),
67 fStringLayout(new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2)),
68 fStringLabel(new TGLabel(fFrame, label)),
69 fStringEntry(new TGTextEntry(fFrame, string.Data())),
72 // create a dialog for connecting to a monitor process
74 fFrame->AddFrame(fStringLabel, fStringLayout);
75 fStringEntry->Resize(100, fStringEntry->GetDefaultHeight());
76 fFrame->AddFrame(fStringEntry, fStringLayout);
80 fMain->SetWindowName(title);
81 fMain->MapSubwindows();
83 gClient->WaitFor(fMain);
86 //_____________________________________________________________________________
87 AliMonitorClient::AliMonitorStringDlg::~AliMonitorStringDlg()
96 //_____________________________________________________________________________
97 void AliMonitorClient::AliMonitorStringDlg::OnOkClicked()
99 fString = fStringEntry->GetText();
103 //_____________________________________________________________________________
104 AliMonitorClient::AliMonitorNumberDlg::AliMonitorNumberDlg(Float_t& value,
109 AliMonitorDialog(main, 250, 80),
110 fNumberLayout(new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2)),
111 fNumberLabel(new TGLabel(fFrame, label)),
112 fNumberEntry(new TGNumberEntry(fFrame, value, 4, -1, TGNumberFormat::kNESRealOne)),
115 // create a dialog for getting a number
117 fFrame->AddFrame(fNumberLabel, fNumberLayout);
118 fNumberEntry->SetLimits(TGNumberFormat::kNELLimitMin, min, 0);
119 fFrame->AddFrame(fNumberEntry, fNumberLayout);
123 fMain->SetWindowName(title);
124 fMain->MapSubwindows();
126 gClient->WaitFor(fMain);
129 //_____________________________________________________________________________
130 AliMonitorClient::AliMonitorNumberDlg::~AliMonitorNumberDlg()
135 delete fNumberLayout;
139 //_____________________________________________________________________________
140 void AliMonitorClient::AliMonitorNumberDlg::OnOkClicked()
142 fNumber = fNumberEntry->GetNumber();
147 // constants for menu entries
148 enum {kMenuFileConnect, kMenuFileDisconnect, kMenuFileOpen, kMenuFileExit,
149 kMenuViewToolBar, kMenuViewTree, kMenuViewDescription,
150 kMenuViewReference, kMenuViewStatistics,
151 kMenuFavAdd, kMenuFavDelete,
152 kMenuFavLoad, kMenuFavSave, kMenuFavSaveAs, kMenuFavSaveOnExit,
153 kMenuRefLoad, kMenuRefThreshold,
154 kMenuRefTakeCurrent, kMenuRefSave, kMenuRefSaveAs,
155 kMenuOptLoop, kMenuOptPrint,
156 kMenuOptSave, kMenuOptSaveOnExit,
157 kMenuHelpDoc, kMenuHelpAbout
160 //_____________________________________________________________________________
161 AliMonitorClient::AliMonitorClient():
162 TGMainFrame(gClient->GetRoot(), 500, 300),
164 fMenuBarLayout(new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1)),
165 fMenuBarItemLayout(new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)),
166 fMenuBarHelpLayout(new TGLayoutHints(kLHintsTop | kLHintsRight)),
167 fMenuFile(new TGPopupMenu(gClient->GetRoot())),
168 fMenuView(new TGPopupMenu(gClient->GetRoot())),
169 fMenuFavorites(new TGPopupMenu(gClient->GetRoot())),
170 fMenuReference(new TGPopupMenu(gClient->GetRoot())),
171 fMenuOptions(new TGPopupMenu(gClient->GetRoot())),
172 fMenuHelp(new TGPopupMenu(gClient->GetRoot())),
173 fMenuBar(new TGMenuBar(this, 1, 1, kHorizontalFrame)),
174 fToolBarLayout(new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 2, 2)),
175 fToolBarSep(new TGHorizontal3DLine(this)),
176 fToolBar(new TGToolBar(this, 60, 20, kHorizontalFrame)),
177 fEventNumberLayout(new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 10, 2, 10, 5)),
178 fEventNumber(new TGNumberEntry(fToolBar, 1, 4, 10, TGNumberFormat::kNESInteger)),
183 fLoopOnPicture(NULL),
184 fLoopOffPicture(NULL),
185 fPreviousButton(NULL),
190 fBottomLayout(new TGLayoutHints(kLHintsExpandX | kLHintsBottom)),
191 fLeftLayout(new TGLayoutHints(kLHintsLeft | kLHintsExpandY)),
192 fExpandLayout(new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)),
193 fVerticalFrame(new TGVerticalFrame(this, 10, 10)),
194 fHorizontalFrame(new TGHorizontalFrame(fVerticalFrame, 10, 10)),
195 fTreeFrame(new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame | kFixedWidth)),
196 fTreeCanvas(new TGCanvas(fTreeFrame, 10, 10)),
197 fTree(new TGListTree(fTreeCanvas, kHorizontalFrame)),
198 fHistoPicture(fClient->GetPicture("h1_t.xpm")),
199 fAllItem(fTree->AddItem(NULL, "All")),
200 fFavoritesItem(fTree->AddItem(NULL, "Favorites")),
201 fComparisonItem(fTree->AddItem(NULL, "Comparison")),
202 fTreeSplitter(new TGVSplitter(fHorizontalFrame, 4)),
203 fDrawFrame(new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame)),
204 fDrawCanvas(new TRootEmbeddedCanvas("current monitor histogram", fDrawFrame, 10, 10)),
205 fDescriptionSplitter(new TGHSplitter(fVerticalFrame, 4, 4)),
206 fDescriptionFrame(new TGCompositeFrame(fVerticalFrame, 10, 60, kSunkenFrame | kFixedHeight)),
207 fDescription(new TGTextView(fDescriptionFrame, 10, 60, "")),
208 fServerName("localhost"),
210 fSocketHandler(NULL),
211 fFolder(CreateTopFolder()),
216 fFavoritesFileName(""),
217 fReferenceFileName(""),
218 fReference(CreateTopFolder()),
221 // initialize the monitoring client window
224 fMenuFile->AddEntry("&Connect...", kMenuFileConnect);
225 fMenuFile->AddEntry("&Disconnect...", kMenuFileDisconnect);
226 fMenuFile->HideEntry(kMenuFileDisconnect);
227 fMenuFile->AddEntry("&Open...", kMenuFileOpen);
228 fMenuFile->AddSeparator();
229 fMenuFile->AddEntry("E&xit", kMenuFileExit);
230 fMenuFile->Connect("Activated(Int_t)", "AliMonitorClient", this,
231 "OnMenuActivated(Int_t)");
234 fMenuView->AddEntry("Tool&bar", kMenuViewToolBar);
235 fMenuView->CheckEntry(kMenuViewToolBar);
236 fMenuView->AddEntry("&Tree", kMenuViewTree);
237 fMenuView->CheckEntry(kMenuViewTree);
238 fMenuView->AddEntry("&Description", kMenuViewDescription);
239 fMenuView->CheckEntry(kMenuViewDescription);
240 fMenuView->AddSeparator();
241 fMenuView->AddEntry("&Reference", kMenuViewReference);
242 fMenuView->CheckEntry(kMenuViewReference);
243 AliMonitorHisto::SetDrawRef(kTRUE);
244 fMenuView->AddEntry("&Statistics", kMenuViewStatistics);
245 fMenuView->CheckEntry(kMenuViewStatistics);
246 gStyle->SetOptStat(1110);
247 fMenuView->Connect("Activated(Int_t)", "AliMonitorClient", this,
248 "OnMenuActivated(Int_t)");
251 fMenuFavorites->AddEntry("&Add", kMenuFavAdd);
252 fMenuFavorites->DisableEntry(kMenuFavAdd);
253 fMenuFavorites->AddEntry("&Delete", kMenuFavDelete);
254 fMenuFavorites->DisableEntry(kMenuFavDelete);
255 fMenuFavorites->AddSeparator();
256 fMenuFavorites->AddEntry("&Load...", kMenuFavLoad);
257 fMenuFavorites->AddEntry("&Save", kMenuFavSave);
258 fMenuFavorites->DisableEntry(kMenuFavSave);
259 fMenuFavorites->AddEntry("&Save As...", kMenuFavSaveAs);
260 fMenuFavorites->DisableEntry(kMenuFavSaveAs);
261 fMenuFavorites->AddEntry("Save On &Exit", kMenuFavSaveOnExit);
262 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
263 fMenuFavorites->Connect("Activated(Int_t)", "AliMonitorClient", this,
264 "OnMenuActivated(Int_t)");
267 fMenuReference->AddEntry("&Load...", kMenuRefLoad);
268 fMenuReference->AddEntry("&Threshold...", kMenuRefThreshold);
269 fMenuReference->AddSeparator();
270 fMenuReference->AddEntry("Take &Current", kMenuRefTakeCurrent);
271 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
272 fMenuReference->AddEntry("&Save", kMenuRefSave);
273 fMenuReference->DisableEntry(kMenuRefSave);
274 fMenuReference->AddEntry("Save &As...", kMenuRefSaveAs);
275 fMenuReference->DisableEntry(kMenuRefSaveAs);
276 fMenuReference->Connect("Activated(Int_t)", "AliMonitorClient", this,
277 "OnMenuActivated(Int_t)");
280 fMenuOptions->AddEntry("&Loop Interval...", kMenuOptLoop);
281 fMenuOptions->AddEntry("&Print Command...", kMenuOptPrint);
282 fMenuOptions->AddSeparator();
283 fMenuOptions->AddEntry("&Save Settings", kMenuOptSave);
284 fMenuOptions->AddEntry("Save Settings on &Exit", kMenuOptSaveOnExit);
285 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
286 fMenuOptions->Connect("Activated(Int_t)", "AliMonitorClient", this,
287 "OnMenuActivated(Int_t)");
290 fMenuHelp->AddEntry("&Documentation...", kMenuHelpDoc);
291 fMenuHelp->AddEntry("A&bout...", kMenuHelpAbout);
292 fMenuHelp->Connect("Activated(Int_t)", "AliMonitorClient", this,
293 "OnMenuActivated(Int_t)");
296 fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
297 fMenuBar->AddPopup("&View", fMenuView, fMenuBarItemLayout);
298 fMenuBar->AddPopup("F&avorites", fMenuFavorites, fMenuBarItemLayout);
299 fMenuBar->AddPopup("&Reference", fMenuReference, fMenuBarItemLayout);
300 fMenuBar->AddPopup("&Options", fMenuOptions, fMenuBarItemLayout);
301 fMenuBar->AddPopup("&Help", fMenuHelp, fMenuBarHelpLayout);
303 AddFrame(fMenuBar, fMenuBarLayout);
307 AddFrame(fToolBarSep, fToolBarLayout);
308 AddFrame(fToolBar, fToolBarLayout);
310 // event number field
311 fEventNumber->SetLimits(TGNumberFormat::kNELLimitMin, 1, 0);
312 fToolBar->AddFrame(fEventNumber, fEventNumberLayout);
313 fEventNumber->GetNumberEntry()->Connect("ReturnPressed()",
314 "AliMonitorClient", this,
315 "OnEventNumberChanged()");
316 fEventNumber->GetButtonUp()->Connect("Clicked()",
317 "AliMonitorClient", this,
318 "OnEventNumberChanged()");
319 fEventNumber->GetButtonDown()->Connect("Clicked()",
320 "AliMonitorClient", this,
321 "OnEventNumberChanged()");
324 ToolBarData_t eventButton = {"h1_s.xpm", "draw event histogram",
326 fToolBar->AddButton(this, &eventButton, 5);
327 fEventButton = eventButton.fButton;
328 fEventButton->Connect("Pressed()", "AliMonitorClient", this,
329 "OnEventButtonPressed()");
332 ToolBarData_t sumButton = {"h2_s.xpm", "draw sum histogram",
334 fToolBar->AddButton(this, &sumButton, 5);
335 fSumButton = sumButton.fButton;
336 fSumButton->Connect("Pressed()", "AliMonitorClient", this,
337 "OnSumButtonPressed()");
340 ToolBarData_t runButton = {"h3_s.xpm", "draw run histogram",
342 fToolBar->AddButton(this, &runButton, 5);
343 fRunButton = runButton.fButton;
344 fRunButton->SetDown(kTRUE);
345 fRunButton->Connect("Pressed()", "AliMonitorClient", this,
346 "OnRunButtonPressed()");
350 sprintf(fileName, "%s/MONITOR/loop_on.xpm", gSystem->Getenv("ALICE_ROOT"));
351 ToolBarData_t loopButton = {fileName, "loop over histograms",
353 fToolBar->AddButton(this, &loopButton, 25);
354 fLoopButton = loopButton.fButton;
355 fLoopButton->Connect("Clicked()", "AliMonitorClient", this,
356 "OnLoopButtonClicked()");
357 fLoopOnPicture = gClient->GetPicture(fileName);
358 sprintf(fileName, "%s/MONITOR/loop_off2.xpm", gSystem->Getenv("ALICE_ROOT"));
359 fLoopOffPicture = gClient->GetPicture(fileName);
362 sprintf(fileName, "%s/MONITOR/previous_s.xpm",
363 gSystem->Getenv("ALICE_ROOT"));
364 ToolBarData_t previousButton = {fileName, "go to previous histogram",
366 fToolBar->AddButton(this, &previousButton, 5);
367 fPreviousButton = previousButton.fButton;
368 fPreviousButton->Connect("Clicked()", "AliMonitorClient", this,
369 "OnPreviousButtonClicked()");
372 sprintf(fileName, "%s/MONITOR/next_s.xpm", gSystem->Getenv("ALICE_ROOT"));
373 ToolBarData_t nextButton = {fileName, "go to next histogram",
375 fToolBar->AddButton(this, &nextButton, 5);
376 fNextButton = nextButton.fButton;
377 fNextButton->Connect("Clicked()", "AliMonitorClient", this,
378 "OnNextButtonClicked()");
381 sprintf(fileName, "%s/MONITOR/copy_s.xpm", gSystem->Getenv("ALICE_ROOT"));
382 ToolBarData_t copyButton = {fileName,
383 "copy the current histogram to a new canvas",
385 fToolBar->AddButton(this, ©Button, 25);
386 fCopyButton = copyButton.fButton;
387 fCopyButton->Connect("Clicked()", "AliMonitorClient", this,
388 "OnCopyButtonClicked()");
391 sprintf(fileName, "%s/MONITOR/save_s.xpm", gSystem->Getenv("ALICE_ROOT"));
392 ToolBarData_t saveButton = {fileName, "save the current histogram",
394 fToolBar->AddButton(this, &saveButton, 5);
395 fSaveButton = saveButton.fButton;
396 fSaveButton->Connect("Clicked()", "AliMonitorClient", this,
397 "OnSaveButtonClicked()");
400 ToolBarData_t printButton = {"printer_s.xpm", "print the current histogram",
402 fToolBar->AddButton(this, &printButton, 5);
403 fPrintButton = printButton.fButton;
404 fPrintButton->Connect("Clicked()", "AliMonitorClient", this,
405 "OnPrintButtonClicked()");
408 AddFrame(fVerticalFrame, fExpandLayout);
410 fVerticalFrame->AddFrame(fHorizontalFrame, fExpandLayout);
413 fHorizontalFrame->AddFrame(fTreeFrame, fLeftLayout);
414 fTreeFrame->AddFrame(fTreeCanvas, fExpandLayout);
415 fTreeCanvas->AddFrame(fTree, fExpandLayout);
416 fTree->Connect("Clicked(TGListTreeItem*,Int_t)", "AliMonitorClient",
417 this, "OnTreeClicked(TGListTreeItem*,Int_t)");
418 fTree->Connect("ReturnPressed(TGListTreeItem*)", "AliMonitorClient",
419 this, "OnTreeReturnPressed(TGListTreeItem*)");
422 fTreeFrame->Resize(100, fTreeFrame->GetDefaultHeight());
424 // tree / histogram splitter
425 fTreeSplitter->SetFrame(fTreeFrame, kTRUE);
426 fHorizontalFrame->AddFrame(fTreeSplitter, fLeftLayout);
429 fHorizontalFrame->AddFrame(fDrawFrame, fExpandLayout);
430 fDrawFrame->AddFrame(fDrawCanvas, fExpandLayout);
433 fVerticalFrame->AddFrame(fDescriptionFrame, fBottomLayout);
434 fDescriptionFrame->AddFrame(fDescription, fExpandLayout);
436 // histogram / description splitter
437 fVerticalFrame->AddFrame(fDescriptionSplitter, fBottomLayout);
438 fDescriptionSplitter->SetFrame(fDescriptionFrame, kFALSE);
441 Connect("CloseWindow()", "AliMonitorClient", this, "CloseWindow()");
442 SetWindowName("Monitor Client");
443 SetWMSize(GetWidth(), GetHeight());
445 SetWMPosition(100, 100);
451 // default data members
453 fFolder = CreateTopFolder();
455 fReference = CreateTopFolder();
456 AliMonitorHisto::SetThreshold(5.0);
458 // load saved settings
462 //_____________________________________________________________________________
463 AliMonitorClient::~AliMonitorClient()
467 delete fMenuBarLayout;
468 delete fMenuBarItemLayout;
469 delete fMenuBarHelpLayout;
472 delete fMenuFavorites;
473 delete fMenuReference;
478 delete fEventNumberLayout;
480 delete fToolBarLayout;
484 delete fBottomLayout;
486 delete fExpandLayout;
491 delete fTreeSplitter;
496 delete fDescriptionSplitter;
498 delete fDescriptionFrame;
500 delete fVerticalFrame;
501 delete fHorizontalFrame;
504 fSocketHandler->Remove();
505 fSocket->Send("disconnect");
508 delete fSocketHandler;
511 if (fFolder) delete fFolder;
514 fLoopTimer->TurnOff();
518 if (fReference) delete fReference;
522 //_____________________________________________________________________________
523 void AliMonitorClient::CloseWindow()
525 // terminate the application when the window is closed
527 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
530 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
534 fSocketHandler->Remove();
535 fSocket->Send("disconnect");
539 delete fSocketHandler;
540 fSocketHandler = NULL;
543 gApplication->Terminate(0);
547 //_____________________________________________________________________________
548 void AliMonitorClient::OnNewData()
550 // called when data has arrived from the monitor server
552 if (CheckForNewData()) UpdateAll();
556 //_____________________________________________________________________________
557 void AliMonitorClient::OnMenuActivated(Int_t id)
559 // called when a menu item was selected
563 case kMenuFileConnect: {
564 if (ConnectToServer()) UpdateAll();
568 case kMenuFileDisconnect: {
569 DisconnectFromServer();
573 case kMenuFileOpen: {
574 if (OpenFile()) UpdateAll();
578 case kMenuFileExit: {
583 case kMenuViewToolBar: {
584 ViewToolBar(!fMenuView->IsEntryChecked(kMenuViewToolBar));
588 case kMenuViewTree: {
589 ViewTree(!fMenuView->IsEntryChecked(kMenuViewTree));
593 case kMenuViewDescription: {
594 ViewDescription(!fMenuView->IsEntryChecked(kMenuViewDescription));
598 case kMenuViewReference: {
599 ViewReference(!fMenuView->IsEntryChecked(kMenuViewReference));
604 case kMenuViewStatistics: {
605 ViewStatistics(!fMenuView->IsEntryChecked(kMenuViewStatistics));
612 fMenuFavorites->EnableEntry(kMenuFavSave);
613 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
618 case kMenuFavDelete: {
619 if (DeleteFavorite()) {
622 fMenuFavorites->DisableEntry(kMenuFavDelete);
623 fMenuFavorites->EnableEntry(kMenuFavSave);
624 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
630 if (LoadFavorites()) {
633 fMenuFavorites->DisableEntry(kMenuFavSave);
634 fMenuFavorites->EnableEntry(kMenuFavSaveAs);
640 if (SaveFavorites()) {
641 fMenuFavorites->DisableEntry(kMenuFavSave);
646 case kMenuFavSaveAs: {
647 if (SaveFavoritesAs()) {
648 fMenuFavorites->DisableEntry(kMenuFavSave);
653 case kMenuFavSaveOnExit: {
654 if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
655 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
657 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
663 if (LoadReference()) {
666 UpdateComparisonTree();
667 fMenuReference->EnableEntry(kMenuRefSaveAs);
672 case kMenuRefThreshold: {
673 Float_t threshold = AliMonitorHisto::GetThreshold();
674 new AliMonitorNumberDlg(threshold, this,
675 "Comparison with Reference Histograms",
676 "threshold for comparison:", 0.);
677 if (threshold < 0) break;
679 AliMonitorHisto::SetThreshold(threshold);
681 UpdateComparisonTree();
685 case kMenuRefTakeCurrent: {
686 if (TakeCurrentReference()) {
688 UpdateComparisonTree();
689 fMenuReference->EnableEntry(kMenuRefSave);
690 fMenuReference->EnableEntry(kMenuRefSaveAs);
696 if (SaveReference()) {
697 fMenuReference->DisableEntry(kMenuRefSave);
702 case kMenuRefSaveAs: {
703 if (SaveReferenceAs()) {
704 fMenuReference->DisableEntry(kMenuRefSave);
710 Float_t interval = fLoopInterval * 0.001;
711 new AliMonitorNumberDlg(interval, this, "Loop Interval",
712 "loop time in seconds:", 0.1);
713 if (interval < 0) break;
715 fLoopInterval = Int_t(1000 * interval);
718 fLoopTimer->Start(fLoopInterval);
723 case kMenuOptPrint: {
724 TString printCommand(fPrintCommand);
725 new AliMonitorStringDlg(printCommand, this, "Print Command",
726 "shell command for printing:");
727 if (printCommand.IsNull()) break;
729 fPrintCommand = printCommand;
733 case kMenuOptSaveOnExit: {
734 if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
735 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
737 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
747 case kMenuHelpAbout: {
749 new TGMsgBox(gClient->GetRoot(), this,
750 "About", "AliMonitorClient $Revision$",
751 kMBIconAsterisk, kMBOk, &result);
757 new TGMsgBox(gClient->GetRoot(), this,
758 "AliMonitorClient", "not yet implemented",
759 kMBIconExclamation, kMBOk, &result);
765 //_____________________________________________________________________________
766 void AliMonitorClient::OnEventNumberChanged()
768 // called when the event number in the tool button was changed
770 if (!fRunButton->IsDown()) {
772 UpdateComparisonTree();
776 //_____________________________________________________________________________
777 void AliMonitorClient::OnEventButtonPressed()
779 // called when the event tool button was clicked
781 fSumButton->SetDown(kFALSE);
782 fRunButton->SetDown(kFALSE);
784 UpdateComparisonTree();
787 //_____________________________________________________________________________
788 void AliMonitorClient::OnSumButtonPressed()
790 // called when the sum tool button was clicked
792 fEventButton->SetDown(kFALSE);
793 fRunButton->SetDown(kFALSE);
795 UpdateComparisonTree();
798 //_____________________________________________________________________________
799 void AliMonitorClient::OnRunButtonPressed()
801 // called when the run tool button was clicked
803 fEventButton->SetDown(kFALSE);
804 fSumButton->SetDown(kFALSE);
806 UpdateComparisonTree();
809 //_____________________________________________________________________________
810 void AliMonitorClient::OnLoopButtonClicked()
812 // called when the loop tool button was clicked
814 // if loop is not running, start the loop timer and
815 // set the stop loop button picture
818 if (!GetBaseItem()) return;
820 fLoopTimer = new TTimer(fLoopInterval);
821 fLoopTimer->Connect("Timeout()", "AliMonitorClient", this,
823 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOffPicture);
824 fLoopTimer->TurnOn();
826 // if the loop is running, stop it
832 //_____________________________________________________________________________
833 void AliMonitorClient::OnPreviousButtonClicked()
835 // called when the previous tool button was clicked
838 if (!GetBaseItem()) return;
844 //_____________________________________________________________________________
845 void AliMonitorClient::OnNextButtonClicked()
847 // called when the next tool button was clicked
850 if (!GetBaseItem()) return;
856 //_____________________________________________________________________________
857 void AliMonitorClient::OnCopyButtonClicked()
859 // called when the copy tool button was clicked
861 fDrawCanvas->GetCanvas()->DrawClone();
864 //_____________________________________________________________________________
865 void AliMonitorClient::OnSaveButtonClicked()
867 // called when the save tool button was clicked
869 // display a file save dialog
870 static TGFileInfo fileInfo;
871 static const char* fileTypes[] = {"PostScript", "*.ps",
872 "Encapsulated PostScript", "*.eps",
874 "Gif files", "*.gif",
875 "Macro files", "*.C",
876 "ROOT files", "*.root",
879 fileInfo.fFileTypes = fileTypes;
880 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
881 if (!fileInfo.fFilename) return;
883 fDrawCanvas->GetCanvas()->SaveAs(fileInfo.fFilename);
886 //_____________________________________________________________________________
887 void AliMonitorClient::OnPrintButtonClicked()
889 // called when the print tool button was clicked
891 // save the canvas to a temporary postscript file
892 char fileName[L_tmpnam+4];
893 sprintf(fileName, "%s.ps", tmpnam(NULL));
894 fDrawCanvas->GetCanvas()->SaveAs(fileName);
896 // call the print command and delete the temporary file
898 sprintf(command, "%s %s", fPrintCommand.Data(), fileName);
899 gSystem->Exec(command);
900 gSystem->Unlink(fileName);
904 //_____________________________________________________________________________
905 void AliMonitorClient::OnTreeClicked(TGListTreeItem* item, Int_t)
907 // called when an item in the histogram tree is clicked
909 OnTreeReturnPressed(item);
912 //_____________________________________________________________________________
913 void AliMonitorClient::OnTreeReturnPressed(TGListTreeItem* item)
915 // called when return is pressed at an item in the histogram tree
924 //_____________________________________________________________________________
925 void AliMonitorClient::OnLoopTimer()
927 // called by the loop timer when a new histogram should be displayed
930 if (!GetBaseItem()) return;
936 //_____________________________________________________________________________
937 TFolder* AliMonitorClient::CreateTopFolder() const
939 // create a top folder for monitor histograms
941 return (new TFolder("Monitor", "monitor histograms"));
944 //_____________________________________________________________________________
945 AliMonitorHisto* AliMonitorClient::GetHisto(const char* folderName,
946 const char* histoName)
948 // find the monitor histogram with the given name in the given folder
950 TGListTreeItem* folderItem = fTree->FindChildByName(fAllItem, folderName);
952 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
953 if (histoItem) return (AliMonitorHisto*) histoItem->GetUserData();
958 //_____________________________________________________________________________
959 TGListTreeItem* AliMonitorClient::GetItem(TGListTreeItem* base,
960 const char* folderName,
961 const char* histoName,
964 // find the tree item with given name in the given folder
965 // if create is kTRUE it is created if it is not there
967 // get or create the folder
968 TGListTreeItem* folderItem = fTree->FindChildByName(base, folderName);
970 if (!create) return NULL;
971 folderItem = fTree->AddItem(base, folderName);
974 // get or create the histo
975 TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
977 if (!create) return NULL;
978 histoItem = fTree->AddItem(folderItem, histoName,
979 fClient->GetPicture("h1_t.xpm"),
980 fClient->GetPicture("h1_t.xpm"));
986 //_____________________________________________________________________________
987 Bool_t AliMonitorClient::ConnectToServer()
989 // display the dialog for the server name or ip and try to connect to it
991 TString serverName(fServerName);
994 // ask for the server name or ip
995 new AliMonitorStringDlg(serverName, this, "Connection to monitor process",
996 "monitor server name or ip:");
997 if (serverName.IsNull()) return kFALSE;
999 // connect to the server
1000 fSocket = new TSocket(serverName, AliMonitorProcess::GetPort());
1001 if (!fSocket || !fSocket->IsValid() || (fSocket->Send("client") <= 0)) {
1002 if (fSocket) delete fSocket;
1005 new TGMsgBox(gClient->GetRoot(), this, "Connect",
1006 "connection to monitor server failed",
1007 kMBIconExclamation, kMBOk, &result);
1009 } else { // set up a handler for notifying when new data is there
1010 fServerName = serverName;
1011 fSocketHandler = new TFileHandler(fSocket->GetDescriptor(),
1012 TFileHandler::kRead);
1013 fSocketHandler->Connect("Notified()", "AliMonitorClient", this,
1015 fSocketHandler->Add();
1016 TInetAddress adr = fSocket->GetInetAddress();
1017 AliInfo(Form("connected to server: %s (%s), port %d",
1018 adr.GetHostName(), adr.GetHostAddress(), adr.GetPort()));
1019 fMenuFile->HideEntry(kMenuFileConnect);
1020 fMenuFile->HideEntry(kMenuFileOpen);
1021 fMenuFile->EnableEntry(kMenuFileDisconnect);
1026 // delete the old monitor histos
1027 if (fFolder) delete fFolder;
1028 fFolder = CreateTopFolder();
1032 //_____________________________________________________________________________
1033 void AliMonitorClient::DisconnectFromServer()
1035 // disconnect from the monitor server
1037 // are-you-really-sure-dialog
1039 new TGMsgBox(gClient->GetRoot(), this, "Disconnect",
1040 "Do you really want to disconnect from the monitor server?",
1041 kMBIconQuestion, kMBYes | kMBNo, &result);
1042 if (result == kMBNo) return;
1044 // disconnect from the server
1045 fSocketHandler->Remove();
1046 fSocket->Send("disconnect");
1050 fMenuFile->HideEntry(kMenuFileDisconnect);
1051 fMenuFile->EnableEntry(kMenuFileConnect);
1052 fMenuFile->EnableEntry(kMenuFileOpen);
1055 //_____________________________________________________________________________
1056 Bool_t AliMonitorClient::OpenFile()
1058 // open a file with monitor histograms
1060 // display a file open dialog
1061 static TGFileInfo fileInfo;
1062 static const char* fileTypes[] = {"ROOT files", "*.root",
1065 fileInfo.fFileTypes = fileTypes;
1066 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1067 if (!fileInfo.fFilename) return kFALSE;
1069 // open the root file
1070 TFile* file = TFile::Open(fileInfo.fFilename);
1071 if (!file || !file->IsOpen()) {
1073 new TGMsgBox(gClient->GetRoot(), this, "Open",
1074 "The file could not be opened.",
1075 kMBIconExclamation, kMBOk, &result);
1079 // get the folder with the monitor histograms
1080 TFolder* folder = (TFolder*) file->Get("Monitor");
1081 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1083 new TGMsgBox(gClient->GetRoot(), this, "Open",
1084 "The file does not contain monitor histograms.",
1085 kMBIconExclamation, kMBOk, &result);
1091 // replace the old folder with the new one
1095 if (fFolder) delete fFolder;
1101 //_____________________________________________________________________________
1102 void AliMonitorClient::ViewToolBar(Bool_t visible)
1104 // en- or disable the view of the tool bar
1107 ShowFrame(fToolBarSep);
1108 ShowFrame(fToolBar);
1109 fMenuView->CheckEntry(kMenuViewToolBar);
1111 HideFrame(fToolBarSep);
1112 HideFrame(fToolBar);
1113 fMenuView->UnCheckEntry(kMenuViewToolBar);
1117 //_____________________________________________________________________________
1118 void AliMonitorClient::ViewTree(Bool_t visible)
1120 // en- or disable the view of the tree
1123 fHorizontalFrame->ShowFrame(fTreeFrame);
1124 fHorizontalFrame->ShowFrame(fTreeSplitter);
1125 fMenuView->CheckEntry(kMenuViewTree);
1127 fHorizontalFrame->HideFrame(fTreeFrame);
1128 fHorizontalFrame->HideFrame(fTreeSplitter);
1129 fMenuView->UnCheckEntry(kMenuViewTree);
1133 //_____________________________________________________________________________
1134 void AliMonitorClient::ViewDescription(Bool_t visible)
1136 // en- or disable the view of the histogram description
1139 fVerticalFrame->ShowFrame(fDescriptionFrame);
1140 fVerticalFrame->ShowFrame(fDescriptionSplitter);
1141 fMenuView->CheckEntry(kMenuViewDescription);
1143 fVerticalFrame->HideFrame(fDescriptionFrame);
1144 fVerticalFrame->HideFrame(fDescriptionSplitter);
1145 fMenuView->UnCheckEntry(kMenuViewDescription);
1149 //_____________________________________________________________________________
1150 void AliMonitorClient::ViewReference(Bool_t visible)
1152 // en- or disable the view of the reference histos
1155 AliMonitorHisto::SetDrawRef(kTRUE);
1156 fMenuView->CheckEntry(kMenuViewReference);
1158 AliMonitorHisto::SetDrawRef(kFALSE);
1159 fMenuView->UnCheckEntry(kMenuViewReference);
1163 //_____________________________________________________________________________
1164 void AliMonitorClient::ViewStatistics(Bool_t visible)
1166 // en- or disable the view of the statistics box
1169 gStyle->SetOptStat(1110);
1170 fMenuView->CheckEntry(kMenuViewStatistics);
1172 gStyle->SetOptStat(0);
1173 fMenuView->UnCheckEntry(kMenuViewStatistics);
1178 //_____________________________________________________________________________
1179 Bool_t AliMonitorClient::AddFavorite()
1181 // add the current histogram or folder to the list of favorites
1183 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1185 // get the folder item
1186 TGListTreeItem* folderItem = fCurrentItem->GetParent();
1187 if (fCurrentItem->GetFirstChild()) folderItem = fCurrentItem;
1189 Bool_t result = kFALSE;
1192 if (fCurrentItem->GetFirstChild()) {
1193 TGListTreeItem* histoItem = fCurrentItem->GetFirstChild();
1195 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1196 histoItem->GetText(), kFALSE)) result = kTRUE;
1197 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1198 histoItem->GetText(), kTRUE);
1199 item->SetUserData(histoItem->GetUserData());
1200 histoItem = histoItem->GetNextSibling();
1205 if (!GetItem(fFavoritesItem, folderItem->GetText(),
1206 fCurrentItem->GetText(), kFALSE)) result = kTRUE;
1207 TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(),
1208 fCurrentItem->GetText(), kTRUE);
1209 item->SetUserData(fCurrentItem->GetUserData());
1212 if (result) gClient->NeedRedraw(fTree);
1216 //_____________________________________________________________________________
1217 Bool_t AliMonitorClient::DeleteFavorite()
1219 // delete the current histogram or folder from the list of favorites
1221 // check that the current item is a favorites histo or folder
1222 if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1223 TGListTreeItem* base = fCurrentItem;
1224 while (base->GetParent()) base = base->GetParent();
1225 if (base != fFavoritesItem) return kFALSE;
1228 TGListTreeItem* parent = fCurrentItem->GetParent();
1229 fTree->DeleteItem(fCurrentItem);
1230 fCurrentItem = NULL;
1232 // delete the parent folder if it is empty now
1233 if (parent->GetParent() != NULL) {
1234 if (!parent->GetFirstChild()) fTree->DeleteItem(parent);
1237 gClient->NeedRedraw(fTree);
1241 //_____________________________________________________________________________
1242 Bool_t AliMonitorClient::LoadFavorites(Bool_t dialog)
1244 // load the list of favorites from a file
1246 // display a file open dialog
1247 TGFileInfo fileInfo;
1248 static const char* fileTypes[] = {"Favorites files", "*.fav",
1251 fileInfo.fFileTypes = fileTypes;
1252 fileInfo.fIniDir = StrDup(".");
1253 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1255 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1256 if (!fileInfo.fFilename) return kFALSE;
1259 // open the text file
1260 FILE* file = fopen(fileInfo.fFilename, "rt");
1263 new TGMsgBox(gClient->GetRoot(), this, "Load Favorites",
1264 "The file could not be opened.",
1265 kMBIconExclamation, kMBOk, &result);
1269 // delete the old favorites
1270 TGListTreeItem* favFolderItem = fFavoritesItem->GetFirstChild();
1271 while (favFolderItem) {
1272 TGListTreeItem* deleteItem = favFolderItem;
1273 favFolderItem = favFolderItem->GetNextSibling();
1274 fTree->DeleteItem(deleteItem);
1277 // scan the text file and add the favorites histos
1279 while (!feof(file)) {
1280 if (fgets(buffer, 255, file) == NULL) break;
1281 char* folder = strtok(buffer, "/");
1282 char* item = strtok(NULL, "\n");
1283 if (item[strlen(item)-1] == '\n') item[strlen(item)-1] = 0;
1284 if (!folder || !item) continue;
1286 AliMonitorHisto* histo = GetHisto(folder, item);
1287 TGListTreeItem* histoItem = GetItem(fFavoritesItem, folder, item, kTRUE);
1288 histoItem->SetUserData(histo);
1295 //_____________________________________________________________________________
1296 Bool_t AliMonitorClient::SaveFavorites()
1298 // save the list of favorites in a file with the name fFavoritesFileName
1300 // if no file name is given use a default one
1301 if (fFavoritesFileName.IsNull()) {
1302 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1303 "AliMonitorClient.fav");
1304 fFavoritesFileName = fileName;
1308 // open the text file
1309 FILE* file = fopen(fFavoritesFileName.Data(), "wt");
1312 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1313 "The file could not be opened.",
1314 kMBIconExclamation, kMBOk, &result);
1318 // loop over folders
1319 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1320 while (folderItem) {
1323 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1326 // write the favorites
1327 if (fprintf(file, "%s/%s\n", folderItem->GetText(),
1328 histoItem->GetText()) <= 0) {
1330 new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1331 "An error occured while sving the favorites.",
1332 kMBIconExclamation, kMBOk, &result);
1336 histoItem = histoItem->GetNextSibling();
1339 folderItem = folderItem->GetNextSibling();
1343 AliInfo(Form("favorites saved to file %s", fFavoritesFileName.Data()));
1347 //_____________________________________________________________________________
1348 Bool_t AliMonitorClient::SaveFavoritesAs()
1350 // ask for a file name and save the favorites to this file
1352 // display a save file dialog
1353 TGFileInfo fileInfo;
1354 static const char* fileTypes[] = {"Favorites files", "*.fav",
1357 fileInfo.fFileTypes = fileTypes;
1358 fileInfo.fIniDir = StrDup(".");
1359 fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1360 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1361 if (!fileInfo.fFilename) return kFALSE;
1363 // save the favorites
1364 fFavoritesFileName = fileInfo.fFilename;
1365 return SaveFavorites();
1369 //_____________________________________________________________________________
1370 Bool_t AliMonitorClient::LoadReference(Bool_t dialog)
1372 // load reference histograms from a file
1374 // display a file open dialog
1375 TGFileInfo fileInfo;
1376 static const char* fileTypes[] = {"ROOT files", "*.root",
1379 fileInfo.fFileTypes = fileTypes;
1380 fileInfo.fIniDir = StrDup(".");
1381 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1383 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1384 if (!fileInfo.fFilename) return kFALSE;
1387 // open the root file
1388 TFile* file = TFile::Open(fileInfo.fFilename);
1389 if (!file || !file->IsOpen()) {
1391 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1392 "The file could not be opened.",
1393 kMBIconExclamation, kMBOk, &result);
1397 // get the folder with the monitor histograms
1398 TFolder* folder = (TFolder*) file->Get("Monitor");
1399 if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1401 new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1402 "The file does not contain monitor histograms.",
1403 kMBIconExclamation, kMBOk, &result);
1409 // replace the old reference folder with the new one
1410 fReferenceFileName = fileInfo.fFilename;
1414 if (fReference) delete fReference;
1415 fReference = folder;
1419 //_____________________________________________________________________________
1420 void AliMonitorClient::SetReference()
1422 // set the reference histograms for all monitor histograms
1425 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1426 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1427 TFolder* refFolder = (TFolder*) fReference->FindObject(folder->GetName());
1428 if (!refFolder) continue;
1431 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1432 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1433 AliMonitorHisto* refHisto =
1434 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1435 if (!refHisto) continue;
1436 histo->SetReference(refHisto);
1444 //_____________________________________________________________________________
1445 Bool_t AliMonitorClient::TakeCurrentReference()
1447 // take the current monitor histogram or folder as reference
1449 // check that a histo or folder is selected
1450 if (!fCurrentItem) return kFALSE;
1451 AliMonitorHisto* histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
1452 if (!histo && !fCurrentItem->GetFirstChild()) return kFALSE;
1457 sprintf(message, "Do you want to take the current histogram %s/%s "
1458 "as reference histogram?", fCurrentItem->GetParent()->GetText(),
1461 sprintf(message, "Do you want to take all current histogram of the "
1462 "folder %s as reference histogram?", fCurrentItem->GetText());
1465 new TGMsgBox(gClient->GetRoot(), this, "Take Current as Reference",
1466 message, kMBIconQuestion, kMBYes | kMBNo, &result);
1467 if (result != kMBYes) return kFALSE;
1470 if (histo) { // ... a histo
1471 TakeReferenceHisto(fCurrentItem->GetParent()->GetText(), histo);
1472 } else if (fCurrentItem->GetParent()) { // ... a folder
1473 TakeReferenceFolder(fCurrentItem);
1474 } else { // ... a top folder
1475 TGListTreeItem* folderItem = fCurrentItem->GetFirstChild();
1476 while (folderItem) {
1477 TakeReferenceFolder(folderItem);
1478 folderItem = folderItem->GetNextSibling();
1484 //_____________________________________________________________________________
1485 void AliMonitorClient::TakeReferenceHisto(const char* folderName,
1486 AliMonitorHisto* histo)
1488 // take the given monitor histogram as reference histogram
1490 // get or create the reference folder
1491 TFolder* refFolder = (TFolder*) fReference->FindObject(folderName);
1492 if (!refFolder) refFolder = fReference->AddFolder(folderName, folderName);
1494 // delete the old reference histo
1495 AliMonitorHisto* refHisto =
1496 (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1498 refFolder->Remove(refHisto);
1502 // add the new one and use it as reference
1503 refFolder->Add(new AliMonitorHisto(*histo));
1504 histo->SetReference(histo);
1507 //_____________________________________________________________________________
1508 void AliMonitorClient::TakeReferenceFolder(TGListTreeItem* item)
1510 // take all monitor histogram in the given folder as reference histograms
1513 TGListTreeItem* histoItem = item->GetFirstChild();
1515 AliMonitorHisto* histo = (AliMonitorHisto*) histoItem->GetUserData();
1516 if (histo) TakeReferenceHisto(item->GetText(), histo);
1517 histoItem = histoItem->GetNextSibling();
1521 //_____________________________________________________________________________
1522 Bool_t AliMonitorClient::SaveReference()
1524 // save the reference histograms to the file with name fReferenceFileName
1526 // if no file name is given use a default one
1527 if (fFavoritesFileName.IsNull()) {
1528 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1529 "AliMonitorClientRef.root");
1530 fFavoritesFileName = fileName;
1534 // open the root file
1535 TFile* file = TFile::Open(fReferenceFileName, "RECREATE");
1536 if (!file || !file->IsOpen()) {
1538 new TGMsgBox(gClient->GetRoot(), this, "Save Reference",
1539 "The file could not be opened.",
1540 kMBIconExclamation, kMBOk, &result);
1541 if (file) delete file;
1545 // write the reference folder
1546 fReference->Write();
1549 AliInfo(Form("reference histograms saved to file %s",
1550 fReferenceFileName.Data()));
1554 //_____________________________________________________________________________
1555 Bool_t AliMonitorClient::SaveReferenceAs()
1557 // ask for a file name and save the reference histograms to this file
1559 // display a save file dialog
1560 TGFileInfo fileInfo;
1561 static const char* fileTypes[] = {"ROOT files", "*.root",
1564 fileInfo.fFileTypes = fileTypes;
1565 fileInfo.fIniDir = StrDup(".");
1566 fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1567 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1568 if (!fileInfo.fFilename) return kFALSE;
1570 // save the references
1571 fReferenceFileName = fileInfo.fFilename;
1572 return SaveReference();
1576 //_____________________________________________________________________________
1577 void AliMonitorClient::StopLoop()
1579 // stop looping over histograms
1581 // stop the timer and reset the loop button picture
1583 fLoopTimer->TurnOff();
1586 ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOnPicture);
1590 //_____________________________________________________________________________
1591 void AliMonitorClient::LoadSettings()
1593 // load setting from the file with the name fgSettingFileName and apply them
1595 // open the text file
1596 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1597 fgSettingsFileName);
1598 FILE* file = fopen(fileName, "rt");
1604 // scan the text file and apply the settings
1606 while (!feof(file)) {
1607 if (fgets(buffer, 255, file) == NULL) break;
1608 char* token = strtok(buffer, "=");
1609 char* value = strtok(NULL, "\n");
1610 if (!token || !value) continue;
1611 if (value[strlen(value)-1] == '\n') value[strlen(value)-1] = 0;
1613 if (strcmp(token, "ServerName") == 0) {
1614 fServerName = value;
1616 } else if (strcmp(token, "ViewToolBar") == 0) {
1617 ViewToolBar(strcmp(value, "0") != 0);
1618 } else if (strcmp(token, "ViewTree") == 0) {
1619 ViewTree(strcmp(value, "0") != 0);
1620 } else if (strcmp(token, "ViewDescription") == 0) {
1621 ViewDescription(strcmp(value, "0") != 0);
1622 } else if (strcmp(token, "ViewReference") == 0) {
1623 ViewReference(strcmp(value, "0") != 0);
1624 } else if (strcmp(token, "ViewStatistics") == 0) {
1625 ViewStatistics(strcmp(value, "0") != 0);
1627 } else if (strcmp(token, "FavoritesFileName") == 0) {
1628 fFavoritesFileName = value;
1629 LoadFavorites(kFALSE);
1630 } else if (strcmp(token, "FavoritesSaveOnExit") == 0) {
1631 if (strcmp(value, "0") != 0) {
1632 fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
1634 fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
1637 } else if (strcmp(token, "ReferenceFileName") == 0) {
1638 fReferenceFileName = value;
1639 LoadReference(kFALSE);
1640 } else if (strcmp(token, "ReferenceThreshold") == 0) {
1641 AliMonitorHisto::SetThreshold(atof(value));
1643 } else if (strcmp(token, "LoopInterval") == 0) {
1644 fLoopInterval = atoi(value);
1645 } else if (strcmp(token, "PrintCommand") == 0) {
1646 fPrintCommand = value;
1647 } else if (strcmp(token, "SettingsSaveOnExit") == 0) {
1648 if (strcmp(value, "0") != 0) {
1649 fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
1651 fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
1657 AliDebug(1, Form("settings from file %s applied", fileName));
1661 //_____________________________________________________________________________
1662 void AliMonitorClient::SaveSettings()
1664 // save setting to the file with the name fgSettingFileName
1666 // open the text file
1667 char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(),
1668 fgSettingsFileName);
1669 FILE* file = fopen(fileName, "wt");
1672 new TGMsgBox(gClient->GetRoot(), this, "Save Settings",
1673 "The file could not be opened.",
1674 kMBIconExclamation, kMBOk, &result);
1679 // write the settings
1680 fprintf(file, "ServerName=%s\n", fServerName.Data());
1682 fprintf(file, "ViewToolBar=%d\n",
1683 fMenuView->IsEntryChecked(kMenuViewToolBar));
1684 fprintf(file, "ViewTree=%d\n",
1685 fMenuView->IsEntryChecked(kMenuViewTree));
1686 fprintf(file, "ViewDescription=%d\n",
1687 fMenuView->IsEntryChecked(kMenuViewDescription));
1688 fprintf(file, "ViewReference=%d\n",
1689 fMenuView->IsEntryChecked(kMenuViewReference));
1690 fprintf(file, "ViewStatistics=%d\n",
1691 fMenuView->IsEntryChecked(kMenuViewStatistics));
1693 if (!fFavoritesFileName.IsNull()) {
1694 fprintf(file, "FavoritesFileName=%s\n", fFavoritesFileName.Data());
1696 fprintf(file, "FavoritesSaveOnExit=%d\n",
1697 fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit));
1699 if (!fReferenceFileName.IsNull()) {
1700 fprintf(file, "ReferenceFileName=%s\n", fReferenceFileName.Data());
1702 fprintf(file, "ReferenceThreshold=%.1f\n", AliMonitorHisto::GetThreshold());
1704 fprintf(file, "LoopInterval=%d\n", fLoopInterval);
1705 fprintf(file, "PrintCommand=%s\n", fPrintCommand.Data());
1706 fprintf(file, "SettingsSaveOnExit=%d\n",
1707 fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit));
1710 AliInfo(Form("settings saved to file %s", fileName));
1715 //_____________________________________________________________________________
1716 Bool_t AliMonitorClient::GetBaseItem()
1718 // get the base item for looping over histograms
1721 // the base item is a folder
1722 fBaseItem = fCurrentItem;
1723 // if the current item is a histo, its parent is the base folder
1724 if (fBaseItem->GetParent() && fBaseItem->GetParent()->GetParent()) {
1725 fBaseItem = fBaseItem->GetParent();
1728 } else { // if no item is selected the All item is the base item
1729 fBaseItem = fAllItem;
1730 fCurrentItem = fBaseItem->GetFirstChild();
1731 if (!fCurrentItem) return kFALSE;
1737 //_____________________________________________________________________________
1738 Bool_t AliMonitorClient::GoToNextItem()
1740 // go to the next histogram in the loop
1742 if (!fCurrentItem) return kFALSE;
1743 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1745 // remember the start item to avoid an endless loop
1746 TGListTreeItem* startItem = fCurrentItem;
1749 // folder -> first child
1750 if (fCurrentItem->GetFirstChild()) {
1751 fCurrentItem = fCurrentItem->GetFirstChild();
1753 // histo -> next histo
1754 } else if ((fCurrentItem != fBaseItem) &&
1755 (fCurrentItem->GetNextSibling())) {
1756 fCurrentItem = fCurrentItem->GetNextSibling();
1758 // last histo in folder -> next folder
1759 } else if ((fCurrentItem != fBaseItem) &&
1760 (fCurrentItem->GetParent() != fBaseItem) &&
1761 fCurrentItem->GetParent()->GetNextSibling()) {
1762 fCurrentItem = fCurrentItem->GetParent()->GetNextSibling();
1764 // last histo in last folder -> first folder
1766 fCurrentItem = fBaseItem->GetFirstChild();
1769 // abort if no next item found
1770 if (fCurrentItem == startItem) return kFALSE;
1772 // end loop if an item with a monitor histo was found
1773 } while (!fCurrentItem->GetUserData());
1779 //_____________________________________________________________________________
1780 Bool_t AliMonitorClient::GoToPreviousItem()
1782 // go to the previous histogram in the loop
1784 if (!fCurrentItem) return kFALSE;
1785 if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1787 // remember the start item to avoid an endless loop
1788 TGListTreeItem* startItem = fCurrentItem;
1791 // folder -> last child
1792 if (fCurrentItem->GetFirstChild()) {
1793 fCurrentItem = fCurrentItem->GetFirstChild();
1794 while (fCurrentItem->GetNextSibling()) {
1795 fCurrentItem = fCurrentItem->GetNextSibling();
1798 // histo -> previous histo
1799 } else if ((fCurrentItem != fBaseItem) &&
1800 (fCurrentItem->GetPrevSibling())) {
1801 fCurrentItem = fCurrentItem->GetPrevSibling();
1803 // first histo in folder -> previous folder
1804 } else if ((fCurrentItem != fBaseItem) &&
1805 (fCurrentItem->GetParent() != fBaseItem) &&
1806 fCurrentItem->GetParent()->GetPrevSibling()) {
1807 fCurrentItem = fCurrentItem->GetParent()->GetPrevSibling();
1809 // first histo in first folder -> last folder
1811 fCurrentItem = fBaseItem->GetFirstChild();
1812 while (fCurrentItem->GetNextSibling()) {
1813 fCurrentItem = fCurrentItem->GetNextSibling();
1817 // abort if no next item found
1818 if (fCurrentItem == startItem) return kFALSE;
1820 // end loop if an item with a monitor histo was found
1821 } while (!fCurrentItem->GetUserData());
1827 //_____________________________________________________________________________
1828 void AliMonitorClient::UpdateItem(Bool_t highlight)
1830 // update the displayed tree for currently selected item
1832 if (highlight) { // highlight the selected item and open its parent folders
1833 TGListTreeItem* parent = fCurrentItem->GetParent();
1835 if (!parent->IsOpen()) fTree->OpenItem(parent);
1836 parent = parent->GetParent();
1838 fTree->HighlightItem(fCurrentItem);
1839 gClient->NeedRedraw(fTree);
1842 // update displayed histo
1843 UpdateDescription();
1846 // en- or disable the "Reference/Take Current" menu item
1847 TGListTreeItem* base = fCurrentItem;
1848 while (base->GetParent()) base = base->GetParent();
1849 if (base != fComparisonItem) {
1850 fMenuReference->EnableEntry(kMenuRefTakeCurrent);
1852 fMenuReference->DisableEntry(kMenuRefTakeCurrent);
1855 // en- or disable the "Favorites/Add" and "Favorites/Delete" menu items
1856 if (fCurrentItem->GetParent()) {
1857 if (base == fFavoritesItem) {
1858 fMenuFavorites->DisableEntry(kMenuFavAdd);
1859 fMenuFavorites->EnableEntry(kMenuFavDelete);
1861 fMenuFavorites->EnableEntry(kMenuFavAdd);
1862 fMenuFavorites->DisableEntry(kMenuFavDelete);
1865 fMenuFavorites->DisableEntry(kMenuFavAdd);
1866 fMenuFavorites->DisableEntry(kMenuFavDelete);
1871 //_____________________________________________________________________________
1872 Bool_t AliMonitorClient::CheckForNewData()
1874 // check whether the monitor process server sent new data
1876 // disable the socket handler in this method
1877 if (!fSocket || !fSocket->IsValid()) return kFALSE;
1878 fSocketHandler->Remove();
1880 // receive a control message from the server
1881 char controlMessage[256];
1882 if (fSocket->Recv(controlMessage, 255) <= 0) {
1883 fSocketHandler->Add();
1887 // if it is new histogram data, send ok
1888 if ((strcmp(controlMessage, "histograms") != 0) ||
1889 (fSocket->Send("ok") <= 0)) {
1890 fSocketHandler->Add();
1894 // get the histogram data
1895 TMessage* message = NULL;
1896 if (fSocket->Recv(message) <= 0) {
1897 fSocketHandler->Add();
1901 // replace the old folder of monitor histos with the new one
1902 if (message->GetClass()->InheritsFrom(TFolder::Class())) {
1903 if (fFolder) delete fFolder;
1904 fFolder = (TFolder*) message->ReadObject(message->GetClass());
1906 fSocketHandler->Add();
1911 fSocketHandler->Add();
1915 //_____________________________________________________________________________
1916 void AliMonitorClient::ClearItems(TGListTreeItem* base) const
1918 // remove the references to the histograms from all subitems of the
1921 // loop over folders
1922 TGListTreeItem* folderItem = base->GetFirstChild();
1923 while (folderItem) {
1926 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1928 histoItem->SetUserData(NULL);
1929 histoItem = histoItem->GetNextSibling();
1932 folderItem = folderItem->GetNextSibling();
1936 //_____________________________________________________________________________
1937 void AliMonitorClient::CleanUpTree(TGListTreeItem* base)
1939 // remove items without monitor histograms and
1940 // folders without monitor histograms
1942 // loop over folders
1943 TGListTreeItem* folderItem = base->GetFirstChild();
1944 while (folderItem) {
1947 TGListTreeItem* histoItem = folderItem->GetFirstChild();
1949 TGListTreeItem* deleteItem = NULL;
1950 if (!histoItem->GetUserData()) deleteItem = histoItem;
1951 histoItem = histoItem->GetNextSibling();
1952 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1953 if (deleteItem) fTree->DeleteItem(deleteItem);
1956 folderItem = folderItem->GetNextSibling();
1959 // loop over folders and remove empty folders
1960 folderItem = base->GetFirstChild();
1961 while (folderItem) {
1962 TGListTreeItem* deleteItem = NULL;
1963 if (!folderItem->GetFirstChild()) deleteItem = folderItem;
1964 folderItem = folderItem->GetNextSibling();
1965 if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1966 if (deleteItem) fTree->DeleteItem(deleteItem);
1970 //_____________________________________________________________________________
1971 void AliMonitorClient::UpdateTree()
1973 // update the tree of monitor histograms
1975 // delete references to old monitor histograms
1976 ClearItems(fAllItem);
1979 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1980 while (TFolder* folder = (TFolder*) iFolder->Next()) {
1983 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1984 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1986 // add new monitor histograms
1987 TGListTreeItem* histoItem = GetItem(fAllItem, folder->GetName(),
1988 histo->GetName(), kTRUE);
1989 histoItem->SetUserData(histo);
1996 // remove items and folders without monitor histograms
1997 CleanUpTree(fAllItem);
1999 gClient->NeedRedraw(fTree);
2002 //_____________________________________________________________________________
2003 void AliMonitorClient::UpdateFavoritesTree()
2005 // update the tree of favorite monitor histograms
2007 // loop over folders
2008 TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
2009 while (folderItem) {
2012 TGListTreeItem* histoItem = folderItem->GetFirstChild();
2015 // set monitor histo
2016 histoItem->SetUserData(GetHisto(folderItem->GetText(),
2017 histoItem->GetText()));
2018 histoItem = histoItem->GetNextSibling();
2021 folderItem = folderItem->GetNextSibling();
2025 //_____________________________________________________________________________
2026 void AliMonitorClient::UpdateComparisonTree()
2028 // update the tree of monitor histograms with significant deviation
2029 // from the reference histograms
2031 if (!fFolder) return;
2033 // delete references to old monitor histograms
2034 ClearItems(fComparisonItem);
2036 // add monitor histograms where the comparison returns a deviation
2037 // loop over folders
2038 TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
2039 while (TFolder* folder = (TFolder*) iFolder->Next()) {
2042 TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
2043 while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
2045 // compare the histo to its reference
2046 Bool_t comparison = kTRUE;
2047 if (fEventButton->IsDown()) {
2048 comparison = histo->CompareEvent(fEventNumber->GetIntNumber());
2049 } else if (fSumButton->IsDown()) {
2050 comparison = histo->CompareSum(fEventNumber->GetIntNumber());
2052 comparison = histo->CompareRun();
2055 // add it to the comparison tree in case of a bad comparison result
2057 TGListTreeItem* histoItem = GetItem(fComparisonItem, folder->GetName(),
2058 histo->GetName(), kTRUE);
2059 histoItem->SetUserData(histo);
2067 // remove items and folders without monitor histograms
2068 CleanUpTree(fComparisonItem);
2070 gClient->NeedRedraw(fTree);
2073 //_____________________________________________________________________________
2074 void AliMonitorClient::UpdateDescription()
2076 // update the description of the current monitor histogram
2078 fDescription->Clear();
2079 AliMonitorHisto* histo = NULL;
2080 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2081 if (histo) fDescription->LoadBuffer(histo->GetDescription().Data());
2083 gClient->NeedRedraw(fDescription);
2086 //_____________________________________________________________________________
2087 void AliMonitorClient::UpdateHisto()
2089 // update the current monitor histogram
2091 // clear the canvas if no histo is selected
2092 AliMonitorHisto* histo = NULL;
2093 if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2095 fDrawCanvas->GetCanvas()->Clear();
2096 fDrawCanvas->GetCanvas()->Update();
2100 // draw the histo for a single event or summed over several events or a run
2101 fDrawCanvas->GetCanvas()->cd();
2102 if (fEventButton->IsDown()) {
2103 histo->DrawEvent(fEventNumber->GetIntNumber());
2104 } else if (fSumButton->IsDown()) {
2105 histo->DrawSum(fEventNumber->GetIntNumber());
2111 //_____________________________________________________________________________
2112 void AliMonitorClient::UpdateAll()
2114 // update the trees, the histogram and the description
2117 UpdateFavoritesTree();
2118 UpdateComparisonTree();
2119 UpdateDescription();