1 // Author: Benjamin Hess 29/01/2010
3 /*************************************************************************
4 * Copyright (C) 2009-2010, Alexandru Bercuci, Benjamin Hess. *
5 * All rights reserved. *
6 *************************************************************************/
8 //////////////////////////////////////////////////////////////////////////
10 // AliEveListAnalyserEditor //
12 // The AliEveListAnalyserEditor provides the graphical func- //
13 // tionality for the AliEveListAnalyser. It creates the tabs //
14 // and canvases, when they are needed and, as well, frees allocated //
15 // memory on destruction (or if new events are loaded and thus some //
16 // tabs are closed). //
17 // The function DrawHistos() accesses the temporary file created by the //
18 // AliEveListAnalyser and draws the desired data (the file will //
19 // be created within the call of ApplyMacros()). Have a look at this //
20 // function to learn more about the structure of the file and how to //
21 // access the data. //
22 // You can add objects to the list (of analysis objects) "by clicking"! //
23 // To do this, click the "start" button in the "list" tab. Pressing it, //
24 // connects the class to signals of objects in the viewer. //
25 // You have to kinds of selection: //
27 // Secondary selection: //
28 // You can hold "CTRL"+"ALT" (depending on your system, "ALT" alone can //
29 // also be fine) and click an single object (e.g. a single cluster of a //
30 // TEvePointSet) in the viewer to add it to the list. If the object is //
31 // already in the list, it will be removed from it! //
33 // Primary selection: //
34 // Just click the object you want to add in the viewer (or as well in //
35 // the browser (left panel)). If the object is already in the list, it //
36 // will be removed from it! //
38 // For both cases: Note: //
39 // If you have added all the desired objects, please press the "stop" //
40 // button in the "list" tab to disconnect the class from the signals. //
41 // If you want to remove an object, you HAVE to use the same procedure //
42 // that you have used for adding it. e.g. you cannot(!) remove an //
43 // object added by the secondary selection method by using the primary //
44 // selection method! //
45 //////////////////////////////////////////////////////////////////////////
47 #include <EveDet/AliEveListAnalyser.h>
48 #include "AliEveListAnalyserEditor.h"
50 #include <EveBase/AliEveEventManager.h>
52 #include <TEveBrowser.h>
53 #include <TEveGedEditor.h>
54 #include <TEveMacro.h>
55 #include <TEveManager.h>
59 #include <TGButtonGroup.h>
60 #include <TGComboBox.h>
61 #include <TGFileDialog.h>
63 #include <TGListBox.h>
66 #include <TGTextEdit.h>
67 #include <TGTextEntry.h>
68 #include <TGTextView.h>
71 #include <TObjString.h>
75 #include <TTreeStream.h>
78 ClassImp(AliEveListAnalyserEditor)
80 ///////////////////////////////////////////////////////////
81 ///////////// AliEveListAnalyserEditor //////////////////
82 ///////////////////////////////////////////////////////////
83 AliEveListAnalyserEditor::AliEveListAnalyserEditor(const TGWindow* p, Int_t width, Int_t height,
84 UInt_t options, Pixel_t back) :
85 TGedFrame(p, width, height, options, back),
89 fInheritedMacroList(0),
90 fInheritSettings(kFALSE),
96 //fbAddPrimObjects(0),
101 //fbRemovePrimObjects(0),
111 fLabel1(0), fLabel2(0), fLabel3(0), fLabel4(0),
112 fLine1(0), fLine2(0), fLine3(0), fLine4(0),
115 // Creates the AliEveListAnalyserEditor.
117 // Functionality for adding objects
118 fObjectFrame = CreateEditorTabSubFrame("List");
121 TGLabel* label = new TGLabel(fObjectFrame,"Add objects via primary selection:");
122 fObjectFrame->AddFrame(label);
124 fbAddPrimObjects = new TGTextButton(fObjectFrame, "Add selected object(s)");
125 fObjectFrame->AddFrame(fbAddPrimObjects, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 3, 1));
126 fbAddPrimObjects->SetToolTipText("TODO! - Use primary selection to add \"complete\" objects like tracks, tracklets etc.\nHold the CTRL-key for multiple selection.");
127 fbAddPrimObjects->Connect("Clicked()", "AliEveListAnalyserEditor", this, "DoAddPrimSelectedObjects()");
129 fbRemovePrimObjects = new TGTextButton(fObjectFrame, "Remove selected object(s)");
130 fObjectFrame->AddFrame(fbRemovePrimObjects, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 3, 1));
131 fbRemovePrimObjects->SetToolTipText("TODO! - Hold the CTRL-key for multiple selection");
132 fbRemovePrimObjects->Connect("Clicked()", "AliEveListAnalyserEditor", this, "DoRemovePrimSelectedObjects()");
134 TGHorizontal3DLine* line = new TGHorizontal3DLine(this, 194, 8);
135 fObjectFrame->AddFrame(line, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 2, 2, 8, 8));
138 TGLabel* label = new TGLabel(fObjectFrame,"Add objects by clicking:");
139 fObjectFrame->AddFrame(label);
141 fbStart = new TGTextButton(fObjectFrame, "Start");
142 fObjectFrame->AddFrame(fbStart, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 3, 1));
143 fbStart->SetToolTipText("Start \"adding objects by clicking\":\n\nPrimary selection: Simply left-click an object in the viewer with your mouse to add it to the list analyser.\nIf you click an object that is already in the list, it will be removed from it.\n\nSecondary selection: Simply hold ALT+CTRL and left-click a single object of a TEvePointSet (e.g. single clusters or a single digit from TEveQuadSet)\nin the viewer with your mouse to add it to the list analyser.\nIf you click (in this way!) an object that is already in the list, it will be removed from it.\nNote: The key combination depends on your operating system and might be different!\n\nAlso note: Remove objects with the same type of selection you added them,\ne.g. you cannot(!) remove a single cluster added via secondary selection\nby using primary selection with this object!");
144 fbStart->Connect("Clicked()", "AliEveListAnalyserEditor", this, "DoStartAddingObjects()");
146 fbReset = new TGTextButton(fObjectFrame, "Reset");
147 fObjectFrame->AddFrame(fbReset, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 1, 1));
148 fbReset->SetToolTipText("Remove all(!) objects from the list");
149 fbReset->Connect("Clicked()", "AliEveListAnalyserEditor", this, "DoResetObjectList()");
151 fbStop = new TGTextButton(fObjectFrame, "Stop");
152 fObjectFrame->AddFrame(fbStop, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 1, 4));
153 fbStop->SetToolTipText("Stop \"adding objects by clicking\"");
154 fbStop->Connect("Clicked()", "AliEveListAnalyserEditor", this, "DoStopAddingObjects()");
156 // Functionality for adding macros
157 fMainFrame = CreateEditorTabSubFrame("Process");
159 fLabel1 = new TGLabel(fMainFrame,"Add plugin(s):");
160 fMainFrame->AddFrame(fLabel1);
161 fBrowseFrame = new TGHorizontalFrame(fMainFrame);
163 fteField = new TGTextEntry(fBrowseFrame);
164 fteField->SetToolTipText("Enter the pathname of the macro you want to add here and press \"Enter\"");
165 fteField->Connect("ReturnPressed()","AliEveListAnalyserEditor", this, "HandleMacroPathSet()");
166 fBrowseFrame->AddFrame(fteField);
168 fbBrowse = new TGTextButton(fBrowseFrame, "Browse");
169 fbBrowse->SetToolTipText("Browse the macro you want to add");
170 fbBrowse->Connect("Clicked()", "AliEveListAnalyserEditor", this, "BrowseMacros()");
171 fBrowseFrame->AddFrame(fbBrowse);
173 fbNew = new TGTextButton(fBrowseFrame, "New");
174 fbNew->SetToolTipText("Start macro creation wizard");
175 fbNew->Connect("Clicked()", "AliEveListAnalyserEditor", this, "NewMacros()");
176 fBrowseFrame->AddFrame(fbNew);
177 fMainFrame->AddFrame(fBrowseFrame);
179 fLine1 = new TGHorizontal3DLine(fMainFrame, 194, 8);
180 fMainFrame->AddFrame(fLine1, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 8, 2));
181 fLabel2 = new TGLabel(fMainFrame,"Selection plugins:");
182 fMainFrame->AddFrame(fLabel2);
184 ftlMacroSelList = new TGListBox(fMainFrame);
185 ftlMacroSelList->Resize(194, 94);
186 ftlMacroSelList->SetMultipleSelections(kTRUE);
187 fMainFrame->AddFrame(ftlMacroSelList);
189 fLine2 = new TGHorizontal3DLine(fMainFrame, 194, 8);
190 fMainFrame->AddFrame(fLine2, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 8, 2));
191 fLabel3 = new TGLabel(fMainFrame,"Process plugins:");
192 fMainFrame->AddFrame(fLabel3);
194 ftlMacroList = new TGListBox(fMainFrame);
195 ftlMacroList->Resize(194, 94);
196 ftlMacroList->SetMultipleSelections(kTRUE);
197 fMainFrame->AddFrame(ftlMacroList);
199 fLine3 = new TGHorizontal3DLine(fMainFrame, 194, 8);
200 fMainFrame->AddFrame(fLine3, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 8, 2));
202 fbApplyMacros = new TGTextButton(fMainFrame, "Apply plugin(s)");
203 fbApplyMacros->SetToolTipText("Apply all selected macros/class functins to the list of objects -> A data file will be generated");
204 fbApplyMacros->Connect("Clicked()", "AliEveListAnalyserEditor", this, "ApplyMacros()");
205 fbApplyMacros->SetRightMargin(12);
206 fMainFrame->AddFrame(fbApplyMacros);
208 fbRemoveMacros = new TGTextButton(fMainFrame, "Remove plugin(s)");
209 fbRemoveMacros->SetToolTipText("Remove the selected macros/class functions from the list(s)");
210 fbRemoveMacros->Connect("Clicked()", "AliEveListAnalyserEditor", this, "RemoveMacros()");
211 fMainFrame->AddFrame(fbRemoveMacros);
213 // Stuff for displaying histograms
214 fHistoFrame = CreateEditorTabSubFrame("Results");
215 fHistoFrame->SetMapSubwindows(kTRUE);
216 fLabel4 = new TGLabel(fHistoFrame,"Data from plugins:");
217 fHistoFrame->AddFrame(fLabel4);
219 fHistoSubFrame = new TGVerticalFrame(fHistoFrame);
220 fHistoSubFrame->SetMapSubwindows(kTRUE);
221 fHistoSubFrame->Resize(194, 200);
222 fHistoFrame->AddFrame(fHistoSubFrame);
224 fLine4 = new TGHorizontal3DLine(fHistoFrame, 194, 8);
225 fHistoFrame->AddFrame(fLine4, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 8, 2));
227 fbDrawHisto = new TGTextButton(fHistoFrame, "Draw projections");
228 fbDrawHisto->SetToolTipText("Uses the data file created by the last \"Apply selected plugin(s)\".\nClick here to display the data histograms of the selected macros.\nSelect multiple macros to create multi-dimensional plots.\nHisto macros cannot be used for multi-dimensional plots!");
229 fbDrawHisto->Connect("Clicked()", "AliEveListAnalyserEditor", this, "DrawHistos()");
230 fHistoFrame->AddFrame(fbDrawHisto);
232 // Set up file dialog
233 fFileInfo = new TGFileInfo();
234 fFileInfo->SetMultipleSelection(kTRUE);
236 fFileTypes = new Char_t*[6];
237 fFileTypes[0] = (Char_t*)"All files"; fFileTypes[1] = (Char_t*)"*";
238 fFileTypes[2] = (Char_t*)"ROOT macros"; fFileTypes[3] = (Char_t*)"*.C";
239 fFileTypes[4] = 0; fFileTypes[5] = 0;
240 fFileInfo->fFileTypes = (const Char_t**)fFileTypes;
241 fFileInfo->fFileTypeIdx = 2;
242 fFileInfo->fMultipleSelection = kTRUE;
244 fHistoCanvasName = new TGString("");
246 // Handle the signal "Selected(Int_t ind)"
247 ftlMacroList->Connect("Selected(Int_t)", "AliEveListAnalyserEditor", this, "UpdateMacroListSelection(Int_t)");
248 ftlMacroSelList->Connect("Selected(Int_t)", "AliEveListAnalyserEditor", this, "UpdateMacroListSelection(Int_t)");
250 // Handle the signal "NewEventLoaded"
251 AliEveEventManager::GetMaster()->Connect("NewEventLoaded()", "AliEveListAnalyserEditor", this, "HandleNewEventLoaded()");
253 // Handle the signal "Selected" (another tab has been selected)
254 GetGedEditor()->GetTab()->Connect("Selected(Int_t)", "AliEveListAnalyserEditor", this, "HandleTabChangedToIndex(Int_t)");
257 //______________________________________________________
258 AliEveListAnalyserEditor::~AliEveListAnalyserEditor()
260 // Destructor: Closes all tabs created by this object and
261 // frees the corresponding memory.
265 delete [] fFileTypes;
274 // Close and delete all tabs that have been created by this class
277 if (fHistoCanvasName != 0)
279 delete fHistoCanvasName;
280 fHistoCanvasName = 0;
283 if (fInheritedMacroList != 0)
285 fInheritedMacroList->Delete();
286 delete fInheritedMacroList;
287 fInheritedMacroList = 0;
291 //______________________________________________________
292 void AliEveListAnalyserEditor::AddMacro(const Char_t* name, const Char_t* path)
294 // Adds the macro path/name to the macro list. A warning is provided, if there is
295 // something wrong, e.g. if the macro does not have the correct signature.
296 Int_t result = fM->AddMacro(path, name);
304 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Warning", "Macro is already in list (won't be added again)!",
305 kMBIconExclamation, kMBOk);
308 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", "Failed to load the macro (check messages in the terminal)!",
309 kMBIconExclamation, kMBOk);
311 case SIGNATURE_ERROR:
312 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
313 "Macro has not the signature of...\n...a single object selection macro: Bool_t YourMacro(const YourObjectType*)\n...a correlated objects selection macro: Bool_t YourMacro(const YourObjectType*, const YourObjectType2*)\n...a single object analyse macro: void YourMacro(const YourObjectType*, Double_t*&, Int_t&)\n...a correlated objects analyse macro: void YourMacro(const YourObjectType*, const YourObjectType2*, Double_t*&, Int_t&)\n...a single object histo macro: TH1* YourMacro(const YourObjectType*)\n...a correlated objects histo macro: TH1* YourMacro(const YourObjectType*, const YourObjectType2*)",
314 kMBIconExclamation, kMBOk);
316 case NOT_EXIST_ERROR:
317 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
318 "File does not exist or you do not have read permission!", kMBIconExclamation, kMBOk);
320 case UNKNOWN_OBJECT_TYPE_ERROR:
321 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
322 "Unknown object type of macro parameter!", kMBIconExclamation, kMBOk);
325 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
326 Form("AliEveListAnalyser::AddMacro exited with unknown return value: %d", result),
327 kMBIconExclamation, kMBOk);
332 //______________________________________________________
333 void AliEveListAnalyserEditor::ApplyMacros()
335 // Applies the selected macros and updates the view.
337 Bool_t success = kFALSE;
339 // First apply the single object selection macros
340 TList* selIterator = new TList();
341 ftlMacroSelList->GetSelectedEntries(selIterator);
342 fM->ApplySOSelectionMacros(selIterator);
347 // Now apply the process macros
348 TList* procIterator = new TList();
349 ftlMacroList->GetSelectedEntries(procIterator);
350 success = fM->ApplyProcessMacros(selIterator, procIterator);
352 // Update histogram tab (data has to be reloaded)
356 // AliEveListAnalyser::ApplyProcessMacros() automatically selects a macro -> Draw the histogram for it,
357 // if a process macro has been applied
358 if (success && procIterator->GetEntries() > 0)
360 // Set focus on "Histograms" tab
361 GetGedEditor()->GetTab()->SetTab("Results");
370 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
371 "AliEveListAnalyser::ApplyProcessMacros experienced an error (cf. CINT-output)!",
372 kMBIconExclamation, kMBOk);
376 //______________________________________________________
377 void AliEveListAnalyserEditor::BrowseMacros()
379 // Creates a file-dialog. The selected files will be added to the macro list
380 // via AddMacro(...).
382 new TGFileDialog(gClient->GetRoot(), GetMainFrame(), kFDOpen, fFileInfo);
384 if (fFileInfo->fIniDir != 0 && fFileInfo->fFileNamesList != 0)
387 TObject* iter = fFileInfo->fFileNamesList->First();
393 // NOTE: fileInfo->fFileNamesList will be changed by that, too!
394 name = (Char_t*)strrchr(iter->GetName(), '/');
395 // Delete '"' at the end
396 name[strlen(name)] = '\0';
398 AddMacro(name + 1, fFileInfo->fIniDir);
399 iter = (TObjString*)fFileInfo->fFileNamesList->After(iter);
404 //______________________________________________________
405 void AliEveListAnalyserEditor::CloseTabs()
407 // Closes + deletes the tabs created by this object
409 if (fHistoCanvas != 0)
411 // Close the created tab, if it exists
412 if (fHistoCanvasName != 0)
414 if (gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString()))
416 // Now the created tab is the current one and can be deleted
417 gEve->GetBrowser()->GetTab(1)->RemoveTab();
420 // With the tab removal, the canvas will be deleted automatically!
426 //______________________________________________________
427 void AliEveListAnalyserEditor::DoAddPrimSelectedObjects()
429 // Adds the selected object(s) to the list ("primary selection").
431 fM->AddPrimSelectedObjects();
434 //______________________________________________________
435 void AliEveListAnalyserEditor::DoRemovePrimSelectedObjects()
437 // Removes the selected object(s) from the list ("primary selection").
439 fM->RemovePrimSelectedObjects();
443 //______________________________________________________
444 void AliEveListAnalyserEditor::DoResetObjectList()
446 // Removes all objects from the list.
448 fM->ResetObjectList();
452 //______________________________________________________
453 void AliEveListAnalyserEditor::DoStartAddingObjects()
455 // Starts adding objects for the analysis.
457 if (fM->StartAddingObjects())
459 fbStart->SetState(kButtonDisabled);
460 fbStop->SetState(kButtonUp);
464 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", "Failed to connect socket!", kMBIconExclamation, kMBOk);
466 if (fM->GetConnected())
468 fbStop->SetState(kButtonDisabled);
469 fbStart->SetState(kButtonUp);
474 //______________________________________________________
475 void AliEveListAnalyserEditor::DoStopAddingObjects()
477 // Stops adding objects for the analysis.
479 if (fM->StopAddingObjects())
481 fbStop->SetState(kButtonDisabled);
482 fbStart->SetState(kButtonUp);
486 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", "Failed to disconnect socket!", kMBIconExclamation, kMBOk);
488 if (fM->GetConnected())
490 fbStop->SetState(kButtonUp);
491 fbStart->SetState(kButtonDisabled);
496 //______________________________________________________
497 void AliEveListAnalyserEditor::DrawHistos()
499 // Accesses the temporary data file created by the last call of ApplyMacros() and draws
500 // histograms according to the selection in the "Histograms"-tab.
502 Int_t nHistograms = GetNSelectedHistograms();
503 if (nHistograms <= 0)
505 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
506 "No data selected. Please select the data you want to plot!", kMBIconExclamation, kMBOk);
511 new TGMsgBox(gClient->GetRoot(), GetMainFrame(),
512 "Error", "Only histograms with up to 3 dimensions supported. Please select 1,2 or 3 data macros!",
513 kMBIconExclamation, kMBOk);
517 // Check, if a histo macro shall be drawn
518 Int_t indexOfHistoMacro = -1;
519 Int_t selectedChecked = 0;
520 for (Int_t j = 0; j < fM->fDataFromMacroList->GetEntries(); j++)
522 if (fCheckButtons[j]->TGButton::GetState() == kButtonDown)
526 // Histo macro? -> To check this, look for the substring "(histo macro)"
527 if (strstr(fM->fDataFromMacroList->At(j)->GetName(), "(histo macro)") != 0)
529 // Is also another macro selected?
532 // Histo macros cannot(!) be correlated!
533 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
534 "Histo macros (return value \"TH1*\") cannot be combined with other macros",
535 kMBIconExclamation, kMBOk);
539 // Mark this histo macro for drawing
540 indexOfHistoMacro = j;
542 // Have all selected macros been checked? -> If yes, we are done with this
543 if (selectedChecked == nHistograms) break;
548 TFile* file = new TFile(Form("/tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER")), "READ");
551 Error("Draw histograms", Form("Cannot open file \"/tmp/ListAnalyserMacroData_%s.root\"",
552 gSystem->Getenv("USER")));
553 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
554 Form("Cannot open file \"/tmp/ListAnalyserMacroData_%s.root\"", gSystem->Getenv("USER")),
555 kMBIconExclamation, kMBOk);
563 Int_t indexOfMacro1 = 0;
564 Int_t indexOfMacro2 = 0;
565 Int_t indexOfMacro3 = 0;
567 // Variable for the loop below -> Will be set to aborting value, if a histo macro is drawn
571 if (indexOfHistoMacro >= 0)
573 if ((t = (TTree*)file->Get(Form("ObjectData%d", indexOfHistoMacro))))
575 SetDrawingToHistoCanvasTab();
578 t->SetBranchAddress(Form("Macro%d", indexOfHistoMacro), &myHist);
580 if (myHist != 0) myHist->Draw();
583 Error("Draw histograms", Form("No histogram for histo macro \"%s\" found!",
584 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()));
585 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
586 Form("No histogram for histo macro \"%s\" found!",
587 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()), kMBIconExclamation, kMBOk);
591 UpdateHistoCanvasTab();
595 Error("Draw histograms", Form("No data for histo macro \"%s\" found!\nMaybe no objects have been selected.",
596 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()));
597 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
598 Form("No data for histo macro \"%s\" found!\nMaybe no objects have been selected.",
599 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()), kMBIconExclamation, kMBOk);
602 // Skip the loop below
603 i = fM->fDataFromMacroList->GetEntries();
606 // Load the trees in succession and remember the entries -> Plot the analyse macros
607 for ( ; i < fM->fDataFromMacroList->GetEntries(); i++)
609 if (fCheckButtons[i]->TGButton::GetState() == kButtonDown)
614 if (!(t = (TTree*)file->Get(Form("ObjectData%d", i))))
616 Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
617 fM->fDataFromMacroList->At(i)->GetName()));
618 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
619 Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
620 fM->fDataFromMacroList->At(i)->GetName()), kMBIconExclamation, kMBOk);
625 if (nHistograms == 1)
627 SetDrawingToHistoCanvasTab();
629 t->Draw(Form("Macro%d", indexOfMacro1), "1");
630 ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s;%s",
631 fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
632 fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
633 UpdateHistoCanvasTab();
638 else if (tFriend1 == 0)
641 if (!(tFriend1 = (TTree*)file->Get(Form("ObjectData%d", i))))
643 Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
644 fM->fDataFromMacroList->At(i)->GetName()));
645 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
646 Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
647 fM->fDataFromMacroList->At(i)->GetName()),
648 kMBIconExclamation, kMBOk);
653 if (nHistograms == 2)
655 SetDrawingToHistoCanvasTab();
657 t->AddFriend(tFriend1);
658 t->Draw(Form("Macro%d:Macro%d", indexOfMacro1, indexOfMacro2), "1");
659 ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s - %s;%s;%s",
660 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
661 fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
662 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
663 fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
665 UpdateHistoCanvasTab();
674 if (!(tFriend2 = (TTree*)file->Get(Form("ObjectData%d", i))))
676 Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
677 fM->fDataFromMacroList->At(i)->GetName()));
678 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
679 Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
680 fM->fDataFromMacroList->At(i)->GetName()), kMBIconExclamation, kMBOk);
684 SetDrawingToHistoCanvasTab();
686 t->AddFriend(tFriend1);
687 t->AddFriend(tFriend2);
688 t->Draw(Form("Macro%d:Macro%d:Macro%d", indexOfMacro1, indexOfMacro2, indexOfMacro3), "1");
689 ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s - %s - %s;%s;%s;%s",
690 fM->fDataFromMacroList->At(indexOfMacro3)->GetName(),
691 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
692 fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
693 fM->fDataFromMacroList->At(indexOfMacro3)->GetName(),
694 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
695 fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
697 UpdateHistoCanvasTab();
704 if (t != 0) delete t;
706 if (tFriend1 != 0) delete tFriend1;
708 if (tFriend2 != 0) delete tFriend2;
716 //______________________________________________________
717 Int_t AliEveListAnalyserEditor::GetNSelectedHistograms() const
719 // Returns the number of selected macros (or rather: of their selected data) in the "Histograms"-tab
723 for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries(); i++)
725 if (fCheckButtons[i]->TGButton::GetState() == kButtonDown) count++;
731 //______________________________________________________
732 void AliEveListAnalyserEditor::HandleMacroPathSet()
734 // Takes the input of the text field (adding a macro), checks if the macro can be
735 // accessed (and that it exists) and adds the macro to the macro list via AddMacro(...).
736 // You can use environment variables in the text field, e.g. "$ALICE_ROOT/Eve/alice-macro/myMacro.C".
738 if (strlen(fteField->GetText()) != 0)
740 // Expand the pathname
741 Char_t* systemPath = gSystem->ExpandPathName(fteField->GetText());
742 fteField->SetText(systemPath);
746 // Check if file exists
749 fp = fopen(fteField->GetText(), "rb");
755 Char_t* name = (Char_t*)strrchr(fteField->GetText(), '/');
760 name = new Char_t[AliEveListAnalyser::fkMaxMacroNameLength];
761 memset(name, '\0', sizeof(Char_t) * AliEveListAnalyser::fkMaxMacroNameLength);
762 snprintf(name, AliEveListAnalyser::fkMaxMacroNameLength, "%s", fteField->GetText());
764 // Add path to textfield -> Path is "./" -> Use length for the name + 2
765 Char_t pathname[AliEveListAnalyser::fkMaxMacroNameLength + 2];
766 memset(pathname, '\0', sizeof(Char_t) * (AliEveListAnalyser::fkMaxMacroNameLength + 2));
767 snprintf(pathname, AliEveListAnalyser::fkMaxMacroNameLength + 2, "./%s", fteField->GetText());
768 fteField->SetText(pathname);
777 Char_t* path = new Char_t[AliEveListAnalyser::fkMaxMacroPathLength];
778 memset(path, '\0', sizeof(Char_t) * AliEveListAnalyser::fkMaxMacroPathLength);
779 strncpy(path, fteField->GetText(), strlen(fteField->GetText()) - strlen(name));
781 // Ignore the slash "/" in name
782 AddMacro(name + 1, path);
788 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
789 "File does not exist or you do not have read permission!", kMBIconExclamation, kMBOk);
794 //______________________________________________________
795 void AliEveListAnalyserEditor::HandleNewEventLoaded()
797 // Closes the tabs created by this object and sets a flag that will
798 // cause the function SetModel() to inherit the macro lists
799 // for the next AliEveListAnalyser from the current one.
801 // Inherit the macro list for the next analyse object list!
802 fInheritSettings = kTRUE;
808 //______________________________________________________
809 void AliEveListAnalyserEditor::HandleTabChangedToIndex(Int_t index)
811 // Saves the current tab in the current AliEveListAnalyser.
813 fM->SetSelectedTab(index);
816 //______________________________________________________
817 void AliEveListAnalyserEditor::InheritMacroList()
819 // The old macro list is possibly stored in the corresponding interior map. This function will
820 // use this interior map to move the data from the interior map to the newly loaded AliEveListAnalyser.
821 // Then the interior map will be cleaned up. With this, the settings will be inherited from the previously
822 // loaded AliEveListAnalyser.
824 if (fInheritedMacroList == 0) return;
827 fM->fMacroList->Delete();
829 // Store data from interior list in the analyse object list's map
830 TMapIter* iter = (TMapIter*)fInheritedMacroList->MakeIterator();
833 TGeneralMacroData* macro = 0;
835 while ((key = iter->Next()) != 0)
837 macro = (TGeneralMacroData*)fInheritedMacroList->GetValue(key);
838 if (macro != 0) fM->fMacroList->Add(new TObjString(key->GetName()),
839 new TGeneralMacroData(macro->GetName(), macro->GetPath(), macro->GetType(),
840 macro->GetObjectType(), macro->GetObjectType2()));
843 Error("AliEveListAnalyserEditor::InheritMacroList", Form("Failed to inherit the macro \"%s\"!", key->GetName()));
847 fInheritedMacroList->Delete();
848 delete fInheritedMacroList;
849 fInheritedMacroList = 0;
852 //______________________________________________________
853 void AliEveListAnalyserEditor::NewMacros()
855 // Start the macro creation wizard.
856 // thanks to Jacek Otwinowski<J.Otwinowski@GSI.DE> for this suggestion
858 AliEveGeneralMacroWizard *wizz = new AliEveGeneralMacroWizard();
859 wizz->Connect("Create(Char_t*)", "AliEveListAnalyserEditor", this, "AddMacro(Char_t*)");
862 //______________________________________________________
863 void AliEveListAnalyserEditor::RemoveMacros()
865 // Removes the selected macros from the corresponding list.
867 TList* iterator = new TList();
869 ftlMacroList->GetSelectedEntries(iterator);
870 fM->RemoveSelectedMacros(iterator);
874 iterator = new TList();
875 ftlMacroSelList->GetSelectedEntries(iterator);
876 fM->RemoveSelectedMacros(iterator);
878 // Selected macros are deleted from the list -> No selected entries left
879 fM->fMacroListSelected = 0;
885 //______________________________________________________
886 void AliEveListAnalyserEditor::SaveMacroList(TMap* list)
888 // Saves the provided macro list in an interior list. This list will be used by
889 // InheritMacroList() to restore the data in "list". With this method one is able
890 // to inherit the macro list from analyse object list to analyse object list (i.e. from event to event).
892 if (fInheritedMacroList != 0)
894 fInheritedMacroList->Delete();
895 delete fInheritedMacroList;
897 fInheritedMacroList = new TMap();
898 fInheritedMacroList->SetOwnerKeyValue(kTRUE, kTRUE);
900 TMapIter* iter = (TMapIter*)list->MakeIterator();
902 TGeneralMacroData* macro = 0;
904 while ((key = iter->Next()) != 0)
906 macro = (TGeneralMacroData*)fM->fMacroList->GetValue(key);
907 if (macro != 0) fInheritedMacroList->Add(new TObjString(key->GetName()),
908 new TGeneralMacroData(macro->GetName(), macro->GetPath(), macro->GetType(),
909 macro->GetObjectType(), macro->GetObjectType2()));
912 Error("AliEveListAnalyserEditor::SaveMacroList", Form("Failed to inherit the macro \"%s\"!", key->GetName()));
917 //______________________________________________________
918 void AliEveListAnalyserEditor::SetDrawingToHistoCanvasTab()
920 // Sets gPad to the tab with the name of the current AliEveListAnalyser. If this tab does
921 // not exist, it will be created. Otherwise, it is re-used.
923 // If the tab with the canvas has been closed, the canvas will be deleted.
924 // So, if there is no tab, set the canvas pointer to zero and recreate it in a new tab.
925 if (fHistoCanvas != 0)
927 if (gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString()) == 0)
935 fHistoCanvas = gEve->AddCanvasTab(fM->GetName());
941 //______________________________________________________
942 void AliEveListAnalyserEditor::SetModel(TObject* obj)
944 // Sets the model object, updates the related data in the GUI and
945 // inherits settings (cf. Inherit*(...)), if the flag fInheritSettings is set to kTRUE.
947 fM = dynamic_cast<AliEveListAnalyser*>(obj);
951 Error("SetModel", "Parameter is zero pointer");
955 // Provide a pointer to this editor
958 // If macro list + track style shall be inherited from previously loaded track list, do so
959 if (fInheritSettings)
963 fInheritSettings = kFALSE;
970 GetGedEditor()->GetTab()->SetTab(fM->GetSelectedTab());
972 // Set connection buttons correctly
973 if(fM->GetConnected())
975 fbStart->SetState(kButtonDisabled);
976 fbStop->SetState(kButtonUp);
980 fbStop->SetState(kButtonDisabled);
981 fbStart->SetState(kButtonEngaged);
982 fbStart->SetState(kButtonUp);
986 //______________________________________________________
987 void AliEveListAnalyserEditor::UpdateDataFromMacroListSelection()
989 // Saves the current selection in the "Histograms"-tab to the current
990 // AliEveListAnalyser. This means that the selection is updated and won't
991 // get lost, if another editor is loaded in Eve.
993 for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries(); i++)
995 fM->SetHistoDataSelection(i, fCheckButtons[i]->IsOn());
999 //______________________________________________________
1000 void AliEveListAnalyserEditor::UpdateHistoCanvasTab()
1002 // Updates the histogram and the corresponding tab (including titles).
1004 // Update name of the tab (tab has been set to current tab!)
1005 fHistoCanvasName->SetString(fM->GetName());
1007 // Use a copy of fHistoCanvasName!! -> If the user closes a tab manually, the TGString
1008 // will be deleted -> Error might occur, when accessing the pointer
1009 gEve->GetBrowser()->GetTab(1)->GetCurrentTab()->SetText(new TGString(fHistoCanvasName));
1011 // Switch tabs to force redrawing
1012 gEve->GetBrowser()->GetTab(1)->SetTab(0);
1013 gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString());
1014 fHistoCanvas->Update();
1017 //______________________________________________________
1018 void AliEveListAnalyserEditor::UpdateHistoList()
1020 // Reloads (updates) the buttons in the "Histograms"-tab via
1021 // the current AliEveListAnalyser (data).
1023 fHistoSubFrame->TGCompositeFrame::Cleanup();
1025 // Set buttons for histograms
1026 if (fCheckButtons != 0) delete fCheckButtons;
1027 fCheckButtons = new TGCheckButton*[fM->fDataFromMacroList->GetEntries()];
1029 TObjString* iter = (TObjString*)fM->fDataFromMacroList->First();
1030 for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries() && iter != 0; i++)
1032 fCheckButtons[i] = new TGCheckButton(fHistoSubFrame, iter->GetName());
1033 fHistoSubFrame->AddFrame(fCheckButtons[i]);
1035 fCheckButtons[i]->SetState(kButtonUp, kFALSE);
1036 fCheckButtons[i]->MapRaised();
1037 fCheckButtons[i]->SetOn(fM->HistoDataIsSelected(i));
1038 fCheckButtons[i]->Connect("Clicked()", "AliEveListAnalyserEditor", this, "UpdateDataFromMacroListSelection()");
1040 iter = (TObjString*)fM->fDataFromMacroList->After(iter);
1044 //______________________________________________________
1045 void AliEveListAnalyserEditor::UpdateMacroList()
1047 // Reloads (updates) the macro list (selection AND process macros) via
1048 // the current AliEveListAnalyser (data).
1050 ftlMacroList->RemoveAll();
1051 ftlMacroSelList->RemoveAll();
1053 TMapIter* iter = (TMapIter*)fM->fMacroList->MakeIterator();
1055 TGeneralMacroData* macro = 0;
1058 while ((key = iter->Next()) != 0)
1060 macro = (TGeneralMacroData*)fM->fMacroList->GetValue(key);
1063 if (macro->IsProcessMacro())
1065 ftlMacroList->AddEntry(macro->GetName(), ind);
1066 // Select, what has been selected before
1067 ftlMacroList->Select(ind, fM->MacroListIsSelected(ind));
1070 else if (macro->IsSelectionMacro())
1072 ftlMacroSelList->AddEntry(macro->GetName(), ind);
1073 // Select, what has been selected before
1074 ftlMacroSelList->Select(ind, fM->MacroListIsSelected(ind));
1079 Error("AliEveListAnalyserEditor::UpdateMacroList()",
1080 Form("Macro \"%s/%s.C\" is neither a selection macro nor a process macro!",
1081 macro->GetPath(), macro->GetName()));
1086 Error("AliEveListAnalyserEditor::UpdateMacroList()",
1087 Form("Macro list is corrupted: Macro \"%s\" not found!", key->GetName()));
1091 ftlMacroList->SortByName();
1092 ftlMacroSelList->SortByName();
1095 //______________________________________________________
1096 void AliEveListAnalyserEditor::UpdateMacroListSelection(Int_t ind)
1098 // Saves the current selection in the macro listS to the current
1099 // AliEveListAnalyser. This means that the selection is updated and won't
1100 // get lost, if another editor is loaded in Eve.
1101 // NOTE: The indices in BOTH lists will be unique!
1103 // Toggle selected item
1104 fM->SetMacroListSelection(ind, !fM->MacroListIsSelected(ind));
1108 //______________________________________________________
1109 //______________________________________________________
1110 //______________________________________________________
1113 /////////////////////////////////////////////////
1114 ClassImp(AliEveGeneralMacroWizard)
1115 /////////////////////////////////////////////////
1117 //______________________________________________________
1118 AliEveGeneralMacroWizard::AliEveGeneralMacroWizard(const TGWindow* p)
1119 :TGMainFrame(p ? p : gClient->GetRoot(), 10, 10, kMainFrame | kVerticalFrame)
1126 ,fTextObjectType(0x0)
1127 ,fTextObjectType2(0x0)
1129 // Creates the macro wizard.
1131 const Int_t width = 300;
1134 TGHorizontalFrame *fFrameName = new TGHorizontalFrame(this, 10, 10, kHorizontalFrame);
1135 TGLabel *fLabel = new TGLabel(fFrameName, "Name*");
1136 fLabel->SetTextJustify(36);
1137 fLabel->SetMargins(0,0,0,0);
1138 fLabel->SetWrapLength(-1);
1139 fFrameName->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1141 fTextName = new TGTextEntry(fFrameName);
1142 fTextName->SetMaxLength(255);
1143 fTextName->SetAlignment(kTextLeft);
1144 fTextName->SetText("");
1145 fTextName->SetToolTipText("The name of your macro");
1146 fTextName->Resize(width, fTextName->GetDefaultHeight());
1147 fFrameName->AddFrame(fTextName, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1150 TGHorizontalFrame *fFrameObjectType = new TGHorizontalFrame(this, 10, 10, kHorizontalFrame);
1151 fLabel = new TGLabel(fFrameObjectType, "1st object type of macro");
1152 fLabel->SetTextJustify(36);
1153 fLabel->SetMargins(0,0,0,0);
1154 fLabel->SetWrapLength(-1);
1155 fFrameObjectType->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1157 fTextObjectType = new TGTextEntry(fFrameObjectType);
1158 fTextObjectType->SetAlignment(kTextLeft);
1159 fTextObjectType->SetText("");
1160 // Limit max.length to 80 characters
1161 fTextObjectType->SetMaxLength(80);
1162 fTextObjectType->SetToolTipText("The type of objects, your macro will work with (type of the first pointer)");
1163 fTextObjectType->Resize(width, fTextObjectType->GetDefaultHeight());
1164 fFrameObjectType->AddFrame(fTextObjectType, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1167 TGHorizontalFrame *fFrameObjectType2 = new TGHorizontalFrame(this, 10, 10, kHorizontalFrame);
1168 fLabel = new TGLabel(fFrameObjectType2, "2nd object type of macro (pair");
1169 fLabel->SetTextJustify(36);
1170 fLabel->SetMargins(0,0,0,0);
1171 fLabel->SetWrapLength(-1);
1172 fFrameObjectType2->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1174 fTextObjectType2 = new TGTextEntry(fFrameObjectType2);
1175 fTextObjectType2->SetAlignment(kTextLeft);
1176 fTextObjectType2->SetText("");
1177 // Limit max.length to 80 characters
1178 fTextObjectType2->SetMaxLength(80);
1179 fTextObjectType2->SetToolTipText("The type of objects, your macro will work with (type of the second pointer)\nOnly needed for macros dealing with object pairs");
1180 fTextObjectType2->Resize(width, fTextObjectType2->GetDefaultHeight());
1181 fFrameObjectType2->AddFrame(fTextObjectType2, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1182 fTextObjectType2->SetEnabled(kFALSE);
1185 TGHorizontalFrame *fFrameIncludes = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1186 fLabel = new TGLabel(fFrameIncludes, "Include files");
1187 fLabel->SetTextJustify(36);
1188 fLabel->SetMargins(0,0,0,0);
1189 fLabel->SetWrapLength(-1);
1190 fFrameIncludes->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1192 fTextIncludes = new TGTextEntry(fFrameIncludes);
1193 fTextObjectType->SetAlignment(kTextLeft);
1194 fTextIncludes->SetText("<TRD/AliTRDgeometry.h>,<TRD/AliTRDcluster.h>,<TRD/AliTRDseedV1.h>,<TRD/AliTRDtrackV1.h>");
1195 fTextIncludes->SetCursorPosition(0);
1196 fTextIncludes->SetToolTipText("The include files for your macro - separated by commas! -\n e.g. \"<TRD/AliTRDcluster.h>,<TRD/AliTRDtrackV1.h>\".\nThe suggested/default files can be used for track analysis");
1197 fTextIncludes->Resize(width, fTextIncludes->GetDefaultHeight());
1198 fFrameIncludes->AddFrame(fTextIncludes, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1201 TGHorizontalFrame *fFrameComment = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1202 fLabel = new TGLabel(fFrameComment, "Comment");
1203 fLabel->SetTextJustify(36);
1204 fLabel->SetMargins(0,0,0,0);
1205 fLabel->SetWrapLength(-1);
1206 fFrameComment->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1208 fTextEdit = new TGTextEdit(fFrameComment, width, 5*fTextName->GetDefaultHeight());
1209 fFrameComment->AddFrame(fTextEdit, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1212 TGHorizontalFrame *fFrameType = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1213 fLabel = new TGLabel(fFrameType, "Type*");
1214 fLabel->SetTextJustify(36);
1215 fLabel->SetMargins(0,0,0,0);
1216 fLabel->SetWrapLength(-1);
1217 fFrameType->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1219 fCombo = new TGComboBox(fFrameType, -1, kHorizontalFrame | kSunkenFrame | kDoubleBorder | kOwnBackground);
1220 fCombo->AddEntry("Single Object Selection", AliEveListAnalyser::kSingleObjectSelect);
1221 fCombo->AddEntry("Pair Objects Selection", AliEveListAnalyser::kCorrelObjectSelect);
1222 fCombo->AddEntry("Single Object Analyse", AliEveListAnalyser::kSingleObjectAnalyse);
1223 fCombo->AddEntry("Single Object Histo", AliEveListAnalyser::kSingleObjectHisto);
1224 fCombo->AddEntry("Pair Objects Analyse", AliEveListAnalyser::kCorrelObjectAnalyse);
1225 fCombo->AddEntry("Pair Objects Histo", AliEveListAnalyser::kCorrelObjectHisto);
1227 fCombo->Resize(width, fTextName->GetDefaultHeight());
1228 fFrameType->AddFrame(fCombo, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1231 TGHorizontalFrame *fFrameAction = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1232 fbCancel = new TGTextButton(fFrameAction, "Cancel");
1233 fbCancel->SetToolTipText("Exit macro creation wizard");
1234 fFrameAction->AddFrame(fbCancel, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1235 fbCreate = new TGTextButton(fFrameAction, "Done");
1236 fbCreate->SetToolTipText("Use settings to create the macro");
1237 fFrameAction->AddFrame(fbCreate, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1240 TGHorizontalFrame *fFrameText = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1241 fLabel = new TGLabel(fFrameText, "(*) Mandatory fields");
1242 fLabel->SetTextJustify(36);
1243 fLabel->SetMargins(0,0,0,0);
1244 fLabel->SetWrapLength(-1);
1245 fFrameText->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1247 // put things together
1248 AddFrame(fFrameName, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1249 AddFrame(fFrameObjectType, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1250 AddFrame(fFrameObjectType2, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1251 AddFrame(fFrameIncludes, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1252 AddFrame(fFrameComment, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1253 AddFrame(fFrameType, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1254 AddFrame(fFrameAction, new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandX,2,2,2,2));
1256 TGHorizontal3DLine *fLine = new TGHorizontal3DLine(this, 281, 2);
1257 AddFrame(fLine, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1258 AddFrame(fFrameText, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1261 SetWindowName("Macro Wizard");
1262 SetMWMHints(kMWMDecorAll,
1267 Resize(GetDefaultSize());
1271 fCombo->Connect("Selected(Int_t)", "AliEveGeneralMacroWizard", this, "HandleSelectionChanged(Int_t)");
1272 fbCreate->Connect("Clicked()", "AliEveGeneralMacroWizard", this, "HandleCreate()");
1273 fbCancel->Connect("Clicked()", "AliEveGeneralMacroWizard", this, "CloseWindow()");
1276 fCombo->Select(1, kFALSE);
1279 const Char_t *fGeneralIncludes =
1280 "#if !defined(__CINT__) || defined(__MAKECINT__)\n"
1281 "#include <TROOT.h>\n"
1282 "#include <TH1.h>\n";
1284 const Char_t *fGeneralMacroTemplate[7] = {
1286 ," if (!object) return kFALSE;\n"
1290 " if (!object) return;\n"
1292 ," if (!object) return 0x0;\n\n"
1293 "// Set bins, xmin and xmax here - you can also use a different histogram type (but must inherit from TH1)\n"
1295 " Double_t xmin = 0;\n"
1296 " Double_t xmax = 100;\n\n"
1297 " TH1S* h = new TH1S(\"h\", \"Your title\", n, xmin, xmax);\n"
1298 " h->GetXaxis()->SetTitle("");\n"
1299 " h->GetYaxis()->SetTitle("");\n"
1301 ," if (!object) return kFALSE;\n"
1302 " if (!object2) return kFALSE;\n"
1306 " if (!object) return;\n"
1307 " if (!object2) return;\n"
1309 ," if (!object) return 0x0;\n"
1310 " if (!object2) return 0x0;\n\n"
1311 "// Set bins, xmin and xmax here - you can also use a different histogram type (but must inherit from TH1)\n"
1313 " Double_t xmin = 0;\n"
1314 " Double_t xmax = 100;\n\n"
1315 " TH1S* h = new TH1S(\"h\", \"Your title\", n, xmin, xmax);\n"
1316 " h->GetXaxis()->SetTitle("");\n"
1317 " h->GetYaxis()->SetTitle("");\n"
1320 //______________________________________________________
1321 void AliEveGeneralMacroWizard::Create(Int_t type)
1323 // Creates the macro with the selected type (combo box).
1325 const Char_t* name = fTextName->GetText();
1326 if(strcmp(name,"") == 0)
1328 Error("AliEveGeneralMacroWizard::Create", "Please specify a name for your macro.");
1329 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1330 "Please specify a name for your macro.", kMBIconExclamation, kMBOk);
1334 Bool_t useGivenType = kFALSE;
1335 Bool_t useGivenType2 = kFALSE;
1337 // Remove white-spaces
1338 TString* typeStr = new TString(fTextObjectType->GetText());
1339 typeStr->ReplaceAll(" ", "");
1340 fTextObjectType->SetText(typeStr->Data(), kFALSE);
1342 TString* typeStr2 = new TString(fTextObjectType2->GetText());
1343 typeStr2->ReplaceAll(" ", "");
1344 fTextObjectType2->SetText(typeStr2->Data(), kFALSE);
1346 // If an object type is provided by the user, use it!
1347 if (strlen(typeStr->Data()) > 0)
1349 // Check, if the class really exists
1350 if (TClass::GetClass(typeStr->Data()) != 0x0)
1352 useGivenType = kTRUE;
1356 Int_t buttonsPressed = 0;
1357 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Unknown object type",
1358 Form("The class of your 1st object, \"%s\" has not been found. Do you really want to create your macro with this object type?",
1359 typeStr->Data()), kMBIconExclamation, kMBYes | kMBNo, &buttonsPressed);
1361 if (buttonsPressed & kMBYes) useGivenType = kTRUE;
1362 else useGivenType = kFALSE;
1380 // If an object type is provided by the user, use it!
1381 if (strlen(typeStr2->Data()) > 0)
1383 // Check, if the class really exists
1384 if (TClass::GetClass(typeStr2->Data()) != 0x0)
1386 useGivenType2 = kTRUE;
1390 Int_t buttonsPressed = 0;
1391 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Unknown object type",
1392 Form("The class of your 2nd object, \"%s\" has not been found. Do you really want to create your macro with this object type?",
1393 typeStr2->Data()), kMBIconExclamation, kMBYes | kMBNo, &buttonsPressed);
1395 if (buttonsPressed & kMBYes) useGivenType2 = kTRUE;
1396 else useGivenType2 = kFALSE;
1414 // Note: gSystem->AccessPathName(...) returns kTRUE, if the access FAILED!
1415 if(!gSystem->AccessPathName(Form("./%s.C", name)))
1417 // If there is already a file with this name -> Error
1418 Error("AliEveGeneralMacroWizard::Create", Form("A macro \"%s.C\" already exists in the current directory!\nPlease choose another name!", name));
1419 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1420 Form("A macro \"%s.C\" already exists in the current directory!\nPlease choose another name!", name), kMBIconExclamation, kMBOk);
1425 if(!(fp = fopen(Form("%s.C", name), "wt"))){
1426 Error("AliEveGeneralMacroWizard::Create", "Couldn't create macro file.");
1427 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1428 "Couldn't create macro file.", kMBIconExclamation, kMBOk);
1432 TGText* comment = fTextEdit->GetText();
1433 Char_t* line = 0x0; Int_t iline = 0;
1434 while((line = comment->GetLine(TGLongPosition(0,iline++), 200))) fprintf(fp, "// %s\n", line);
1436 TString* tempStr = new TString(fTextIncludes->GetText());
1438 // Add include files:
1439 // Remove white-spaces and replace commas
1440 tempStr->ReplaceAll(" ", "");
1441 tempStr->ReplaceAll(",","\n#include ");
1442 // If there are files, add the first "#include " in front
1443 if (tempStr->Length() > 3) tempStr->Prepend("#include ");
1445 fprintf(fp, "\n%s%s\n#endif\n\n", fGeneralIncludes, tempStr->Data());
1453 (*typeStr)="TObject";
1458 (*typeStr2)="TObject";
1462 case AliEveListAnalyser::kSingleObjectSelect:
1463 // Use "Bool_t 'NAME'(const 'OBJECTTYPE' *object)\n"
1464 tempStr->Append("Bool_t ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object)\n");
1465 fprintf(fp, tempStr->Data());
1467 case AliEveListAnalyser::kCorrelObjectSelect:
1468 // Use "Bool_t 'NAME'(const 'OBJECTTYPE' *object, const 'OBJECTTYPE2' *object2)\n"
1469 tempStr->Append("Bool_t ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object, const ").Append(typeStr2->Data()).Append(" *object2)\n");
1470 fprintf(fp, tempStr->Data());
1472 case AliEveListAnalyser::kSingleObjectAnalyse:
1473 // Use "void 'NAME'(const 'OBJECTTYPE' *object, Double_t*& r, Int_t& n)\n"
1474 tempStr->Append("void ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object, Double_t*& r, Int_t& n)\n");
1475 fprintf(fp, tempStr->Data());
1477 case AliEveListAnalyser::kSingleObjectHisto:
1478 // Use "TH1* 'NAME'(const 'OBJECTTYPE' *object)\n"
1479 tempStr->Append("TH1* ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object)\n");
1480 fprintf(fp, tempStr->Data());
1482 case AliEveListAnalyser::kCorrelObjectAnalyse:
1483 // Use "void 'NAME'(const 'OBJECTTYPE' *object, const 'OBJECTTYPE2' *object2, Double_t*& r, Int_t& n)\n"
1484 tempStr->Append("void ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object, const ").Append(typeStr2->Data()).Append(" *object2, Double_t*& r, Int_t& n)\n");
1485 fprintf(fp, tempStr->Data());
1487 case AliEveListAnalyser::kCorrelObjectHisto:
1488 // Use "TH1* 'NAME'(const 'OBJECTTYPE' *object, const 'OBJECTTYPE2' *object2)\n"
1489 tempStr->Append("TH1* ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object, const ").Append(typeStr2->Data()).Append(" *object2)\n");
1490 fprintf(fp, tempStr->Data());
1493 Error("AliEveGeneralMacroWizard::Create", Form("Unknown type[%d]", type));
1494 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1495 Form("Unknown type[%d]", type), kMBIconExclamation, kMBOk);
1497 gSystem->Exec(Form("rm -f %s.C", name));
1522 fprintf(fp, "{\n%s\n", fGeneralMacroTemplate[type]);
1524 // Add some further information for analyse macros
1525 if (type == AliEveListAnalyser::kSingleObjectAnalyse || type == AliEveListAnalyser::kCorrelObjectAnalyse)
1527 fprintf(fp, "// add your own code here\n// Please allocate memory for your results, e.g. by doing:\n// n = YourNumberOfResults;\n// r = new Double_t[YourNumberOfResults];\n\n}\n");
1531 fprintf(fp, "// add your own code here\n\n\n}\n");
1536 Emit("Create(Int_t)", type);
1537 Create((Char_t*)name);
1541 //______________________________________________________
1542 void AliEveGeneralMacroWizard::Create(Char_t *name)
1544 // Emits the creation signal.
1546 Emit("Create(Char_t*)", Form("%s.C", name));
1549 //______________________________________________________
1550 void AliEveGeneralMacroWizard::HandleCreate()
1552 // Handles the signal, when the creation button is pressed.
1554 Create(fCombo->GetSelected());
1557 //______________________________________________________
1558 void AliEveGeneralMacroWizard::HandleSelectionChanged(Int_t sel)
1560 // Handles the change of the selected macro type.
1564 case AliEveListAnalyser::kCorrelObjectSelect:
1565 case AliEveListAnalyser::kCorrelObjectAnalyse:
1566 case AliEveListAnalyser::kCorrelObjectHisto:
1567 // Enable 2nd object type
1568 fTextObjectType2->SetEnabled(kTRUE);
1571 // Disable 2nd object type
1572 fTextObjectType2->SetEnabled(kFALSE);