]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveDet/AliEveTRDTrackListEditor.cxx
1769fa1c27b8aaa6bcc79b8333654ccb1e0ee89f
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveTRDTrackListEditor.cxx
1 // Author: Benjamin Hess   25/09/2008
2
3 /*************************************************************************
4  * Copyright (C) 2008, Alexandru Bercuci, Benjamin Hess.                 *
5  * All rights reserved.                                                  *
6  *************************************************************************/
7
8 //////////////////////////////////////////////////////////////////////////
9 //                                                                      //
10 // AliEveTRDTrackListEditor                                             //
11 //                                                                      //
12 // The AliEveTRDTrackListEditor provides the graphical functionality    //
13 // for the AliEveTRDTrackList. It creates the tabs and canvases, when   //
14 // they are needed and, as well, frees allocated memory on destruction  //
15 // (or if new events are loaded and thus some tabs are closed).         //
16 // The function DrawHistos() accesses the temporary file created by the //
17 // AliEveTRDTrackList and draws the desired data (the file will be      //
18 // created within the call of ApplyMacros()). Have a look at this       //
19 // function to learn more about the structure of the file and how to    //
20 // access the data.                                                     //
21 //////////////////////////////////////////////////////////////////////////
22
23 #include <EveDet/AliEveTRDData.h>
24 #include <EveDet/AliEveTRDTrackList.h>
25 #include "AliEveTRDTrackListEditor.h"
26
27 #include <EveBase/AliEveEventManager.h>
28 #include <AliTRDReconstructor.h>
29 #include <AliTRDtrackV1.h>
30 #include <TGButton.h>
31 #include <TCanvas.h>     
32 #include <TEveBrowser.h>
33 #include <TEveGedEditor.h> 
34 #include <TEveMacro.h>
35 #include <TEveManager.h>
36 #include <TFile.h>
37 #include <TG3DLine.h>
38 #include <TGButtonGroup.h>
39 #include <TGFileDialog.h>
40 #include <TGLabel.h>
41 #include <TGListBox.h>
42 #include <TGMsgBox.h>
43 #include <TGTab.h>
44 #include <TMap.h>
45 #include <TObjString.h>
46 #include <TROOT.h>
47 #include <TSystem.h>
48 #include <TGTextEntry.h>
49 #include <TGTextView.h>
50 #include <TH1.h>
51 #include <TTreeStream.h>
52
53
54 ClassImp(AliEveTRDTrackListEditor)
55
56 ///////////////////////////////////////////////////////////
57 /////////////   AliEveTRDTrackListEditor //////////////////
58 ///////////////////////////////////////////////////////////
59 AliEveTRDTrackListEditor::AliEveTRDTrackListEditor(const TGWindow* p, Int_t width, Int_t height,
60                                                    UInt_t options, Pixel_t back) :
61   TGedFrame(p, width, height, options, back),
62   fM(0),
63   fHistoCanvas(0),
64   fHistoCanvasName(0),
65   fInheritedMacroList(0),
66   fInheritSettings(kFALSE),
67   fStyleFrame(0),
68   fMainFrame(0),
69   fHistoFrame(0),
70   fHistoSubFrame(0),
71   fBrowseFrame(0),
72   fbgStyleColor(0),
73   fbgStyleTrack(0),
74   frbColor(new TGRadioButton*[3]),
75   frbTrack(new TGRadioButton*[3]),
76   fbBrowse(0),
77   fbApplyMacros(0),
78   fbRemoveMacros(0),
79   fbDrawHisto(0),
80   fteField(0),
81   ftlMacroList(0),
82   ftlMacroSelList(0),
83   fFileInfo(0),
84   fFileTypes(0),
85   fLabel1(0), fLabel2(0), fLabel3(0), fLabel4(0),
86   fLine1(0), fLine2(0), fLine3(0), fLine4(0), fLine5(0),
87   fCheckButtons(0)
88 {
89   // Creates the AliEveTRDTrackListEditor.
90
91   // Style stuff
92   fLine5 = new TGHorizontal3DLine(this, 194, 8);
93   AddFrame(fLine5, new TGLayoutHints(kLHintsLeft  | kLHintsTop, 2, 2, 8, 8));
94   fStyleFrame = new TGHorizontalFrame(this);
95   AddFrame(fStyleFrame);
96
97   // Style - Track model
98   fbgStyleTrack = new TGButtonGroup(fStyleFrame, "Track model");
99   fbgStyleTrack->SetMapSubwindows(kTRUE);
100   fbgStyleTrack->Resize(194, 200);
101   fStyleFrame->AddFrame(fbgStyleTrack);
102
103   frbTrack[0] = new TGRadioButton(fbgStyleTrack, "Rieman", 0);
104   frbTrack[0]->SetToolTipText("Set the track model to \"Rieman\" (i.e. the used fit method)");
105   fbgStyleTrack->AddFrame(frbTrack[0]);
106   frbTrack[1] = new TGRadioButton(fbgStyleTrack, "Kalman", 1);
107   frbTrack[1]->SetToolTipText("Set the track model to \"Kalman\" (i.e. the used fit method)");
108   fbgStyleTrack->AddFrame(frbTrack[1]);
109   frbTrack[2] = new TGRadioButton(fbgStyleTrack, "Line", 2);
110   frbTrack[2]->SetToolTipText("Set the track model to \"Line\" (i.e. the used fit method)");
111   fbgStyleTrack->AddFrame(frbTrack[2]);  
112
113   // Style - Color model
114   fbgStyleColor = new TGButtonGroup(fStyleFrame, "Color model");
115   fbgStyleColor->SetMapSubwindows(kTRUE);
116   fbgStyleColor->Resize(194, 200);
117   fStyleFrame->AddFrame(fbgStyleColor);
118
119   frbColor[0] = new TGRadioButton(fbgStyleColor, "PID LQ", 0);
120   frbColor[0]->SetToolTipText("Set color model to \"PID LQ\" -> 2 dimensional likelihood particle identification");
121   fbgStyleColor->AddFrame(frbColor[0]);
122   frbColor[1] = new TGRadioButton(fbgStyleColor, "PID NN", 1);
123   frbColor[1]->SetToolTipText("Set color model to \"PID NN\" -> Neural network particle identification");
124   fbgStyleColor->AddFrame(frbColor[1]);
125   frbColor[2] = new TGRadioButton(fbgStyleColor, "ESD Source", 2);
126   frbColor[2]->SetToolTipText("Set color model to \"ESD Source\" -> By source (TPC track prolongation or TRD stand alone)");
127   fbgStyleColor->AddFrame(frbColor[2]);  
128   
129
130   // Functionality for adding macros  
131   fMainFrame = CreateEditorTabSubFrame("Apply macros");
132    
133   fLabel1 = new TGLabel(fMainFrame,"Add macro(s):");
134   fMainFrame->AddFrame(fLabel1);
135   fBrowseFrame = new TGHorizontalFrame(fMainFrame);
136
137   fteField = new TGTextEntry(fBrowseFrame);
138   fteField->SetToolTipText("Enter the pathname of the macro you want to add here and press \"Enter\"");
139   fteField->Connect("ReturnPressed()","AliEveTRDTrackListEditor", this, "HandleMacroPathSet()"); 
140   fBrowseFrame->AddFrame(fteField);
141   
142   fbBrowse = new TGTextButton(fBrowseFrame, "Browse");
143   fbBrowse->SetToolTipText("Browse the macro you want to add");
144   fbBrowse->Connect("Clicked()", "AliEveTRDTrackListEditor", this, "BrowseMacros()");
145   fBrowseFrame->AddFrame(fbBrowse);
146   fMainFrame->AddFrame(fBrowseFrame);
147
148   fLine1 = new TGHorizontal3DLine(fMainFrame, 194, 8);
149   fMainFrame->AddFrame(fLine1, new TGLayoutHints(kLHintsLeft  | kLHintsTop, 2, 2, 8, 2));
150   fLabel2 = new TGLabel(fMainFrame,"Selection macros:");
151   fMainFrame->AddFrame(fLabel2);
152
153   ftlMacroSelList = new TGListBox(fMainFrame);
154   ftlMacroSelList->Resize(194, 94);
155   ftlMacroSelList->SetMultipleSelections(kTRUE);
156   fMainFrame->AddFrame(ftlMacroSelList);
157
158   fLine2 = new TGHorizontal3DLine(fMainFrame, 194, 8);
159   fMainFrame->AddFrame(fLine2, new TGLayoutHints(kLHintsLeft  | kLHintsTop, 2, 2, 8, 2));
160   fLabel3 = new TGLabel(fMainFrame,"Process macros:");
161   fMainFrame->AddFrame(fLabel3);
162
163   ftlMacroList = new TGListBox(fMainFrame);
164   ftlMacroList->Resize(194, 94);
165   ftlMacroList->SetMultipleSelections(kTRUE);
166   fMainFrame->AddFrame(ftlMacroList);
167
168   fLine3 = new TGHorizontal3DLine(fMainFrame, 194, 8);
169   fMainFrame->AddFrame(fLine3, new TGLayoutHints(kLHintsLeft  | kLHintsTop, 2, 2, 8, 2));  
170
171   fbApplyMacros = new TGTextButton(fMainFrame, "Apply selected macro(s)");
172   fbApplyMacros->SetToolTipText("Apply all selected macros to the tracklist -> A data file will be generated");
173   fbApplyMacros->Connect("Clicked()", "AliEveTRDTrackListEditor", this, "ApplyMacros()");
174   fbApplyMacros->SetRightMargin(12);
175   fMainFrame->AddFrame(fbApplyMacros);
176
177   fbRemoveMacros = new TGTextButton(fMainFrame, "Remove selected macro(s)");
178   fbRemoveMacros->SetToolTipText("Remove the selected macro(s) from the list(s)");
179   fbRemoveMacros->Connect("Clicked()", "AliEveTRDTrackListEditor", this, "RemoveMacros()");
180   fMainFrame->AddFrame(fbRemoveMacros);
181
182   // Stuff for displaying histograms
183   fHistoFrame = CreateEditorTabSubFrame("Histograms");  
184   fHistoFrame->SetMapSubwindows(kTRUE);
185   fLabel4 = new TGLabel(fHistoFrame,"Data from applied macros:");
186   fHistoFrame->AddFrame(fLabel4);
187
188   fHistoSubFrame = new TGVerticalFrame(fHistoFrame);
189   fHistoSubFrame->SetMapSubwindows(kTRUE);
190   fHistoSubFrame->Resize(194, 200);
191   fHistoFrame->AddFrame(fHistoSubFrame);
192
193   fLine4 = new TGHorizontal3DLine(fHistoFrame, 194, 8);
194   fHistoFrame->AddFrame(fLine4, new TGLayoutHints(kLHintsLeft  | kLHintsTop, 2, 2, 8, 2));  
195
196   fbDrawHisto = new TGTextButton(fHistoFrame, "Draw histogram");
197   fbDrawHisto->SetToolTipText("Uses the data file created by the last \"Apply selected macro(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!");
198   fbDrawHisto->Connect("Clicked()", "AliEveTRDTrackListEditor", this, "DrawHistos()");
199   fHistoFrame->AddFrame(fbDrawHisto);
200
201   // Set up file dialog
202   fFileInfo = new TGFileInfo();
203   fFileInfo->SetMultipleSelection(kTRUE);
204
205   fFileTypes = new Char_t*[6];
206   fFileTypes[0] = (Char_t*)"All files"; fFileTypes[1] = (Char_t*)"*";
207   fFileTypes[2] = (Char_t*)"ROOT macros"; fFileTypes[3] = (Char_t*)"*.C";
208   fFileTypes[4] = 0; fFileTypes[5] = 0;
209   fFileInfo->fFileTypes = (const Char_t**)fFileTypes;
210   fFileInfo->fFileTypeIdx = 2;
211   fFileInfo->fMultipleSelection = kTRUE;
212
213   fHistoCanvasName = new TGString("");
214
215   // Handle style changed signals:
216   fbgStyleTrack->Connect("Clicked(Int_t)", "AliEveTRDTrackListEditor", this, "SetTrackModel(Int_t)");
217   fbgStyleColor->Connect("Clicked(Int_t)", "AliEveTRDTrackListEditor", this, "SetTrackColor(Int_t)");
218
219   // Handle the signal "Selected(Int_t ind)"
220   ftlMacroList->Connect("Selected(Int_t)", "AliEveTRDTrackListEditor", this, "UpdateMacroListSelection(Int_t)");
221   ftlMacroSelList->Connect("Selected(Int_t)", "AliEveTRDTrackListEditor", this, "UpdateMacroListSelection(Int_t)");
222
223   // Handle the signal "NewEventLoaded"
224   gAliEveEvent->Connect("NewEventLoaded()", "AliEveTRDTrackListEditor", this, "HandleNewEventLoaded()");
225
226   // Handle the signal "Selected" (another tab has been selected)
227   GetGedEditor()->GetTab()->Connect("Selected(Int_t)", "AliEveTRDTrackListEditor", 
228                                     this, "HandleTabChangedToIndex(Int_t)");
229 }
230
231 //______________________________________________________
232 AliEveTRDTrackListEditor::~AliEveTRDTrackListEditor()
233 {
234   // Destructor: Closes all tabs created by this object and
235   // frees the corresponding memory.
236
237   if (fFileTypes != 0)
238   {
239     delete [] fFileTypes;
240     fFileTypes = 0;
241   }
242
243   if (fFileInfo != 0)
244   {
245     delete fFileInfo; 
246     fFileInfo = 0;
247   }
248   // Close and delete all tabs that have been created by this class
249   CloseTabs();
250
251   if (fHistoCanvasName != 0)
252   {
253     delete fHistoCanvasName;
254     fHistoCanvasName = 0;
255   }
256   if (fInheritedMacroList != 0)
257   {
258     fInheritedMacroList->Delete();
259     delete fInheritedMacroList;
260     fInheritedMacroList = 0;
261   }
262 }
263
264 //______________________________________________________
265 void AliEveTRDTrackListEditor::AddMacro(const Char_t* path, const Char_t* name)
266 {
267   // Adds the macro path/name to the macro list. A warning is provided, if there is
268   // something wrong, e.g. if the macro does not have the correct signature.
269
270   Int_t result = fM->AddMacro(path, name);
271
272   switch (result)
273   {
274   case SUCCESS:
275     UpdateMacroList();
276     break;
277   case WARNING:
278     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Warning", "Macro is already in list (won't be added again)!",
279                  kMBIconExclamation, kMBOk);
280     break;
281   case SIGNATURE_ERROR:
282     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", 
283                  "Macro has not the signature of...\n...a single track selection macro: Bool_t YourMacro(const AliTRDtrackV1*)\n...a correlated tracks selection macro: Bool_t YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*)\n...a single track analyse macro: void YourMacro(const AliTRDtrackV1*, Double_t*&, Int_t&)\n...a correlated tracks analyse macro: void YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*, Double_t*&, Int_t&)\n...a single track histo macro: TH1* YourMacro(const AliTRDtrackV1*)\n...a correlated tracks histo macro: TH1* YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*)", 
284                  kMBIconExclamation, kMBOk);
285     break;               
286   case NOT_EXIST_ERROR:
287     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", 
288                  "File does not exist or you do not have read permission!", kMBIconExclamation, kMBOk);
289     break;
290   default:
291     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", 
292                  Form("AliEveTRDTrackList::AddMacro exited with unknown return value: %d", result),
293                  kMBIconExclamation, kMBOk);
294     break;
295   }
296 }
297
298 //______________________________________________________
299 void AliEveTRDTrackListEditor::ApplyMacros()
300 {
301   // Applies the selected macros and updates the view.
302
303   Bool_t success = kFALSE;
304
305   // First apply the single track selection macros
306   TList* selIterator = new TList();
307   ftlMacroSelList->GetSelectedEntries(selIterator);
308   fM->ApplySTSelectionMacros(selIterator);
309   
310   // Update view
311   gEve->Redraw3D();
312
313   // Now apply the process macros
314   TList* procIterator = new TList();
315   ftlMacroList->GetSelectedEntries(procIterator);
316   success = fM->ApplyProcessMacros(selIterator, procIterator);
317
318   // Update histogram tab (data has to be reloaded)
319   SetModel(fM);
320   Update();
321
322   // AlieveTRDTrackList::ApplyProcessMacros() automatically selects a macro -> Draw the histogram for it,
323   // if a process macro has been applied
324   if (success && procIterator->GetEntries() > 0) 
325   {
326     // Set focus on "Histograms" tab
327     GetGedEditor()->GetTab()->SetTab("Histograms");
328
329     DrawHistos();
330   }
331
332   if (selIterator != 0) delete selIterator;
333   selIterator = 0;  
334   if (procIterator != 0)  delete procIterator;  
335   procIterator = 0;  
336   
337   if (!success)
338   {
339     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", 
340                  "AliEveTRDTrackList::ApplyProcessMacros experienced an error (cf. CINT-output)!", 
341                  kMBIconExclamation, kMBOk);  
342   }
343 }
344
345 //______________________________________________________
346 void AliEveTRDTrackListEditor::BrowseMacros()
347 {
348   // Creates a file-dialog. The selected files will be added to the macro list
349   // via AddMacro(...).
350
351   new TGFileDialog(gClient->GetRoot(), GetMainFrame(), kFDOpen, fFileInfo);
352   
353   if (fFileInfo->fIniDir != 0 && fFileInfo->fFileNamesList != 0)
354   {       
355     // Extract filenames
356     TObject* iter = fFileInfo->fFileNamesList->First();
357  
358     Char_t* name = 0;
359
360     while (iter != 0)
361     {
362       // NOTE: fileInfo->fFileNamesList will be changed by that, too!
363       name = strrchr(iter->GetName(), '/');
364       // Delete '"' at the end
365       name[strlen(name)] = '\0';
366               
367       AddMacro(fFileInfo->fIniDir, name + 1); 
368       iter = (TObjString*)fFileInfo->fFileNamesList->After(iter);
369     }
370   }
371
372   // -> The following problem has been fixed (trunk -> Changes according to 03 September 2008):
373   // Some error occurs, when one ends the filedialog with "cancel": fileInfo->fFileNamesList is set to 0x0, but
374   // in the next launch no new memory is allocated. So do this manually.
375   //if (fileInfo->fFileNamesList == 0)  fileInfo->fFileNamesList = new TList();
376 }
377
378 //______________________________________________________
379 void AliEveTRDTrackListEditor::CloseTabs()
380 {
381   // Closes + deletes the tabs created by this object
382
383   if (fHistoCanvas != 0)
384   {
385     // Close the created tab, if it exists
386     if (fHistoCanvasName != 0)
387     {
388       if (gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString()))
389       {
390         // Now the created tab is the current one and can be deleted
391         gEve->GetBrowser()->GetTab(1)->RemoveTab();
392       }
393     }
394     // With the tab removal, the canvas will be deleted automatically!
395     fHistoCanvas = 0;
396   }
397 }
398
399 //______________________________________________________
400 void AliEveTRDTrackListEditor::DrawHistos()
401 {
402   // Accesses the temporary data file created by the last call of ApplyMacros() and draws
403   // histograms according to the selection in the "Histograms"-tab.
404  
405   Int_t nHistograms = GetNSelectedHistograms();
406   if (nHistograms <= 0)
407   {
408     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", 
409                  "No data selected. Please select the data you want to plot!", kMBIconExclamation, kMBOk);
410     return;
411   }
412   if (nHistograms > 3)
413   {
414     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), 
415                  "Error", "Only histograms with up to 3 dimensions supported. Please select 1,2 or 3 data macros!",
416                  kMBIconExclamation, kMBOk);
417     return;
418   }
419
420   // Check, if a histo macro shall be drawn
421   Int_t indexOfHistoMacro = -1;
422   Int_t selectedChecked = 0;
423   for (Int_t j = 0; j < fM->fDataFromMacroList->GetEntries(); j++)
424   {
425     if (fCheckButtons[j]->TGButton::GetState() == kButtonDown)
426     {
427       selectedChecked++;
428
429       // Histo macro? -> To check this, look for the substring "(histo macro)"
430       if (strstr(fM->fDataFromMacroList->At(j)->GetName(), "(histo macro)") != 0)
431       {
432         // Is also another macro selected?
433         if (nHistograms > 1)
434         {
435           // Histo macros cannot(!) be correlated!
436           new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms", 
437                        "Histo macros (return value \"TH1*\") cannot be combined with other macros", 
438                        kMBIconExclamation, kMBOk);
439           return;        
440         }
441
442         // Mark this histo macro for drawing
443         indexOfHistoMacro = j;
444
445         // Have all selected macros been checked? -> If yes, we are done with this
446         if (selectedChecked == nHistograms)  break;
447       }
448     }
449   }
450
451   TFile* file = new TFile(Form("/tmp/TRD.TrackListMacroData_%s.root", gSystem->Getenv("USER")), "READ");
452   if (!file)  
453   {
454     Error("Draw histograms", Form("Cannot open file \"/tmp/TRD.TrackListMacroData_%s.root\"", 
455                                   gSystem->Getenv("USER")));
456     new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms", 
457                  Form("Cannot open file \"/tmp/TRD.TrackListMacroData_%s.root\"", gSystem->Getenv("USER")),
458                  kMBIconExclamation, kMBOk);
459     return;
460   }
461   
462   TTree* t = 0;
463   TTree* tFriend1 = 0;
464   TTree* tFriend2 = 0;
465
466   Int_t indexOfMacro1 = 0;
467   Int_t indexOfMacro2 = 0;
468   Int_t indexOfMacro3 = 0;
469
470   // Variable for the loop below -> Will be set to aborting value, if a histo macro is drawn
471   Int_t i = 0;
472   
473   // Draw histo macro?
474   if (indexOfHistoMacro >= 0)
475   {
476     if ((t = (TTree*)file->Get(Form("TrackData%d", indexOfHistoMacro))))
477     {
478       SetDrawingToHistoCanvasTab();
479  
480       TH1* myHist = 0;
481       t->SetBranchAddress(Form("Macro%d", indexOfHistoMacro), &myHist);
482       t->GetEntry(0);
483       if (myHist != 0)  myHist->Draw();
484       else
485       {
486         Error("Draw histograms", Form("No histogram for histo macro \"%s\" found!", 
487                                       fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()));
488         new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms", 
489                      Form("No histogram for histo macro \"%s\" found!", 
490                           fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()), kMBIconExclamation, kMBOk);
491                
492       }
493
494       UpdateHistoCanvasTab();    
495     }
496     else
497     {
498       Error("Draw histograms", Form("No data for histo macro \"%s\" found!\nMaybe no tracks have been selected.", 
499                                     fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()));
500       new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms", 
501                    Form("No data for histo macro \"%s\" found!\nMaybe no tracks have been selected.", 
502                         fM->fDataFromMacroList->At(indexOfHistoMacro)->GetName()), kMBIconExclamation, kMBOk);
503     }
504
505     // Skip the loop below
506     i = fM->fDataFromMacroList->GetEntries();
507   }
508
509   // Load the trees in succession and remember the entries -> Plot the analyse macros
510   for ( ; i < fM->fDataFromMacroList->GetEntries(); i++)
511   {
512     if (fCheckButtons[i]->TGButton::GetState() == kButtonDown)
513     {
514       if (t == 0)
515       {
516         indexOfMacro1 = i;
517         if (!(t = (TTree*)file->Get(Form("TrackData%d", i))))
518         { 
519           Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no tracks have been selected.", 
520                                         fM->fDataFromMacroList->At(i)->GetName()));
521           new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms", 
522                        Form("No data for macro \"%s\" found!\nMaybe no tracks have been selected.", 
523                             fM->fDataFromMacroList->At(i)->GetName()), kMBIconExclamation, kMBOk);
524           break;   
525         }
526
527         // 1d histogram
528         if (nHistograms == 1) 
529         {
530           SetDrawingToHistoCanvasTab();
531       
532           t->Draw(Form("Macro%d", indexOfMacro1), "1");
533           ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s;%s",
534             fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
535             fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
536           UpdateHistoCanvasTab();        
537
538           break;     
539         }
540       }
541       else if (tFriend1 == 0)
542       {
543         indexOfMacro2 = i;
544         if (!(tFriend1 = (TTree*)file->Get(Form("TrackData%d", i))))
545         { 
546           Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no tracks have been selected.", 
547                                         fM->fDataFromMacroList->At(i)->GetName()));
548           new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms", 
549                        Form("No data for macro \"%s\" found!\nMaybe no tracks have been selected.", 
550                             fM->fDataFromMacroList->At(i)->GetName()),
551                             kMBIconExclamation, kMBOk);
552           break;   
553         }
554         
555         // 2d histogram
556         if (nHistograms == 2) 
557         {
558           SetDrawingToHistoCanvasTab();
559
560           t->AddFriend(tFriend1);
561           t->Draw(Form("Macro%d:Macro%d", indexOfMacro1, indexOfMacro2), "1");
562           ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s - %s;%s;%s",
563             fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
564             fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
565             fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
566             fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
567
568           UpdateHistoCanvasTab();
569  
570           break;     
571         }
572       }    
573       // 3d histogram
574       else
575       {
576         indexOfMacro3 = i;
577         if (!(tFriend2 = (TTree*)file->Get(Form("TrackData%d", i))))
578         { 
579           Error("Draw histograms", Form("No data for macro \"%s\" found!\nMaybe no tracks have been selected.", 
580                                         fM->fDataFromMacroList->At(i)->GetName()));
581           new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error - Draw histograms", 
582                        Form("No data for macro \"%s\" found!\nMaybe no tracks have been selected.", 
583                             fM->fDataFromMacroList->At(i)->GetName()), kMBIconExclamation, kMBOk);
584           break;   
585         }
586
587         SetDrawingToHistoCanvasTab();
588
589         t->AddFriend(tFriend1);
590         t->AddFriend(tFriend2);
591         t->Draw(Form("Macro%d:Macro%d:Macro%d", indexOfMacro1, indexOfMacro2, indexOfMacro3), "1");
592         ((TH1*)gPad->GetPrimitive("htemp"))->SetTitle(Form("%s - %s - %s;%s;%s;%s",
593             fM->fDataFromMacroList->At(indexOfMacro3)->GetName(),
594             fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
595             fM->fDataFromMacroList->At(indexOfMacro1)->GetName(),
596             fM->fDataFromMacroList->At(indexOfMacro3)->GetName(),
597             fM->fDataFromMacroList->At(indexOfMacro2)->GetName(),
598             fM->fDataFromMacroList->At(indexOfMacro1)->GetName()));
599         
600         UpdateHistoCanvasTab();
601  
602         break;     
603       }
604     }
605   }
606
607   if (t != 0) delete t;
608   t = 0;
609   if (tFriend1 != 0)  delete tFriend1;
610   tFriend1 = 0;
611   if (tFriend2 != 0)  delete tFriend2;
612   tFriend2 = 0;
613
614   file->Close("R");
615   delete file;
616   file = 0;
617 }
618
619 //______________________________________________________
620 Int_t AliEveTRDTrackListEditor::GetNSelectedHistograms() const
621 {
622   // Returns the number of selected macros (or rather: of their selected data) in the "Histograms"-tab
623
624   Int_t count = 0;
625   
626   for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries(); i++)
627   {
628     if (fCheckButtons[i]->TGButton::GetState() == kButtonDown)  count++;
629   }
630
631   return count;
632 }
633
634 //______________________________________________________
635 void AliEveTRDTrackListEditor::HandleMacroPathSet()
636 {
637   // Takes the input of the text field (adding a macro), checks if the macro can be
638   // accessed (and that it exists) and adds the macro to the macro list via AddMacro(...).
639   // You can use environment variables in the text field, e.g. "$ALICE_ROOT/Eve/alice-macro/myMacro.C".
640
641   if (strlen(fteField->GetText()) != 0)
642   {  
643     // Expand the pathname
644     Char_t* systemPath = gSystem->ExpandPathName(fteField->GetText());
645     fteField->SetText(systemPath);
646     delete systemPath;
647     systemPath = 0;
648                         
649     // Check if file exists
650     FILE* fp = NULL;
651
652     fp = fopen(fteField->GetText(), "rb");
653     if (fp != NULL)
654     {
655       fclose(fp);
656
657       // Extract filename
658       Char_t* name = strrchr(fteField->GetText(), '/');
659
660       // Current path
661       if (name == NULL)
662       {
663         name = new Char_t[AliEveTRDTrackList::fkMaxMacroNameLength];
664         memset(name, '\0', sizeof(Char_t) * AliEveTRDTrackList::fkMaxMacroNameLength);
665         sprintf(name, "%s", fteField->GetText());
666
667         // Add path to textfield -> Path is "./" -> Use length for the name + 2
668         Char_t pathname[AliEveTRDTrackList::fkMaxMacroNameLength + 2];
669         memset(pathname, '\0', sizeof(Char_t) * (AliEveTRDTrackList::fkMaxMacroNameLength + 2));
670         sprintf(pathname, "./%s", fteField->GetText());
671         fteField->SetText(pathname);
672
673         AddMacro(".", name);  
674         if (name != 0)  delete name;
675         name = 0;
676       }
677       // Different path
678       else
679       {
680         // Extract path
681         Char_t* path = new Char_t[AliEveTRDTrackList::fkMaxMacroPathLength];
682         memset(path, '\0', sizeof(Char_t) * AliEveTRDTrackList::fkMaxMacroPathLength);
683         strncpy(path, fteField->GetText(), strlen(fteField->GetText()) - strlen(name));
684         
685         // Ignore the slash "/" in name
686         AddMacro(path, name + 1);  
687   
688         if (path != 0)  delete path;
689         path = 0;
690       }       
691     }
692     else
693     {
694       new TGMsgBox(gClient->GetRoot(), GetMainFrame(), "Error", 
695                    "File does not exist or you do not have read permission!", kMBIconExclamation, kMBOk);
696     }
697   }
698 }
699
700 //______________________________________________________
701 void AliEveTRDTrackListEditor::HandleNewEventLoaded()
702 {
703   // Closes the tabs created by this object and sets a flag that will
704   // cause the function SetModel() to inherit the macro lists + style
705   // for the next AliEveTRDTrackList from the current one.
706
707   // Inherit the macro list and track style for the next track list!
708   fInheritSettings = kTRUE;
709
710   // Close the tabs
711   CloseTabs();
712 }
713
714 //______________________________________________________
715 void AliEveTRDTrackListEditor::HandleTabChangedToIndex(Int_t index)
716 {
717   // Saves the current tab in the current AliEveTRDTrackList.
718
719   fM->SetSelectedTab(index);
720 }
721
722 //______________________________________________________
723 void AliEveTRDTrackListEditor::InheritMacroList()
724 {
725   // The old macro list is possibly stored in the corresponding interior map. This function will 
726   // use this interior map to move the data from the interior map to the newly loaded AliEveTRDTrackList. 
727   // Then the interior map will be cleaned up. With this, the settings will be inherited from the previously 
728   // loaded AliEveTRDTrackList.
729
730   if (fInheritedMacroList == 0)  return;
731
732   // Clear list  
733   fM->fMacroList->Delete();
734
735   // Store data from interior list in the track list's map
736   TMapIter* iter = (TMapIter*)fInheritedMacroList->MakeIterator();
737   
738   TObject* key = 0;
739   TMacroData* macro = 0;
740   
741   while ((key = iter->Next()) != 0)
742   {
743     macro = (TMacroData*)fInheritedMacroList->GetValue(key);
744     if (macro != 0)  fM->fMacroList->Add(new TObjString(key->GetName()), 
745                                          new TMacroData(macro->GetName(), macro->GetPath(), macro->GetType()));
746     else
747     {
748       Error("AliEveTRDTrackListEditor::InheritMacroList", Form("Failed to inherit the macro \"%s\"!", key));
749     }
750   }
751   
752   fInheritedMacroList->Delete();
753   delete fInheritedMacroList;
754   fInheritedMacroList = 0;
755 }
756
757 //______________________________________________________
758 void AliEveTRDTrackListEditor::InheritStyle()
759 {
760   // The old styles are stored in the corresponding button groups. This function will replace
761   // the style settings of the newly loaded AliEveTRDTrackList with the old styles. With this, the settings
762   // will be inherited from the previously loaded AliEveTRDTrackList.
763
764   for (Int_t ind = 0; ind < 3; ind++)
765   {
766     if (fbgStyleTrack->GetButton(ind)->IsOn())
767     {
768       SetTrackModel(ind);
769       break;
770     }
771   }
772   for (Int_t ind = 0; ind < 3; ind++)
773   {
774     if (fbgStyleColor->GetButton(ind)->IsOn())
775     {
776       SetTrackColor(ind);
777       break;
778     }
779   }
780 }
781
782 //______________________________________________________
783 void AliEveTRDTrackListEditor::RemoveMacros()
784 {
785   // Removes the selected macros from the corresponding list.
786
787   TList* iterator = new TList();
788   
789   ftlMacroList->GetSelectedEntries(iterator);
790   fM->RemoveSelectedMacros(iterator);
791
792   if (iterator != 0)  delete iterator;
793
794   iterator = new TList();
795   ftlMacroSelList->GetSelectedEntries(iterator);
796   fM->RemoveSelectedMacros(iterator);
797
798   // Selected macros are deleted from the list -> No selected entries left
799   fM->fMacroListSelected = 0;
800
801   UpdateMacroList();
802
803   if (iterator != 0)  delete iterator;
804   iterator = 0;
805 }
806
807 //______________________________________________________
808 void AliEveTRDTrackListEditor::SetDrawingToHistoCanvasTab()
809 {
810   // Sets gPad to the tab with the name of the current AliEveTRDTrackList. If this tab does
811   // not exist, it will be created. Otherwise, it is re-used.
812
813   // If the tab with the canvas has been closed, the canvas will be deleted.
814   // So, if there is no tab, set the canvas pointer to zero and recreate it in a new tab.
815   if (fHistoCanvas != 0) 
816   {
817     if (gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString()) == 0)
818     {
819       fHistoCanvas = 0;
820     }
821   }
822
823   if (!fHistoCanvas)
824   {
825     fHistoCanvas = gEve->AddCanvasTab(fM->GetName());     
826   }
827                            
828   gPad = fHistoCanvas;
829 }
830
831 //______________________________________________________
832 void AliEveTRDTrackListEditor::SetModel(TObject* obj)
833 {  
834   // Sets the model object, updates the related data in the GUI and
835   // inherits settings (cf. Inherit*(...)), if the flag fInheritSettings is set to kTRUE.
836
837   fM = dynamic_cast<AliEveTRDTrackList*>(obj);
838
839   if (fM == 0) 
840   {
841     Error("SetModel", "Parameter is zero pointer");
842     return;
843   }
844
845   // Provide a pointer to this editor
846   fM->fEditor = this;
847
848   // If macro list + track style shall be inherited from previously loaded track list, do so
849   if (fInheritSettings)
850   {
851     InheritMacroList();
852     InheritStyle();
853
854     fInheritSettings = kFALSE;
855   }
856
857   // Select the correct styles
858   Int_t b = 0;
859   UChar_t style = fM->GetSelectedTrackStyle();
860   if (TESTBIT(style, AliEveTRDTrack::kSource)) b = 2;
861   else 
862   {
863     if (TESTBIT(style, AliEveTRDTrack::kPID)) b = 1;
864     else b = 0;
865   } 
866   fbgStyleColor->SetButton(b, kTRUE);
867
868
869   if (TESTBIT(style, AliEveTRDTrack::kTrackCosmics)) b = 2;
870   else
871   {
872     if (TESTBIT(style, AliEveTRDTrack::kTrackModel)) b = 1;
873     else b = 0;
874   }
875   fbgStyleTrack->SetButton(b, kTRUE);
876   
877   UpdateMacroList();
878   UpdateHistoList(); 
879
880   // View correct tab
881   GetGedEditor()->GetTab()->SetTab(fM->GetSelectedTab()); 
882 }
883
884 //______________________________________________________
885 void AliEveTRDTrackListEditor::SaveMacroList(TMap* list)
886 {
887   // Saves the provided macro list in an interior list. This list will be used by
888   // InheritMacroList() to restore the data in "list". With this method one is able
889   // to inherit the macro list from track list to track list (i.e. from event to event).
890
891   if (fInheritedMacroList != 0)
892   {
893     fInheritedMacroList->Delete();
894     delete fInheritedMacroList;
895   }
896   fInheritedMacroList = new TMap();
897   fInheritedMacroList->SetOwnerKeyValue(kTRUE, kTRUE);
898
899   TMapIter* iter = (TMapIter*)list->MakeIterator();
900   TObject* key = 0;
901   TMacroData* macro = 0;
902   
903   while ((key = iter->Next()) != 0)
904   {
905     macro = (TMacroData*)fM->fMacroList->GetValue(key);
906     if (macro != 0) fInheritedMacroList->Add(new TObjString(key->GetName()), 
907                                              new TMacroData(macro->GetName(), macro->GetPath(), macro->GetType()));
908     else
909     {
910       Error("AliEveTRDTrackListEditor::SaveMacroList", Form("Failed to inherit the macro \"%s\"!", key));
911     }
912   }
913 }
914
915 //______________________________________________________
916 void AliEveTRDTrackListEditor::SetTrackColor(Int_t ind)
917 {
918   // Sets the color model for the tracks, updates the tracks with this model and
919   // redraws the scene.
920
921   switch(ind)
922   { 
923     case AliTRDReconstructor::kLQPID:
924       fM->UpdateTrackStyle(AliEveTRDTrack::kPID, AliTRDReconstructor::kLQPID);
925       break;
926     case AliTRDReconstructor::kNNPID:
927       fM->UpdateTrackStyle(AliEveTRDTrack::kPID, AliTRDReconstructor::kNNPID);
928       break;
929     default:
930       fM->UpdateTrackStyle(AliEveTRDTrack::kSource);
931       break;
932   }
933
934   gEve->Redraw3D();
935 }
936
937 //______________________________________________________
938 void AliEveTRDTrackListEditor::SetTrackModel(Int_t ind)
939 {
940   // Sets the track model for the tracks, updates the tracks with this model and
941   // redraws the scene.
942
943   switch(ind)
944   { 
945     case AliEveTRDTrack::kRieman:
946       fM->UpdateTrackStyle(AliEveTRDTrack::kTrackModel, AliEveTRDTrack::kRieman);
947       break;
948     case AliEveTRDTrack::kKalman:
949       fM->UpdateTrackStyle(AliEveTRDTrack::kTrackModel, AliEveTRDTrack::kKalman);
950       break;
951     default:
952       fM->UpdateTrackStyle(AliEveTRDTrack::kTrackCosmics);
953       break;
954   }
955
956   gEve->Redraw3D();
957 }
958
959 //______________________________________________________
960 void AliEveTRDTrackListEditor::UpdateDataFromMacroListSelection()
961 {
962   // Saves the current selection in the "Histograms"-tab to the current
963   // AliEveTRDTrackList. This means that the selection is updated and won't
964   // get lost, if another editor is loaded in Eve.
965
966   for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries(); i++)
967   {
968     fM->SetHistoDataSelection(i, fCheckButtons[i]->IsOn());
969   }
970 }
971
972 //______________________________________________________
973 void AliEveTRDTrackListEditor::UpdateHistoCanvasTab()
974 {
975    // Updates the histogram and the corresponding tab (including titles).
976
977   // Update name of the tab (tab has been set to current tab!)
978   fHistoCanvasName->SetString(fM->GetName());  
979
980   // Use a copy of fHistoCanvasName!! -> If the user closes a tab manually, the TGString
981   // will be deleted -> Error might occur, when accessing the pointer   
982   gEve->GetBrowser()->GetTab(1)->GetCurrentTab()->SetText(new TGString(fHistoCanvasName));
983
984   // Switch tabs to force redrawing
985   gEve->GetBrowser()->GetTab(1)->SetTab(0);
986   gEve->GetBrowser()->GetTab(1)->SetTab(fHistoCanvasName->GetString());
987   fHistoCanvas->Update();
988 }
989
990 //______________________________________________________
991 void AliEveTRDTrackListEditor::UpdateHistoList()
992 {
993   // Reloads (updates) the buttons in the "Histograms"-tab via
994   // the current AliEveTRDTrackList (data).
995
996   fHistoSubFrame->TGCompositeFrame::Cleanup();
997   
998   // Set buttons for histograms
999   if (fCheckButtons != 0) delete fCheckButtons;
1000   fCheckButtons = new TGCheckButton*[fM->fDataFromMacroList->GetEntries()];
1001   
1002   TObjString* iter = (TObjString*)fM->fDataFromMacroList->First();
1003   for (Int_t i = 0; i < fM->fDataFromMacroList->GetEntries() && iter != 0; i++)
1004   {
1005     fCheckButtons[i] = new TGCheckButton(fHistoSubFrame, iter->GetName());
1006     fHistoSubFrame->AddFrame(fCheckButtons[i]);
1007     
1008     fCheckButtons[i]->SetState(kButtonUp, kFALSE);
1009     fCheckButtons[i]->MapRaised();
1010     fCheckButtons[i]->SetOn(fM->HistoDataIsSelected(i));
1011     fCheckButtons[i]->Connect("Clicked()", "AliEveTRDTrackListEditor", this, "UpdateDataFromMacroListSelection()");
1012             
1013     iter = (TObjString*)fM->fDataFromMacroList->After(iter);
1014   }  
1015 }
1016
1017 //______________________________________________________
1018 void AliEveTRDTrackListEditor::UpdateMacroList()
1019 {
1020   // Reloads (updates) the macro list (selection AND process macros) via
1021   // the current AliEveTRDTrackList (data).
1022
1023   ftlMacroList->RemoveAll();
1024   ftlMacroSelList->RemoveAll();
1025    
1026   TMapIter* iter = (TMapIter*)fM->fMacroList->MakeIterator();
1027   TObject* key = 0;
1028   TMacroData* macro = 0;
1029
1030   Int_t ind = 0;
1031   while ((key = iter->Next()) != 0)
1032   {
1033     macro = (TMacroData*)fM->fMacroList->GetValue(key);
1034     if (macro != 0)
1035     {
1036       if (macro->IsProcessMacro())
1037       {
1038         ftlMacroList->AddEntry(macro->GetName(), ind);
1039         // Select, what has been selected before
1040         ftlMacroList->Select(ind, fM->MacroListIsSelected(ind));
1041         ind++;
1042       }
1043       else if (macro->IsSelectionMacro())
1044       {
1045         ftlMacroSelList->AddEntry(macro->GetName(), ind);
1046         // Select, what has been selected before
1047         ftlMacroSelList->Select(ind, fM->MacroListIsSelected(ind));
1048         ind++;
1049       }
1050       else
1051       {
1052         Error("AliEveTRDTrackListEditor::UpdateMacroList()", 
1053               Form("Macro \"%s/%s.C\" has neither a selection macro nor a process macro!",
1054                    macro->GetPath(), macro->GetName()));                                        
1055       }
1056     }
1057     else
1058     {
1059       Error("AliEveTRDTrackListEditor::UpdateMacroList()", 
1060               Form("Macro list is corrupted: Macro \"%s\" not found!", key->GetName()));            
1061     }     
1062   }
1063
1064   ftlMacroList->SortByName(); 
1065   ftlMacroSelList->SortByName(); 
1066 }
1067
1068 //______________________________________________________
1069 void AliEveTRDTrackListEditor::UpdateMacroListSelection(Int_t ind)
1070 {
1071   // Saves the current selection in the macro listS to the current
1072   // AliEveTRDTrackList. This means that the selection is updated and won't
1073   // get lost, if another editor is loaded in Eve.
1074   // NOTE: The indices in BOTH lists will be unique!
1075
1076   // Toggle selected item
1077   fM->SetMacroListSelection(ind, !fM->MacroListIsSelected(ind));
1078 }