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");
366 if (selIterator != 0) delete selIterator;
368 if (procIterator != 0) delete procIterator;
373 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
374 "AliEveListAnalyser::ApplyProcessMacros experienced an error (cf. CINT-output)!",
375 kMBIconExclamation, kMBOk);
379 //______________________________________________________
380 void AliEveListAnalyserEditor::BrowseMacros()
382 // Creates a file-dialog. The selected files will be added to the macro list
383 // via AddMacro(...).
385 new TGFileDialog(gClient->GetRoot(), GetMainFrame(), kFDOpen, fFileInfo);
387 if (fFileInfo->fIniDir != 0 && fFileInfo->fFileNamesList != 0)
390 TObject* iter = fFileInfo->fFileNamesList->First();
396 // NOTE: fileInfo->fFileNamesList will be changed by that, too!
397 name = (Char_t*)strrchr(iter->GetName(), '/');
398 // Delete '"' at the end
399 name[strlen(name)] = '\0';
401 AddMacro(name + 1, fFileInfo->fIniDir);
402 iter = (TObjString*)fFileInfo->fFileNamesList->After(iter);
407 //______________________________________________________
408 void AliEveListAnalyserEditor::CloseTabs()
410 // Closes + deletes the tabs created by this object
412 if (fHistoCanvas != 0)
414 // Close the created tab, if it exists
415 if (fHistoCanvasName != 0)
417 if (gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString()))
419 // Now the created tab is the current one and can be deleted
420 gEve->GetBrowser()->GetTab(1)->RemoveTab();
423 // With the tab removal, the canvas will be deleted automatically!
429 //______________________________________________________
430 void AliEveListAnalyserEditor::DoAddPrimSelectedObjects()
432 // Adds the selected object(s) to the list ("primary selection").
434 fM->AddPrimSelectedObjects();
437 //______________________________________________________
438 void AliEveListAnalyserEditor::DoRemovePrimSelectedObjects()
440 // Removes the selected object(s) from the list ("primary selection").
442 fM->RemovePrimSelectedObjects();
446 //______________________________________________________
447 void AliEveListAnalyserEditor::DoResetObjectList()
449 // Removes all objects from the list.
451 fM->ResetObjectList();
455 //______________________________________________________
456 void AliEveListAnalyserEditor::DoStartAddingObjects()
458 // Starts adding objects for the analysis.
460 if (fM->StartAddingObjects())
462 fbStart->SetState(kButtonDisabled);
463 fbStop->SetState(kButtonUp);
467 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", "Failed to connect socket!", kMBIconExclamation, kMBOk);
469 if (fM->GetConnected())
471 fbStop->SetState(kButtonDisabled);
472 fbStart->SetState(kButtonUp);
477 //______________________________________________________
478 void AliEveListAnalyserEditor::DoStopAddingObjects()
480 // Stops adding objects for the analysis.
482 if (fM->StopAddingObjects())
484 fbStop->SetState(kButtonDisabled);
485 fbStart->SetState(kButtonUp);
489 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", "Failed to disconnect socket!", kMBIconExclamation, kMBOk);
491 if (fM->GetConnected())
493 fbStop->SetState(kButtonUp);
494 fbStart->SetState(kButtonDisabled);
499 //______________________________________________________
500 void AliEveListAnalyserEditor::DrawHistos()
502 // Accesses the temporary data file created by the last call of ApplyMacros() and draws
503 // histograms according to the selection in the "Histograms"-tab.
505 Int_t nHistograms = GetNSelectedHistograms();
506 if (nHistograms <= 0)
508 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
509 "No data selected. Please select the data you want to plot!", kMBIconExclamation, kMBOk);
514 new TGMsgBox(gClient->GetRoot(), GetMainFrame(),
515 "Error", "Only histograms with up to 3 dimensions supported. Please select 1,2 or 3 data macros!",
516 kMBIconExclamation, kMBOk);
520 // Check, if a histo macro shall be drawn
521 Int_t indexOfHistoMacro = -1;
522 Int_t selectedChecked = 0;
523 for (Int_t j = 0; j < fM->fDataFromMacroList->GetEntries(); j++)
525 if (fCheckButtons[j]->TGButton::GetState() == kButtonDown)
529 // Histo macro? -> To check this, look for the substring "(histo macro)"
530 if (strstr(fM->fDataFromMacroList->At(j)->GetName(), "(histo macro)") != 0)
532 // Is also another macro selected?
535 // Histo macros cannot(!) be correlated!
536 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
537 "Histo macros (return value \"TH1*\") cannot be combined with other macros",
538 kMBIconExclamation, kMBOk);
542 // Mark this histo macro for drawing
543 indexOfHistoMacro = j;
545 // Have all selected macros been checked? -> If yes, we are done with this
546 if (selectedChecked == nHistograms) break;
551 TFile* file = new TFile(Form("/tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER")), "READ");
554 Error("Draw histograms", Form("Cannot open file \"/tmp/ListAnalyserMacroData_%s.root\"",
555 gSystem->Getenv("USER")));
556 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
557 Form("Cannot open file \"/tmp/ListAnalyserMacroData_%s.root\"", gSystem->Getenv("USER")),
558 kMBIconExclamation, kMBOk);
566 Int_t indexOfMacro1 = 0;
567 Int_t indexOfMacro2 = 0;
568 Int_t indexOfMacro3 = 0;
570 // Variable for the loop below -> Will be set to aborting value, if a histo macro is drawn
574 if (indexOfHistoMacro >= 0)
576 if ((t = (TTree*)file->Get(Form("ObjectData%d", indexOfHistoMacro))))
578 SetDrawingToHistoCanvasTab();
581 t->SetBranchAddress(Form("Macro%d", indexOfHistoMacro), &myHist);
583 if (myHist != 0) myHist->Draw();
586 Error("Draw histograms", Form("No histogram for histo macro \"%s\" found!",
587 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()));
588 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
589 Form("No histogram for histo macro \"%s\" found!",
590 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()), kMBIconExclamation, kMBOk);
594 UpdateHistoCanvasTab();
598 Error("Draw histograms", Form("No data for histo macro \"%s\" found!\nMaybe no objects have been selected.",
599 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()));
600 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
601 Form("No data for histo macro \"%s\" found!\nMaybe no objects have been selected.",
602 fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()), kMBIconExclamation, kMBOk);
605 // Skip the loop below
606 i = fM->fDataFromMacroList->GetEntries();
609 // Load the trees in succession and remember the entries -> Plot the analyse macros
610 for ( ; i < fM->fDataFromMacroList->GetEntries(); i++)
612 if (fCheckButtons[i]->TGButton::GetState() == kButtonDown)
617 if (!(t = (TTree*)file->Get(Form("ObjectData%d", i))))
619 Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
620 fM->fDataFromMacroList->At(i)->GetName()));
621 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
622 Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
623 fM->fDataFromMacroList->At(i)->GetName()), kMBIconExclamation, kMBOk);
628 if (nHistograms == 1)
630 SetDrawingToHistoCanvasTab();
632 t->Draw(Form("Macro%d", indexOfMacro1), "1");
633 ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s;%s",
634 fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
635 fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
636 UpdateHistoCanvasTab();
641 else if (tFriend1 == 0)
644 if (!(tFriend1 = (TTree*)file->Get(Form("ObjectData%d", i))))
646 Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
647 fM->fDataFromMacroList->At(i)->GetName()));
648 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
649 Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
650 fM->fDataFromMacroList->At(i)->GetName()),
651 kMBIconExclamation, kMBOk);
656 if (nHistograms == 2)
658 SetDrawingToHistoCanvasTab();
660 t->AddFriend(tFriend1);
661 t->Draw(Form("Macro%d:Macro%d", indexOfMacro1, indexOfMacro2), "1");
662 ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s - %s;%s;%s",
663 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
664 fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
665 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
666 fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
668 UpdateHistoCanvasTab();
677 if (!(tFriend2 = (TTree*)file->Get(Form("ObjectData%d", i))))
679 Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
680 fM->fDataFromMacroList->At(i)->GetName()));
681 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms",
682 Form("No data for macro \"%s\" found!\nMaybe no objects have been selected.",
683 fM->fDataFromMacroList->At(i)->GetName()), kMBIconExclamation, kMBOk);
687 SetDrawingToHistoCanvasTab();
689 t->AddFriend(tFriend1);
690 t->AddFriend(tFriend2);
691 t->Draw(Form("Macro%d:Macro%d:Macro%d", indexOfMacro1, indexOfMacro2, indexOfMacro3), "1");
692 ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s - %s - %s;%s;%s;%s",
693 fM->fDataFromMacroList->At(indexOfMacro3)->GetName(),
694 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
695 fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
696 fM->fDataFromMacroList->At(indexOfMacro3)->GetName(),
697 fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
698 fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
700 UpdateHistoCanvasTab();
707 if (t != 0) delete t;
709 if (tFriend1 != 0) delete tFriend1;
711 if (tFriend2 != 0) delete tFriend2;
719 //______________________________________________________
720 Int_t AliEveListAnalyserEditor::GetNSelectedHistograms() const
722 // Returns the number of selected macros (or rather: of their selected data) in the "Histograms"-tab
726 for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries(); i++)
728 if (fCheckButtons[i]->TGButton::GetState() == kButtonDown) count++;
734 //______________________________________________________
735 void AliEveListAnalyserEditor::HandleMacroPathSet()
737 // Takes the input of the text field (adding a macro), checks if the macro can be
738 // accessed (and that it exists) and adds the macro to the macro list via AddMacro(...).
739 // You can use environment variables in the text field, e.g. "$ALICE_ROOT/Eve/alice-macro/myMacro.C".
741 if (strlen(fteField->GetText()) != 0)
743 // Expand the pathname
744 Char_t* systemPath = gSystem->ExpandPathName(fteField->GetText());
745 fteField->SetText(systemPath);
749 // Check if file exists
752 fp = fopen(fteField->GetText(), "rb");
758 Char_t* name = (Char_t*)strrchr(fteField->GetText(), '/');
763 name = new Char_t[AliEveListAnalyser::fkMaxMacroNameLength];
764 memset(name, '\0', sizeof(Char_t) * AliEveListAnalyser::fkMaxMacroNameLength);
765 sprintf(name, "%s", fteField->GetText());
767 // Add path to textfield -> Path is "./" -> Use length for the name + 2
768 Char_t pathname[AliEveListAnalyser::fkMaxMacroNameLength + 2];
769 memset(pathname, '\0', sizeof(Char_t) * (AliEveListAnalyser::fkMaxMacroNameLength + 2));
770 sprintf(pathname, "./%s", fteField->GetText());
771 fteField->SetText(pathname);
774 if (name != 0) delete [] name;
781 Char_t* path = new Char_t[AliEveListAnalyser::fkMaxMacroPathLength];
782 memset(path, '\0', sizeof(Char_t) * AliEveListAnalyser::fkMaxMacroPathLength);
783 strncpy(path, fteField->GetText(), strlen(fteField->GetText()) - strlen(name));
785 // Ignore the slash "/" in name
786 AddMacro(name + 1, path);
788 if (path != 0) delete [] path;
794 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
795 "File does not exist or you do not have read permission!", kMBIconExclamation, kMBOk);
800 //______________________________________________________
801 void AliEveListAnalyserEditor::HandleNewEventLoaded()
803 // Closes the tabs created by this object and sets a flag that will
804 // cause the function SetModel() to inherit the macro lists
805 // for the next AliEveListAnalyser from the current one.
807 // Inherit the macro list for the next analyse object list!
808 fInheritSettings = kTRUE;
814 //______________________________________________________
815 void AliEveListAnalyserEditor::HandleTabChangedToIndex(Int_t index)
817 // Saves the current tab in the current AliEveListAnalyser.
819 fM->SetSelectedTab(index);
822 //______________________________________________________
823 void AliEveListAnalyserEditor::InheritMacroList()
825 // The old macro list is possibly stored in the corresponding interior map. This function will
826 // use this interior map to move the data from the interior map to the newly loaded AliEveListAnalyser.
827 // Then the interior map will be cleaned up. With this, the settings will be inherited from the previously
828 // loaded AliEveListAnalyser.
830 if (fInheritedMacroList == 0) return;
833 fM->fMacroList->Delete();
835 // Store data from interior list in the analyse object list's map
836 TMapIter* iter = (TMapIter*)fInheritedMacroList->MakeIterator();
839 TGeneralMacroData* macro = 0;
841 while ((key = iter->Next()) != 0)
843 macro = (TGeneralMacroData*)fInheritedMacroList->GetValue(key);
844 if (macro != 0) fM->fMacroList->Add(new TObjString(key->GetName()),
845 new TGeneralMacroData(macro->GetName(), macro->GetPath(), macro->GetType(),
846 macro->GetObjectType(), macro->GetObjectType2()));
849 Error("AliEveListAnalyserEditor::InheritMacroList", Form("Failed to inherit the macro \"%s\"!", key->GetName()));
853 fInheritedMacroList->Delete();
854 delete fInheritedMacroList;
855 fInheritedMacroList = 0;
858 //______________________________________________________
859 void AliEveListAnalyserEditor::NewMacros()
861 // Start the macro creation wizard.
862 // thanks to Jacek Otwinowski<J.Otwinowski@GSI.DE> for this suggestion
864 AliEveGeneralMacroWizard *wizz = new AliEveGeneralMacroWizard();
865 wizz->Connect("Create(Char_t*)", "AliEveListAnalyserEditor", this, "AddMacro(Char_t*)");
868 //______________________________________________________
869 void AliEveListAnalyserEditor::RemoveMacros()
871 // Removes the selected macros from the corresponding list.
873 TList* iterator = new TList();
875 ftlMacroList->GetSelectedEntries(iterator);
876 fM->RemoveSelectedMacros(iterator);
878 if (iterator != 0) delete iterator;
880 iterator = new TList();
881 ftlMacroSelList->GetSelectedEntries(iterator);
882 fM->RemoveSelectedMacros(iterator);
884 // Selected macros are deleted from the list -> No selected entries left
885 fM->fMacroListSelected = 0;
889 if (iterator != 0) delete iterator;
893 //______________________________________________________
894 void AliEveListAnalyserEditor::SaveMacroList(TMap* list)
896 // Saves the provided macro list in an interior list. This list will be used by
897 // InheritMacroList() to restore the data in "list". With this method one is able
898 // to inherit the macro list from analyse object list to analyse object list (i.e. from event to event).
900 if (fInheritedMacroList != 0)
902 fInheritedMacroList->Delete();
903 delete fInheritedMacroList;
905 fInheritedMacroList = new TMap();
906 fInheritedMacroList->SetOwnerKeyValue(kTRUE, kTRUE);
908 TMapIter* iter = (TMapIter*)list->MakeIterator();
910 TGeneralMacroData* macro = 0;
912 while ((key = iter->Next()) != 0)
914 macro = (TGeneralMacroData*)fM->fMacroList->GetValue(key);
915 if (macro != 0) fInheritedMacroList->Add(new TObjString(key->GetName()),
916 new TGeneralMacroData(macro->GetName(), macro->GetPath(), macro->GetType(),
917 macro->GetObjectType(), macro->GetObjectType2()));
920 Error("AliEveListAnalyserEditor::SaveMacroList", Form("Failed to inherit the macro \"%s\"!", key->GetName()));
925 //______________________________________________________
926 void AliEveListAnalyserEditor::SetDrawingToHistoCanvasTab()
928 // Sets gPad to the tab with the name of the current AliEveListAnalyser. If this tab does
929 // not exist, it will be created. Otherwise, it is re-used.
931 // If the tab with the canvas has been closed, the canvas will be deleted.
932 // So, if there is no tab, set the canvas pointer to zero and recreate it in a new tab.
933 if (fHistoCanvas != 0)
935 if (gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString()) == 0)
943 fHistoCanvas = gEve->AddCanvasTab(fM->GetName());
949 //______________________________________________________
950 void AliEveListAnalyserEditor::SetModel(TObject* obj)
952 // Sets the model object, updates the related data in the GUI and
953 // inherits settings (cf. Inherit*(...)), if the flag fInheritSettings is set to kTRUE.
955 fM = dynamic_cast<AliEveListAnalyser*>(obj);
959 Error("SetModel", "Parameter is zero pointer");
963 // Provide a pointer to this editor
966 // If macro list + track style shall be inherited from previously loaded track list, do so
967 if (fInheritSettings)
971 fInheritSettings = kFALSE;
978 GetGedEditor()->GetTab()->SetTab(fM->GetSelectedTab());
980 // Set connection buttons correctly
981 if(fM->GetConnected())
983 fbStart->SetState(kButtonDisabled);
984 fbStop->SetState(kButtonUp);
988 fbStop->SetState(kButtonDisabled);
989 fbStart->SetState(kButtonEngaged);
990 fbStart->SetState(kButtonUp);
994 //______________________________________________________
995 void AliEveListAnalyserEditor::UpdateDataFromMacroListSelection()
997 // Saves the current selection in the "Histograms"-tab to the current
998 // AliEveListAnalyser. This means that the selection is updated and won't
999 // get lost, if another editor is loaded in Eve.
1001 for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries(); i++)
1003 fM->SetHistoDataSelection(i, fCheckButtons[i]->IsOn());
1007 //______________________________________________________
1008 void AliEveListAnalyserEditor::UpdateHistoCanvasTab()
1010 // Updates the histogram and the corresponding tab (including titles).
1012 // Update name of the tab (tab has been set to current tab!)
1013 fHistoCanvasName->SetString(fM->GetName());
1015 // Use a copy of fHistoCanvasName!! -> If the user closes a tab manually, the TGString
1016 // will be deleted -> Error might occur, when accessing the pointer
1017 gEve->GetBrowser()->GetTab(1)->GetCurrentTab()->SetText(new TGString(fHistoCanvasName));
1019 // Switch tabs to force redrawing
1020 gEve->GetBrowser()->GetTab(1)->SetTab(0);
1021 gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString());
1022 fHistoCanvas->Update();
1025 //______________________________________________________
1026 void AliEveListAnalyserEditor::UpdateHistoList()
1028 // Reloads (updates) the buttons in the "Histograms"-tab via
1029 // the current AliEveListAnalyser (data).
1031 fHistoSubFrame->TGCompositeFrame::Cleanup();
1033 // Set buttons for histograms
1034 if (fCheckButtons != 0) delete fCheckButtons;
1035 fCheckButtons = new TGCheckButton*[fM->fDataFromMacroList->GetEntries()];
1037 TObjString* iter = (TObjString*)fM->fDataFromMacroList->First();
1038 for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries() && iter != 0; i++)
1040 fCheckButtons[i] = new TGCheckButton(fHistoSubFrame, iter->GetName());
1041 fHistoSubFrame->AddFrame(fCheckButtons[i]);
1043 fCheckButtons[i]->SetState(kButtonUp, kFALSE);
1044 fCheckButtons[i]->MapRaised();
1045 fCheckButtons[i]->SetOn(fM->HistoDataIsSelected(i));
1046 fCheckButtons[i]->Connect("Clicked()", "AliEveListAnalyserEditor", this, "UpdateDataFromMacroListSelection()");
1048 iter = (TObjString*)fM->fDataFromMacroList->After(iter);
1052 //______________________________________________________
1053 void AliEveListAnalyserEditor::UpdateMacroList()
1055 // Reloads (updates) the macro list (selection AND process macros) via
1056 // the current AliEveListAnalyser (data).
1058 ftlMacroList->RemoveAll();
1059 ftlMacroSelList->RemoveAll();
1061 TMapIter* iter = (TMapIter*)fM->fMacroList->MakeIterator();
1063 TGeneralMacroData* macro = 0;
1066 while ((key = iter->Next()) != 0)
1068 macro = (TGeneralMacroData*)fM->fMacroList->GetValue(key);
1071 if (macro->IsProcessMacro())
1073 ftlMacroList->AddEntry(macro->GetName(), ind);
1074 // Select, what has been selected before
1075 ftlMacroList->Select(ind, fM->MacroListIsSelected(ind));
1078 else if (macro->IsSelectionMacro())
1080 ftlMacroSelList->AddEntry(macro->GetName(), ind);
1081 // Select, what has been selected before
1082 ftlMacroSelList->Select(ind, fM->MacroListIsSelected(ind));
1087 Error("AliEveListAnalyserEditor::UpdateMacroList()",
1088 Form("Macro \"%s/%s.C\" is neither a selection macro nor a process macro!",
1089 macro->GetPath(), macro->GetName()));
1094 Error("AliEveListAnalyserEditor::UpdateMacroList()",
1095 Form("Macro list is corrupted: Macro \"%s\" not found!", key->GetName()));
1099 ftlMacroList->SortByName();
1100 ftlMacroSelList->SortByName();
1103 //______________________________________________________
1104 void AliEveListAnalyserEditor::UpdateMacroListSelection(Int_t ind)
1106 // Saves the current selection in the macro listS to the current
1107 // AliEveListAnalyser. This means that the selection is updated and won't
1108 // get lost, if another editor is loaded in Eve.
1109 // NOTE: The indices in BOTH lists will be unique!
1111 // Toggle selected item
1112 fM->SetMacroListSelection(ind, !fM->MacroListIsSelected(ind));
1116 //______________________________________________________
1117 //______________________________________________________
1118 //______________________________________________________
1121 /////////////////////////////////////////////////
1122 ClassImp(AliEveGeneralMacroWizard)
1123 /////////////////////////////////////////////////
1125 //______________________________________________________
1126 AliEveGeneralMacroWizard::AliEveGeneralMacroWizard(const TGWindow* p)
1127 :TGMainFrame(p ? p : gClient->GetRoot(), 10, 10, kMainFrame | kVerticalFrame)
1134 ,fTextObjectType(0x0)
1135 ,fTextObjectType2(0x0)
1137 // Creates the macro wizard.
1139 const Int_t width = 300;
1142 TGHorizontalFrame *fFrameName = new TGHorizontalFrame(this, 10, 10, kHorizontalFrame);
1143 TGLabel *fLabel = new TGLabel(fFrameName, "Name*");
1144 fLabel->SetTextJustify(36);
1145 fLabel->SetMargins(0,0,0,0);
1146 fLabel->SetWrapLength(-1);
1147 fFrameName->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1149 fTextName = new TGTextEntry(fFrameName);
1150 fTextName->SetMaxLength(255);
1151 fTextName->SetAlignment(kTextLeft);
1152 fTextName->SetText("");
1153 fTextName->SetToolTipText("The name of your macro");
1154 fTextName->Resize(width, fTextName->GetDefaultHeight());
1155 fFrameName->AddFrame(fTextName, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1158 TGHorizontalFrame *fFrameObjectType = new TGHorizontalFrame(this, 10, 10, kHorizontalFrame);
1159 fLabel = new TGLabel(fFrameObjectType, "1st object type of macro");
1160 fLabel->SetTextJustify(36);
1161 fLabel->SetMargins(0,0,0,0);
1162 fLabel->SetWrapLength(-1);
1163 fFrameObjectType->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1165 fTextObjectType = new TGTextEntry(fFrameObjectType);
1166 fTextObjectType->SetAlignment(kTextLeft);
1167 fTextObjectType->SetText("");
1168 // Limit max.length to 80 characters
1169 fTextObjectType->SetMaxLength(80);
1170 fTextObjectType->SetToolTipText("The type of objects, your macro will work with (type of the first pointer)");
1171 fTextObjectType->Resize(width, fTextObjectType->GetDefaultHeight());
1172 fFrameObjectType->AddFrame(fTextObjectType, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1175 TGHorizontalFrame *fFrameObjectType2 = new TGHorizontalFrame(this, 10, 10, kHorizontalFrame);
1176 fLabel = new TGLabel(fFrameObjectType2, "2nd object type of macro (pair");
1177 fLabel->SetTextJustify(36);
1178 fLabel->SetMargins(0,0,0,0);
1179 fLabel->SetWrapLength(-1);
1180 fFrameObjectType2->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1182 fTextObjectType2 = new TGTextEntry(fFrameObjectType2);
1183 fTextObjectType2->SetAlignment(kTextLeft);
1184 fTextObjectType2->SetText("");
1185 // Limit max.length to 80 characters
1186 fTextObjectType2->SetMaxLength(80);
1187 fTextObjectType2->SetToolTipText("The type of objects, your macro will work with (type of the second pointer)\nOnly needed for macros dealing with object pairs");
1188 fTextObjectType2->Resize(width, fTextObjectType2->GetDefaultHeight());
1189 fFrameObjectType2->AddFrame(fTextObjectType2, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1190 fTextObjectType2->SetEnabled(kFALSE);
1193 TGHorizontalFrame *fFrameIncludes = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1194 fLabel = new TGLabel(fFrameIncludes, "Include files");
1195 fLabel->SetTextJustify(36);
1196 fLabel->SetMargins(0,0,0,0);
1197 fLabel->SetWrapLength(-1);
1198 fFrameIncludes->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1200 fTextIncludes = new TGTextEntry(fFrameIncludes);
1201 fTextObjectType->SetAlignment(kTextLeft);
1202 fTextIncludes->SetText("<TRD/AliTRDgeometry.h>,<TRD/AliTRDcluster.h>,<TRD/AliTRDseedV1.h>,<TRD/AliTRDtrackV1.h>");
1203 fTextIncludes->SetCursorPosition(0);
1204 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");
1205 fTextIncludes->Resize(width, fTextIncludes->GetDefaultHeight());
1206 fFrameIncludes->AddFrame(fTextIncludes, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1209 TGHorizontalFrame *fFrameComment = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1210 fLabel = new TGLabel(fFrameComment, "Comment");
1211 fLabel->SetTextJustify(36);
1212 fLabel->SetMargins(0,0,0,0);
1213 fLabel->SetWrapLength(-1);
1214 fFrameComment->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1216 fTextEdit = new TGTextEdit(fFrameComment, width, 5*fTextName->GetDefaultHeight());
1217 fFrameComment->AddFrame(fTextEdit, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1220 TGHorizontalFrame *fFrameType = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1221 fLabel = new TGLabel(fFrameType, "Type*");
1222 fLabel->SetTextJustify(36);
1223 fLabel->SetMargins(0,0,0,0);
1224 fLabel->SetWrapLength(-1);
1225 fFrameType->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1227 fCombo = new TGComboBox(fFrameType, -1, kHorizontalFrame | kSunkenFrame | kDoubleBorder | kOwnBackground);
1228 fCombo->AddEntry("Single Object Selection", AliEveListAnalyser::kSingleObjectSelect);
1229 fCombo->AddEntry("Pair Objects Selection", AliEveListAnalyser::kCorrelObjectSelect);
1230 fCombo->AddEntry("Single Object Analyse", AliEveListAnalyser::kSingleObjectAnalyse);
1231 fCombo->AddEntry("Single Object Histo", AliEveListAnalyser::kSingleObjectHisto);
1232 fCombo->AddEntry("Pair Objects Analyse", AliEveListAnalyser::kCorrelObjectAnalyse);
1233 fCombo->AddEntry("Pair Objects Histo", AliEveListAnalyser::kCorrelObjectHisto);
1235 fCombo->Resize(width, fTextName->GetDefaultHeight());
1236 fFrameType->AddFrame(fCombo, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1239 TGHorizontalFrame *fFrameAction = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1240 fbCancel = new TGTextButton(fFrameAction, "Cancel");
1241 fbCancel->SetToolTipText("Exit macro creation wizard");
1242 fFrameAction->AddFrame(fbCancel, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1243 fbCreate = new TGTextButton(fFrameAction, "Done");
1244 fbCreate->SetToolTipText("Use settings to create the macro");
1245 fFrameAction->AddFrame(fbCreate, new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2));
1248 TGHorizontalFrame *fFrameText = new TGHorizontalFrame(this,10,10,kHorizontalFrame);
1249 fLabel = new TGLabel(fFrameText, "(*) Mandatory fields");
1250 fLabel->SetTextJustify(36);
1251 fLabel->SetMargins(0,0,0,0);
1252 fLabel->SetWrapLength(-1);
1253 fFrameText->AddFrame(fLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
1255 // put things together
1256 AddFrame(fFrameName, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1257 AddFrame(fFrameObjectType, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1258 AddFrame(fFrameObjectType2, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1259 AddFrame(fFrameIncludes, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1260 AddFrame(fFrameComment, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1261 AddFrame(fFrameType, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1262 AddFrame(fFrameAction, new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandX,2,2,2,2));
1264 TGHorizontal3DLine *fLine = new TGHorizontal3DLine(this, 281, 2);
1265 AddFrame(fLine, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1266 AddFrame(fFrameText, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
1269 SetWindowName("Macro Wizard");
1270 SetMWMHints(kMWMDecorAll,
1275 Resize(GetDefaultSize());
1279 fCombo->Connect("Selected(Int_t)", "AliEveGeneralMacroWizard", this, "HandleSelectionChanged(Int_t)");
1280 fbCreate->Connect("Clicked()", "AliEveGeneralMacroWizard", this, "HandleCreate()");
1281 fbCancel->Connect("Clicked()", "AliEveGeneralMacroWizard", this, "CloseWindow()");
1284 fCombo->Select(1, kFALSE);
1287 const Char_t *fGeneralIncludes =
1288 "#if !defined(__CINT__) || defined(__MAKECINT__)\n"
1289 "#include <TROOT.h>\n"
1290 "#include <TH1.h>\n";
1292 const Char_t *fGeneralMacroTemplate[7] = {
1294 ," if (!object) return kFALSE;\n"
1298 " if (!object) return;\n"
1300 ," if (!object) return 0x0;\n\n"
1301 "// Set bins, xmin and xmax here - you can also use a different histogram type (but must inherit from TH1)\n"
1303 " Double_t xmin = 0;\n"
1304 " Double_t xmax = 100;\n\n"
1305 " TH1S* h = new TH1S(\"h\", \"Your title\", n, xmin, xmax);\n"
1306 " h->GetXaxis()->SetTitle("");\n"
1307 " h->GetYaxis()->SetTitle("");\n"
1309 ," if (!object) return kFALSE;\n"
1310 " if (!object2) return kFALSE;\n"
1314 " if (!object) return;\n"
1315 " if (!object2) return;\n"
1317 ," if (!object) return 0x0;\n"
1318 " if (!object2) return 0x0;\n\n"
1319 "// Set bins, xmin and xmax here - you can also use a different histogram type (but must inherit from TH1)\n"
1321 " Double_t xmin = 0;\n"
1322 " Double_t xmax = 100;\n\n"
1323 " TH1S* h = new TH1S(\"h\", \"Your title\", n, xmin, xmax);\n"
1324 " h->GetXaxis()->SetTitle("");\n"
1325 " h->GetYaxis()->SetTitle("");\n"
1328 //______________________________________________________
1329 void AliEveGeneralMacroWizard::Create(Int_t type)
1331 // Creates the macro with the selected type (combo box).
1333 const Char_t* name = fTextName->GetText();
1334 if(strcmp(name,"") == 0)
1336 Error("AliEveGeneralMacroWizard::Create", "Please specify a name for your macro.");
1337 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1338 "Please specify a name for your macro.", kMBIconExclamation, kMBOk);
1342 Bool_t useGivenType = kFALSE;
1343 Bool_t useGivenType2 = kFALSE;
1345 // Remove white-spaces
1346 TString* typeStr = new TString();
1348 typeStr->Append(fTextObjectType->GetText());
1349 typeStr->ReplaceAll(" ", "");
1350 fTextObjectType->SetText(typeStr->Data(), kFALSE);
1352 TString* typeStr2 = new TString();
1354 typeStr2->Append(fTextObjectType2->GetText());
1355 typeStr2->ReplaceAll(" ", "");
1356 fTextObjectType2->SetText(typeStr2->Data(), kFALSE);
1358 // If an object type is provided by the user, use it!
1359 if (strlen(typeStr->Data()) > 0)
1361 // Check, if the class really exists
1362 if (TClass::GetClass(typeStr->Data()) != 0x0)
1364 useGivenType = kTRUE;
1368 Int_t buttonsPressed = 0;
1369 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Unknown object type",
1370 Form("The class of your 1st object, \"%s\" has not been found. Do you really want to create your macro with this object type?",
1371 typeStr->Data()), kMBIconExclamation, kMBYes | kMBNo, &buttonsPressed);
1373 if (buttonsPressed & kMBYes) useGivenType = kTRUE;
1374 else useGivenType = kFALSE;
1398 // If an object type is provided by the user, use it!
1399 if (strlen(typeStr2->Data()) > 0)
1401 // Check, if the class really exists
1402 if (TClass::GetClass(typeStr2->Data()) != 0x0)
1404 useGivenType2 = kTRUE;
1408 Int_t buttonsPressed = 0;
1409 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Unknown object type",
1410 Form("The class of your 2nd object, \"%s\" has not been found. Do you really want to create your macro with this object type?",
1411 typeStr2->Data()), kMBIconExclamation, kMBYes | kMBNo, &buttonsPressed);
1413 if (buttonsPressed & kMBYes) useGivenType2 = kTRUE;
1414 else useGivenType2 = kFALSE;
1438 // Note: gSystem->AccessPathName(...) returns kTRUE, if the access FAILED!
1439 if(!gSystem->AccessPathName(Form("./%s.C", name)))
1441 // If there is already a file with this name -> Error
1442 Error("AliEveGeneralMacroWizard::Create", Form("A macro \"%s.C\" already exists in the current directory!\nPlease choose another name!", name));
1443 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1444 Form("A macro \"%s.C\" already exists in the current directory!\nPlease choose another name!", name), kMBIconExclamation, kMBOk);
1449 if(!(fp = fopen(Form("%s.C", name), "wt"))){
1450 Error("AliEveGeneralMacroWizard::Create", "Couldn't create macro file.");
1451 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1452 "Couldn't create macro file.", kMBIconExclamation, kMBOk);
1456 TGText* comment = fTextEdit->GetText();
1457 Char_t* line = 0x0; Int_t iline = 0;
1458 while((line = comment->GetLine(TGLongPosition(0,iline++), 200))) fprintf(fp, "// %s\n", line);
1460 TString* tempStr = new TString();
1462 // Add include files:
1463 // Remove white-spaces and replace commas
1464 tempStr->Append(fTextIncludes->GetText());
1465 tempStr->ReplaceAll(" ", "");
1466 tempStr->ReplaceAll(",","\n#include ");
1467 // If there are files, add the first "#include " in front
1468 if (tempStr->Length() > 3) tempStr->Prepend("#include ");
1470 fprintf(fp, "\n%s%s\n#endif\n\n", fGeneralIncludes, tempStr->Data());
1478 typeStr->Append("TObject");
1483 typeStr2->Append("TObject");
1487 case AliEveListAnalyser::kSingleObjectSelect:
1488 // Use "Bool_t 'NAME'(const 'OBJECTTYPE' *object)\n"
1489 tempStr->Append("Bool_t ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object)\n");
1490 fprintf(fp, tempStr->Data());
1492 case AliEveListAnalyser::kCorrelObjectSelect:
1493 // Use "Bool_t 'NAME'(const 'OBJECTTYPE' *object, const 'OBJECTTYPE2' *object2)\n"
1494 tempStr->Append("Bool_t ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object, const ").Append(typeStr2->Data()).Append(" *object2)\n");
1495 fprintf(fp, tempStr->Data());
1497 case AliEveListAnalyser::kSingleObjectAnalyse:
1498 // Use "void 'NAME'(const 'OBJECTTYPE' *object, Double_t*& r, Int_t& n)\n"
1499 tempStr->Append("void ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object, Double_t*& r, Int_t& n)\n");
1500 fprintf(fp, tempStr->Data());
1502 case AliEveListAnalyser::kSingleObjectHisto:
1503 // Use "TH1* 'NAME'(const 'OBJECTTYPE' *object)\n"
1504 tempStr->Append("TH1* ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object)\n");
1505 fprintf(fp, tempStr->Data());
1507 case AliEveListAnalyser::kCorrelObjectAnalyse:
1508 // Use "void 'NAME'(const 'OBJECTTYPE' *object, const 'OBJECTTYPE2' *object2, Double_t*& r, Int_t& n)\n"
1509 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");
1510 fprintf(fp, tempStr->Data());
1512 case AliEveListAnalyser::kCorrelObjectHisto:
1513 // Use "TH1* 'NAME'(const 'OBJECTTYPE' *object, const 'OBJECTTYPE2' *object2)\n"
1514 tempStr->Append("TH1* ").Append(name).Append("(const ").Append(typeStr->Data()).Append(" *object, const ").Append(typeStr2->Data()).Append(" *object2)\n");
1515 fprintf(fp, tempStr->Data());
1518 Error("AliEveGeneralMacroWizard::Create", Form("Unknown type[%d]", type));
1519 new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error",
1520 Form("Unknown type[%d]", type), kMBIconExclamation, kMBOk);
1522 gSystem->Exec(Form("rm -f %s.C", name));
1525 if (tempStr != 0) delete tempStr;
1529 if (typeStr != 0) delete typeStr;
1536 if (tempStr != 0) delete tempStr;
1540 if (typeStr != 0) delete typeStr;
1544 if (typeStr2 != 0) delete typeStr2;
1547 fprintf(fp, "{\n%s\n", fGeneralMacroTemplate[type]);
1549 // Add some further information for analyse macros
1550 if (type == AliEveListAnalyser::kSingleObjectAnalyse || type == AliEveListAnalyser::kCorrelObjectAnalyse)
1552 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");
1556 fprintf(fp, "// add your own code here\n\n\n}\n");
1561 Emit("Create(Int_t)", type);
1562 Create((Char_t*)name);
1566 //______________________________________________________
1567 void AliEveGeneralMacroWizard::Create(Char_t *name)
1569 // Emits the creation signal.
1571 Emit("Create(Char_t*)", Form("%s.C", name));
1574 //______________________________________________________
1575 void AliEveGeneralMacroWizard::HandleCreate()
1577 // Handles the signal, when the creation button is pressed.
1579 Create(fCombo->GetSelected());
1582 //______________________________________________________
1583 void AliEveGeneralMacroWizard::HandleSelectionChanged(Int_t sel)
1585 // Handles the change of the selected macro type.
1589 case AliEveListAnalyser::kCorrelObjectSelect:
1590 case AliEveListAnalyser::kCorrelObjectAnalyse:
1591 case AliEveListAnalyser::kCorrelObjectHisto:
1592 // Enable 2nd object type
1593 fTextObjectType2->SetEnabled(kTRUE);
1596 // Disable 2nd object type
1597 fTextObjectType2->SetEnabled(kFALSE);