]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveDet/AliEveTRDTrackList.cxx
fix user histogram management and style (Ben)
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveTRDTrackList.cxx
1 // Author: Benjamin Hess   29/01/2010
2
3 /*************************************************************************
4  * Copyright (C) 2009-2010, Alexandru Bercuci, Benjamin Hess.            *
5  * All rights reserved.                                                  *
6  *************************************************************************/
7
8
9 //////////////////////////////////////////////////////////////////////////
10 //                                                                      //
11 // AliEveTRDTrackList                                                   //
12 //                                                                      //
13 // An AliEveTRDTrackList is, in principal, a TEveElementList with some  //
14 // sophisticated features. You can add macros to this list, which then  //
15 // can be applied to the list of tracks (these tracks can be added to   //
16 // the list in the same way as for the TEveElementList). In general,    //
17 // please use AddMacro(...) for this purpose.                           //
18 // Macros that are no longer needed can be removed from the list via    //
19 // RemoveSelectedMacros(...).This function takes an iterator of the     //
20 // list of macros that are to be removed.                               //
21 // be removed. An entry looks like:                                     //
22 // The data for each macro consists of path, name, type and the command //
23 // that will be used to apply the macro. This stuff is stored in a map  //
24 // which takes the macro name for the key and the above mentioned data  //
25 // in a TMacroData-object for the value.                                //
26 // You can get the macro type via GetMacroType(...).                    //
27 // With ApplySTSelectionMacros(...) or ApplyProcessMacros(...)          //
28 // respectively you can apply the macros to the track list via          //
29 // iterators (same style like for RemoveSelectedMacros(...)(cf. above)).//
30 // Selection macros (de-)select macros according to a selection rule    //
31 // by setting the rnr-state of the tracks.                              //
32 // If multiple selection macros are applied, a track is selected, if    //
33 // all selection macros select the track.                               //
34 // Process macros create data or histograms, which will be stored in    //
35 // a temporary file. The editor of this class will access this file     //
36 // and draw all the stuff within it's DrawHistos() function. The file   //
37 // will be deleted by the destructor.                                   //
38 //                                                                      //
39 // Currently, the following macro types are supported:                  //
40 // Selection macros:                                                    //
41 // Bool_t YourMacro(const AliTRDtrackV1*);                              //
42 // Bool_t YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*);        //
43 //                                                                      //
44 // Process macros:                                                      //
45 // void YourMacro(const AliTRDtrackV1*, Double_t*&, Int_t&);            //
46 // void YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*,           //
47 //                Double_t*&, Int_t&);                                  //
48 // TH1* YourMacro(const AliTRDtrackV1*);                                //
49 // TH1* YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*);          //
50 //                                                                      //
51 // The macros which take 2 tracks are applied to all track pairs        //
52 // (whereby BOTH tracks of the pair have to be selected by the single   //
53 // track selection macros and have to be unequal, otherwise they will   //
54 // be skipped) that have been selected by ALL correlated tracks         //
55 // selection macros. The selection macros with 2 tracks do NOT affect   //
56 // process macros that process only a single track!                     //
57 //////////////////////////////////////////////////////////////////////////
58
59
60 // Uncomment to display debugging infos
61 //#define ALIEVETRDTRACKLIST_DEBUG
62
63 #include <TFile.h>
64 #include <TFunction.h>
65 #include <TH1.h>
66 #include <TList.h>
67 #include <TMap.h>
68 #include <TObjString.h>
69 #include <TROOT.h>
70 #include <TSystem.h>
71 #include <TTree.h>
72 #include <TTreeStream.h>
73 #include <TMethodCall.h>
74
75 #include <AliTRDReconstructor.h>
76
77 #include <EveDet/AliEveTRDTrackList.h>
78 #include <EveDet/AliEveTRDTrackListEditor.h>
79
80 #include <../PWG1/TRD/AliTRDrecoTask.h>
81 #include <../PWG1/TRD/macros/AliTRDperformanceTrain.h>
82
83 ClassImp(AliEveTRDTrackList)
84
85 ///////////////////////////////////////////////////////////
86 /////////////   AliEveTRDTrackList ////////////////////////
87 ///////////////////////////////////////////////////////////
88 AliEveTRDTrackList::AliEveTRDTrackList(const Text_t* n, const Text_t* t, Bool_t doColor):
89   TEveElementList(n, t, doColor),
90   fEditor(0x0),
91   fDataFromMacroList(0x0),
92   fMacroList(0x0),
93   fDataTree(0x0),
94   fHistoDataSelected(0),
95   fMacroListSelected(0),
96   fSelectedTab(1),                              // Standard tab: "Apply macros" (index 1)
97   fSelectedStyle(0)
98 {
99   // Creates the AliEveTRDTrackList.
100
101   // Only accept childs of type AliEveTRDTrack
102   SetChildClass(AliEveTRDTrack::Class());
103
104   // Allocate memory for the lists and declare them as owners of their contents
105   fDataFromMacroList = new TList();
106   fDataFromMacroList->TCollection::SetOwner(kTRUE);
107
108   fMacroList = new TMap();
109   // Set map to owner of it's objects to delete them, if they are removed from the map
110   fMacroList->SetOwnerKeyValue(kTRUE, kTRUE);
111
112   // Set the build directory for AClic
113   if(gSystem->AccessPathName(Form("%s/.trdQArec" , gSystem->Getenv("HOME")))) gSystem->Exec("mkdir $HOME/.trdQArec");
114   gSystem->SetBuildDir(Form("%s/.trdQArec", gSystem->Getenv("HOME")));
115
116   AddStandardContent();
117 }
118
119 //______________________________________________________
120 AliEveTRDTrackList::~AliEveTRDTrackList()
121 {
122   // Frees allocated memory (lists etc.).
123
124   // Let the editor know that the list will be destroyed -> The editor will save the data
125   if (fEditor != 0)
126   {
127     fEditor->SaveMacroList(fMacroList);
128     fEditor = 0;
129   }
130
131   if (fDataFromMacroList != 0)
132   {
133     fDataFromMacroList->Delete();
134     delete fDataFromMacroList;
135     fDataFromMacroList = 0;
136   } 
137   if (fDataTree != 0)
138   {
139     delete fDataTree;
140     fDataTree = 0;
141   } 
142   if (fMacroList != 0)
143   {
144     fMacroList->DeleteAll();
145     delete fMacroList;
146     fMacroList = 0;
147   }
148   // Note: gSystem->AccessPathName(...) returns kTRUE, if the access FAILED!
149   if(!gSystem->AccessPathName(Form("/tmp/TRD.TrackListMacroData_%s.root", gSystem->Getenv("USER")))) 
150     gSystem->Exec(Form("rm /tmp/TRD.TrackListMacroData_%s.root", gSystem->Getenv("USER")));
151 }
152
153 //______________________________________________________
154 Int_t AliEveTRDTrackList::AddMacro(const Char_t* path, const Char_t* nameC, Bool_t forceReload)
155 {
156   // Checks, if the file exists and if the signature is correct.
157   // If these criteria are fullfilled, the library for this macro is built
158   // and the macro is added to the corresponding list.
159   // Supported macro types:
160   // Selection macros:                                                    
161   // Bool_t YourMacro(const AliTRDtrackV1*)
162   // Bool_t YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*)
163   //
164   // Process macros:                                                      
165   // void YourMacro(const AliTRDtrackV1*, Double_t*&, Int_t&)             
166   // void YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*,           
167   //                Double_t*&, Int_t&)                                   
168   // TH1* YourMacro(const AliTRDtrackV1*)                                 
169   // TH1* YourMacro(const AliTRDtrackV1*, const AliTRDtrackV1*)                              
170
171   Char_t pathname[fkMaxMacroPathNameLength];
172   memset(pathname, '\0', sizeof(Char_t) * fkMaxMacroPathNameLength);
173
174   // Expand the path and create the pathname
175   Char_t* systemPath = gSystem->ExpandPathName(path);
176   sprintf(pathname, "%s/%s", systemPath, nameC);
177   delete systemPath;
178   systemPath = 0;
179
180   // Delete ".C" from filename
181   Char_t name[fkMaxMacroNameLength];
182   memset(name, '\0', sizeof(Char_t) * fkMaxMacroNameLength);
183   
184   for (UInt_t ind = 0; ind < fkMaxMacroNameLength && ind < strlen(nameC) - 2; ind++)  name[ind] = nameC[ind];
185
186   // Check, if files exists
187   FILE* fp = 0x0;
188   if((fp = fopen(pathname, "rb"))){
189     fclose(fp);
190     fp = 0x0;
191   } else  return NOT_EXIST_ERROR;
192   
193   // Clean up root, load the desired macro and then check the type of the macro
194   // A.B. gROOT->Reset();
195  
196   gROOT->ProcessLineSync(Form(".L %s+%c", pathname, forceReload ? '+' : ' '));
197
198   // We need this line... otherwise, in some cases, there will be problems concerning ACLIC
199   gROOT->ProcessLineSync(Form(".L %s", pathname));
200
201   AliEveTRDTrackListMacroType type = GetMacroType(name, kFALSE);
202
203   // Clean up again
204   // A.B. gROOT->Reset();
205   
206   // Has not the correct signature!
207   if (type == kUnknown)  return SIGNATURE_ERROR;
208
209   // Only add macro, if it is not already in the list
210   Int_t returnValue = WARNING;
211   if(fMacroList->GetValue(name) == 0) {
212     returnValue = AddMacroFast(path, name, type) ? SUCCESS : ERROR;
213   }
214   return returnValue;
215 }
216
217 //______________________________________________________
218 Bool_t AliEveTRDTrackList::AddMacroFast(const Char_t* path, const Char_t* name, AliEveTRDTrackListMacroType type)
219 {
220   // Adds a macro (path/name) to the corresponding list. No checks are performed (file exist, 
221   // macro already in list/map, signature correct),  no libraries are created!
222   // You can use this function only, if the macro has been added successfully before 
223   // (and then maybe was removed). The function is very fast. On success kTRUE is returned, otherwise: kFALSE;
224
225   Bool_t success = kFALSE;
226
227   switch (type)
228   {
229     case kSingleTrackSelect:
230     case kCorrelTrackSelect:
231     case kSingleTrackAnalyse:
232     case kSingleTrackHisto:
233     case kCorrelTrackAnalyse:
234     case kCorrelTrackHisto:
235       fMacroList->Add(new TObjString(name), new TMacroData(name, path, type));
236
237       // We do not know, where the element has been inserted - deselect this list
238       fMacroListSelected = 0;
239     
240       success = kTRUE;
241
242 #ifdef ALIEVETRDTRACKLIST_DEBUG
243       // Successfull add will only be displayed in debug mode
244       printf("AliEveTRDTrackList::AddMacroFast: Added macro \"%s/%s\" to the corresponding list\n", path, name);
245 #endif
246
247       break;
248
249     default:
250       // Error will always be displayed
251       printf("AliEveTRDTrackList::AddMacroFast: ERROR: Could not add macro \"%s/%s\" to the corresponding list\n", 
252              path, name);
253
254       success = kFALSE;
255
256       break;
257   }
258
259   return success;
260 }
261
262 //______________________________________________________
263 void AliEveTRDTrackList::AddStandardContent()
264 {
265   // Adds standard macros to the macro list.
266
267   // Add your standard macros here, e.g.: 
268   // To add a macro use:
269   // AddMacro("$(ALICE_ROOT)/myFolder", "myMacroName.C");
270   // -> If the file does not exist, nothing happens. So if you want to handle this,
271   // use the return value of AddMacro (NOT_EXIST_ERROR is returned, if file does not exist)
272   // (-> You can also check for other return values (see AddMacro(...)))
273
274   const Char_t *libs[] = {"libANALYSIS.so", "libANALYSISalice.so", "libTENDER.so", "libPWG1.so"};
275   Int_t nlibs = static_cast<Int_t>(sizeof(libs)/sizeof(Char_t *));
276   for(Int_t ilib=0; ilib<nlibs; ilib++){
277     if(gSystem->Load(libs[ilib]) >= 0) continue;
278     AliError(Form("Fail loading %s.", libs[ilib]));
279     return;
280   }
281
282   AliTRDrecoTask *task = 0x0;
283   TList *fPlots = 0x0;
284   for(Int_t it=2; it<NTRDQATASKS; it++){
285     TClass c(fgkTRDtaskClassName[it]);
286     task = (AliTRDrecoTask*)c.New();
287     task->SetMCdata(kFALSE);
288     if(!(fPlots = task->GetPlotFunctors())){
289       //AliWarning(Form("No Plot functors defined for task \"%s\"", fgkTRDtaskClassName[it]));
290       delete task;
291       continue;
292     }
293     if(!(task->Histos())){
294       //AliWarning(Form("No Ref Histograms defined for task \"%s\"", fgkTRDtaskClassName[it]));
295       delete task;
296       continue;
297     }
298
299     // export task to CINT and add functions
300     gROOT->ProcessLine(Form("%s* %s = (%s*)0x%lx;", fgkTRDtaskClassName[it], task->GetName(), fgkTRDtaskClassName[it], (void*)task));
301     TIter iter(fPlots); TMethodCall *m = 0x0;
302     while((m = dynamic_cast<TMethodCall*>(iter()))){
303       AddMacroFast("", Form("%s->%s", task->GetName(), m->GetMethodName()), kSingleTrackHisto);
304     }
305   }
306 }
307
308 //______________________________________________________
309 Bool_t AliEveTRDTrackList::ApplyProcessMacros(const TList* selIterator, const TList* procIterator)
310 {
311   // Uses the procIterator (for the selected process macros) to apply the selected macros to the data.
312   // Returns kTRUE on success, otherwise kFALSE. If there no process macros selected, kTRUE is returned 
313   // (this is no error!).
314   // The single track process macros are applied to all selected tracks.
315   // The selIterator (for the selected selection macros) will be used to apply the correlated tracks selection
316   // macros to all track pairs (whereby BOTH tracks have to be selected, otherwise they will be skipped).
317   // All track pairs that have been selected by ALL correlated tracks selection macros will be processed by
318   // the correlated tracks process macros.
319
320   // No process macros need to be processed
321   if (procIterator->GetEntries() <= 0)  return kTRUE;
322
323   // Clear root
324   // A.B. gROOT->Reset();
325   
326   // Clear old data and re-allocate
327   if (fDataTree == 0x0){ 
328     TDirectory *cwd = gDirectory;
329     fDataTree = new TTreeSRedirector(Form("/tmp/TRD.TrackListMacroData_%s.root", gSystem->Getenv("USER")));
330     cwd->cd();
331   }
332   if (!fDataTree){
333     Error("Apply process macros", Form("File \"/tmp/TRD.TrackListMacroData_%s.root\" could not be accessed properly!", gSystem->Getenv("USER")));
334     return kFALSE;
335   }
336   
337   if (fDataFromMacroList != 0) {
338     fDataFromMacroList->Delete();
339     delete fDataFromMacroList;
340   }
341   fDataFromMacroList = new TList();
342   fDataFromMacroList->TCollection::SetOwner(kTRUE);
343
344   fHistoDataSelected = 0;
345
346
347   TMacroData* macro = 0;
348
349   Char_t** procCmds = 0;
350   AliEveTRDTrackListMacroType* mProcType = 0;
351   if (procIterator->GetEntries() > 0) {
352     procCmds = new Char_t*[procIterator->GetEntries()];
353     mProcType = new AliEveTRDTrackListMacroType[procIterator->GetEntries()];
354   }
355
356   Char_t** selCmds  = 0;
357   AliEveTRDTrackListMacroType* mSelType = 0;
358   if (selIterator->GetEntries() > 0) {
359     selCmds = new Char_t*[selIterator->GetEntries()];
360     mSelType = new AliEveTRDTrackListMacroType[selIterator->GetEntries()];
361   }
362   
363   Bool_t selectedByCorrSelMacro = kFALSE;
364
365   AliEveTRDTrackListMacroType macroType = kUnknown;
366   Int_t numHistoMacros = 0;
367   TH1** histos = 0;
368
369   AliEveTRDTrack* track1 = 0;
370   AliEveTRDTrack* track2 = 0;
371
372   // Collect the commands for each process macro and add them to "data-from-list"
373   for (Int_t i = 0; i < procIterator->GetEntries(); i++){
374     procCmds[i] = new Char_t[(fkMaxMacroPathNameLength + fkMaxApplyCommandLength)];
375     memset(procCmds[i], '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
376
377     macro = (TMacroData*)fMacroList->GetValue(procIterator->At(i)->GetTitle());
378
379     if (!macro){
380       Error("Apply process macros", 
381         Form("Macro list is corrupted: Macro \"%s\" is not registered!", 
382         procIterator->At(i)->GetTitle()));
383       continue;
384     }
385
386 #ifdef ALIEVETRDTRACKLIST_DEBUG
387     printf("AliEveTRDTrackList: Checking process macro: %s\n", macro->GetName());
388 #endif 
389            
390     // Find the type of the process macro
391     macroType = macro->GetType();
392     if (macroType == kSingleTrackHisto || macroType == kCorrelTrackHisto){
393       mProcType[i] = macroType;
394       numHistoMacros++;
395       // Create the command 
396       sprintf(procCmds[i], macro->GetCmd());
397
398       // Add to "data-from-list" -> Mark as a histo macro with the substring "(histo macro)"
399       fDataFromMacroList->Add(new TObjString(Form("%s (histo macro)", macro->GetName())));
400     } else if (macroType == kSingleTrackAnalyse || macroType == kCorrelTrackAnalyse) {
401       mProcType[i] = macroType;
402       // Create the command 
403       sprintf(procCmds[i], macro->GetCmd());
404
405       // Add to "data-from-list"
406       fDataFromMacroList->Add(new TObjString(macro->GetName()));
407     } else {
408       Error("Apply process macros", 
409         Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a process macro!", 
410         macro->GetPath(), macro->GetName()));
411       mProcType[i] = kUnknown;
412     } 
413   }  
414
415   // Collect the commands for each selection macro and add them to "data-from-list"
416   for (Int_t i = 0; i < selIterator->GetEntries(); i++){
417     selCmds[i] = new Char_t[(fkMaxMacroPathNameLength + fkMaxApplyCommandLength)];
418     memset(selCmds[i], '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
419
420     macro = (TMacroData*)fMacroList->GetValue(selIterator->At(i)->GetTitle());
421
422     if (!macro){
423       Error("Apply process macros", 
424         Form("Macro list is corrupted: Macro \"%s\" is not registered!", 
425         selIterator->At(i)->GetTitle()));
426       continue;
427     }
428
429 #ifdef ALIEVETRDTRACKLIST_DEBUG
430     printf("AliEveTRDTrackList: Checking selection macro: %s\n", macro->GetName());
431 #endif
432        
433     // Find the type of the process macro
434     macroType = macro->GetType();
435
436     // Single track select macro
437     if (macroType == kSingleTrackSelect) {
438       // Has already been processed by ApplySTSelectionMacros(...)
439       mSelType[i] = macroType;         
440     }
441     // Correlated tracks select macro
442     else if (macroType == kCorrelTrackSelect) {
443       mSelType[i] = macroType;  
444  
445       // Create the command
446       sprintf(selCmds[i], macro->GetCmd());
447     } else {
448       Error("Apply process macros", 
449         Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a selection macro!", 
450         macro->GetPath(), macro->GetName()));
451       mSelType[i] = kUnknown;
452     } 
453   }  
454
455   // Allocate memory for the histograms
456   if (numHistoMacros > 0)  histos = new TH1*[numHistoMacros];
457   for (Int_t i = 0; i < numHistoMacros; i++)  histos[i] = 0x0;
458
459
460   //////////////////////////////////
461   // WALK THROUGH THE LIST OF TRACKS
462   //////////////////////////////////     
463   for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter){
464     if(!(track1 = dynamic_cast<AliEveTRDTrack*>(*iter))) continue;
465
466     // Skip tracks that have not been selected
467     if (!track1->GetRnrState())  continue;
468     
469     // Cast to AliTRDtrackV1
470     gROOT->ProcessLineSync(Form("AliEveTRDTrack *automaticTrack = (AliEveTRDTrack*)0x%xl;", track1));
471     gROOT->ProcessLineSync("AliTRDtrackV1* automaticTrackV1_1 = (AliTRDtrackV1*)automaticTrack->GetUserData();");
472
473     // Collect data for each macro
474     for (Int_t i = 0, histoIndex = 0; i < procIterator->GetEntries(); i++){
475       // Single track histo
476       if (mProcType[i] == kSingleTrackHisto){
477         histos[histoIndex++] = (TH1*)gROOT->ProcessLineSync(procCmds[i]);
478        // Correlated tracks histo
479       } else if (mProcType[i] == kCorrelTrackHisto) {
480         // Loop over all pairs behind the current one - together with the other loop this will be a loop
481         // over all pairs. We have a pair of tracks, if and only if both tracks of the pair are selected (Rnr-state)
482         // and are not equal.
483         // The correlated tracks process macro will be applied to all pairs that will be additionally selected by
484         // all correlated tracks selection macros.
485         TEveElement::List_i iter2 = iter;
486         iter2++;
487         for ( ; iter2 != this->EndChildren(); ++iter2)
488         {
489           if(!(track2 = dynamic_cast<AliEveTRDTrack*>(*iter2))) continue;
490
491           // Skip tracks that have not been selected
492           if (!track2->GetRnrState())  continue;
493       
494           // Cast to AliTRDtrackV1
495           gROOT->ProcessLineSync(Form("AliEveTRDTrack *automaticTrack = (AliEveTRDTrack*)0x%xl;", track2));
496           gROOT->ProcessLineSync("AliTRDtrackV1* automaticTrackV1_2 = (AliTRDtrackV1*)automaticTrack->GetUserData();");
497
498           // Select track by default (so it will be processed, if there are no correlated tracks selection macros!)
499           selectedByCorrSelMacro = kTRUE;
500           for (Int_t j = 0; j < selIterator->GetEntries(); j++){
501             if (mSelType[j] == kCorrelTrackSelect){
502               selectedByCorrSelMacro = (Bool_t)gROOT->ProcessLineSync(selCmds[j]);
503               if (!selectedByCorrSelMacro)  break;
504             }
505           }       
506
507           // If the pair has not been selected by the correlated tracks selection macros, skip it!
508           if (!selectedByCorrSelMacro) continue;
509           
510           histos[histoIndex] = (TH1*)gROOT->ProcessLineSync(procCmds[i]);
511         }
512         histoIndex++;
513       }
514       // Single track analyse
515       else if (mProcType[i] == kSingleTrackAnalyse) {
516         // Create data pointers in CINT, execute the macro and get the data
517         gROOT->ProcessLineSync("Double_t* results = 0;");
518         gROOT->ProcessLineSync("Int_t n = 0;");
519         gROOT->ProcessLineSync(procCmds[i]);
520         Double_t* results = (Double_t*)gROOT->ProcessLineSync("results;");
521         Int_t nResults = (Int_t)gROOT->ProcessLineSync("n;");
522         
523         if (results == 0) {
524           Error("Apply macros", Form("Error reading data from macro \"%s\"", procIterator->At(i)->GetTitle()));
525           continue;
526         }
527         for (Int_t resInd = 0; resInd < nResults; resInd++){
528           (*fDataTree) << Form("TrackData%d", i) << Form("Macro%d=", i) << results[resInd] << (Char_t*)"\n";   
529         }
530
531         delete results;
532         results = 0;
533       }
534       // Correlated tracks analyse
535       else if (mProcType[i] == kCorrelTrackAnalyse){
536         // Loop over all pairs behind the current one - together with the other loop this will be a loop
537         // over all pairs. We have a pair of tracks, if and only if both tracks of the pair are selected (Rnr-state)
538         // and are not equal.
539         // The correlated tracks process macro will be applied to all pairs that will be additionally selected by
540         // all correlated tracks selection macros.
541         TEveElement::List_i iter2 = iter;
542         iter2++;
543
544         for ( ; iter2 != this->EndChildren(); ++iter2) {
545           if(!(track2 = dynamic_cast<AliEveTRDTrack*>(*iter2))) continue;
546  
547           // Skip tracks that have not been selected
548           if (!track2->GetRnrState())  continue;
549     
550           // Cast to AliTRDtrackV1
551           gROOT->ProcessLineSync(Form("AliEveTRDTrack *automaticTrack = (AliEveTRDTrack*)0x%xl;", track2));
552           gROOT->ProcessLineSync("AliTRDtrackV1* automaticTrackV1_2 = (AliTRDtrackV1*)automaticTrack->GetUserData();");
553
554           // Select track by default (so it will be processed, if there are no correlated tracks selection macros!)
555           selectedByCorrSelMacro = kTRUE;
556           for (Int_t j = 0; j < selIterator->GetEntries(); j++) {
557             if (mSelType[j] == kCorrelTrackSelect) {
558               selectedByCorrSelMacro = (Bool_t)gROOT->ProcessLineSync(selCmds[j]);
559               if (!selectedByCorrSelMacro)  break;
560             }
561           }       
562
563           // If the pair has not been selected by the correlated tracks selection macros, skip it!
564           if (!selectedByCorrSelMacro) continue;
565           
566           // Create data pointers in CINT, execute the macro and get the data
567           gROOT->ProcessLineSync("Double_t* results = 0;");
568           gROOT->ProcessLineSync("Int_t n = 0;");
569           gROOT->ProcessLineSync(procCmds[i]);
570           Double_t* results = (Double_t*)gROOT->ProcessLineSync("results;");
571           Int_t nResults = (Int_t)gROOT->ProcessLineSync("n;");
572      
573           if (results == 0) {
574             Error("Apply macros", Form("Error reading data from macro \"%s\"", procIterator->At(i)->GetTitle()));
575             continue;
576           }
577           for (Int_t resInd = 0; resInd < nResults; resInd++) {
578             (*fDataTree) << Form("TrackData%d", i) << Form("Macro%d=", i) << results[resInd] << (Char_t*)"\n";   
579           }
580
581           delete results;
582           results = 0;
583         }
584       }
585     }
586   }    
587
588   for (Int_t i = 0, histoIndex = 0; i < procIterator->GetEntries() && histoIndex < numHistoMacros; i++) {
589     if (mProcType[i] == kSingleTrackHisto || mProcType[i] == kCorrelTrackHisto) {
590       // Might be empty (e.g. no tracks have been selected)!
591       if (histos[histoIndex]) {
592         (*fDataTree) << Form("TrackData%d", i) << Form("Macro%d=", i) << histos[histoIndex] << (Char_t*)"\n";
593       }
594       histoIndex++;
595     }
596   }
597
598   if (fDataTree != 0) delete fDataTree;
599   fDataTree = 0;
600
601   if (procCmds != 0)  delete [] procCmds;
602   procCmds = 0;
603   if (mProcType != 0)  delete mProcType;
604   mProcType = 0;
605
606   if (selCmds != 0)  delete [] selCmds;
607   selCmds = 0;
608   if (mSelType != 0)  delete mSelType;
609   mSelType = 0;
610
611   if (histos != 0)  delete [] histos;
612   histos = 0;
613
614   // Clear root
615   // A.B. gROOT->Reset();
616   
617   // If there is data, select the first data set
618   if (procIterator->GetEntries() > 0) SETBIT(fHistoDataSelected, 0);
619
620   // Now the data is stored in "/tmp/TRD.TrackListMacroData_$USER.root"
621   // The editor will access this file to display the data
622   return kTRUE;
623 }
624
625 //______________________________________________________
626 void AliEveTRDTrackList::ApplySTSelectionMacros(const TList* iterator)
627 {
628   // Uses the iterator (for the selected selection macros) to apply the selected macros to the data.
629   // The rnr-states of the tracks are set according to the result of the macro calls (kTRUE, if all
630   // macros return kTRUE for this track, otherwise: kFALSE).
631   // "ST" stands for "single track". This means that only single track selection macros are applied.
632   // Correlated tracks selection macros will be used inside the call of ApplyProcessMacros(...)!
633
634   TMacroData* macro = 0;
635   AliEveTRDTrackListMacroType macroType = kUnknown;
636   AliEveTRDTrack* track1 = 0;
637   Bool_t selectedByMacro = kFALSE;
638
639   // Clear root
640   // A.B. gROOT->Reset();
641
642   // Select all tracks at first. A track is then deselected, if at least one selection macro
643   // returns kFALSE for this track.
644   // Enable all tracks (Note: EnableListElements(..) will call "ElementChanged", which will cause unforeseen behaviour!)
645   for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter) ((TEveElement*)(*iter))->SetRnrState(kTRUE);
646   SetRnrState(kTRUE);
647   
648   for (Int_t i = 0; i < iterator->GetEntries(); i++){
649     macro = (TMacroData*)fMacroList->GetValue(iterator->At(i)->GetTitle());
650
651     if (!macro){
652       Error("Apply selection macros", 
653             Form("Macro list is corrupted: Macro \"%s\" is not registered!", iterator->At(i)->GetTitle()));
654       continue;
655     }
656
657 #ifdef ALIEVETRDTRACKLIST_DEBUG
658     printf("AliEveTRDTrackList: Applying selection macro: %s\n", macro->GetName());
659 #endif
660     
661     // Determine macro type
662     macroType = macro->GetType();
663
664     // Single track select macro
665     if (macroType == kSingleTrackSelect){
666       // Walk through the list of tracks
667       for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter)
668       {
669         track1 = dynamic_cast<AliEveTRDTrack*>(*iter);
670
671         if (!track1) continue;
672
673         // If the track has already been deselected, nothing is to do here
674         if (!track1->GetRnrState()) continue;
675
676         // Cast to AliTRDtrackV1
677         gROOT->ProcessLineSync(Form("AliEveTRDTrack *automaticTrack = (AliEveTRDTrack*)0x%xl;", track1));
678         gROOT->ProcessLineSync("AliTRDtrackV1* automaticTrackV1_1 = (AliTRDtrackV1*)automaticTrack->GetUserData();");
679         selectedByMacro = (Bool_t)gROOT->ProcessLineSync(macro->GetCmd());
680         track1->SetRnrState(selectedByMacro && track1->GetRnrState());               
681       }
682     }
683     // Correlated tracks select macro
684     else if (macroType == kCorrelTrackSelect){
685       // Will be processed in ApplyProcessMacros(...)
686       continue;
687     } else {
688       Error("Apply selection macros", 
689         Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a selection macro!", 
690         macro->GetPath(), macro->GetName()));
691     } 
692   }
693
694   // Clear root
695   // A.B. gROOT->Reset();  
696 }
697
698 //______________________________________________________
699 AliEveTRDTrackList::AliEveTRDTrackListMacroType AliEveTRDTrackList::GetMacroType(const Char_t* name, Bool_t UseList) const
700 {
701   // Returns the type of the corresponding macro. 
702   // If "UseList" is kTRUE, the type will be looked up in the internal list (very fast). But if this list
703   // does not exist, you have to use kFALSE for this parameter. Then the type will be determined by the
704   // prototype! NOTE: It is assumed that the macro has been compiled! If not, the return value is not
705   // predictable, but normally will be kUnknown.
706   // Note: AddMacro(Fast) will update the internal list and RemoveMacros respectively.
707
708   AliEveTRDTrackListMacroType type = kUnknown;
709
710   // Re-do the check of the macro type
711   if (!UseList){
712     // Single track select macro or single track histo macro?
713     TFunction* f = gROOT->GetGlobalFunctionWithPrototype(name, "const AliTRDtrackV1*", kTRUE);
714     if (f != 0x0)
715     {
716       // Some additional check (is the parameter EXACTLY of the desired type?)
717       if (strstr(f->GetMangledName(), "oPconstsPAliTRDtrackV1mUsP") != 0x0)
718       {
719         // Single track select macro?
720         if (!strcmp(f->GetReturnTypeName(), "Bool_t")) 
721         { 
722           type = kSingleTrackSelect;     
723         }
724         // single track histo macro?
725         else if (!strcmp(f->GetReturnTypeName(), "TH1*"))
726         {
727           type = kSingleTrackHisto;
728         }
729       }
730     }
731     // Single track analyse macro?
732     else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, "const AliTRDtrackV1*, Double_t*&, Int_t&", kTRUE)) 
733              != 0x0)
734     {
735       if (!strcmp(f->GetReturnTypeName(), "void"))
736       {
737         // Some additional check (are the parameters EXACTLY of the desired type?)
738         if (strstr(f->GetMangledName(), "oPconstsPAliTRDtrackV1mUsP") != 0x0 &&
739             strstr(f->GetMangledName(), "cODouble_tmUaNsP") != 0x0 &&
740             strstr(f->GetMangledName(), "cOInt_taNsP") != 0x0)
741         {
742           type = kSingleTrackAnalyse;
743         }
744       }
745     }    
746     // Correlated tracks select macro or correlated tracks histo macro?
747     else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, "const AliTRDtrackV1*, const AliTRDtrackV1*", kTRUE)) 
748              != 0x0)
749     {
750       // Some additional check (is the parameter EXACTLY of the desired type?)
751       if (strstr(f->GetMangledName(), "oPconstsPAliTRDtrackV1mUsP") != 0x0 &&
752           strstr(f->GetMangledName(), "cOconstsPAliTRDtrackV1mUsP") != 0x0)
753       {
754         // Correlated track select macro?
755         if (!strcmp(f->GetReturnTypeName(), "Bool_t")) 
756         { 
757           type = kCorrelTrackSelect;     
758         }
759         // Correlated track histo macro?
760         else if (!strcmp(f->GetReturnTypeName(), "TH1*"))
761         {
762           type = kCorrelTrackHisto;
763         }
764       }
765     }    
766     // Correlated tracks analyse macro?
767     else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, 
768                               "const AliTRDtrackV1*, const AliTRDtrackV1*, Double_t*&, Int_t&", kTRUE)) 
769              != 0x0)
770     {
771       if (!strcmp(f->GetReturnTypeName(), "void"))
772       {
773         // Some additional check (is the parameter EXACTLY of the desired type?)
774         if (strstr(f->GetMangledName(), "oPconstsPAliTRDtrackV1mUsP") != 0x0 &&
775             strstr(f->GetMangledName(), "cOconstsPAliTRDtrackV1mUsP") != 0x0 &&
776             strstr(f->GetMangledName(), "cODouble_tmUaNsP") != 0x0 &&
777             strstr(f->GetMangledName(), "cOInt_taNsP") != 0x0)
778         {
779           type = kCorrelTrackAnalyse;
780         }
781       }
782     }    
783   }
784   // Use list to look up the macro type
785   else
786   {
787     TMacroData* macro = 0;
788     macro = (TMacroData*)fMacroList->GetValue(name);
789     if (macro == 0)  return kUnknown; 
790     
791     type = macro->GetType();
792     switch (type)
793     {
794       case kSingleTrackSelect:
795       case kSingleTrackAnalyse:
796       case kSingleTrackHisto:
797       case kCorrelTrackSelect:
798       case kCorrelTrackAnalyse:
799       case kCorrelTrackHisto:      
800         break;
801     default:
802       type = kUnknown;
803       break;
804     }
805   }
806
807   return type;
808 }
809
810 //______________________________________________________
811 void AliEveTRDTrackList::RemoveSelectedMacros(const TList* iterator) 
812 {
813   // Uses the iterator (for the selected macros) to remove the selected macros from 
814   // the corresponding list.
815    
816   TObject* key = 0;
817   TPair*   entry = 0;
818   for (Int_t i = 0; i < iterator->GetEntries(); i++)
819   {
820     entry = (TPair*)fMacroList->FindObject(iterator->At(i)->GetTitle());
821
822     if (entry == 0)
823     {
824       Error("AliEveTRDTrackList::RemoveSelectedMacros", Form("Macro \"%s\" not found in list!", 
825                                                              iterator->At(i)->GetTitle()));
826       continue;
827     }
828     key = entry->Key();
829
830     if (key == 0)   
831     {
832       Error("AliEveTRDTrackList::RemoveSelectedMacros", Form("Key for macro \"%s\" not found in list!", 
833                                                              iterator->At(i)->GetTitle()));
834       continue;
835     }
836
837     // Key and value will be deleted, too, since fMacroList is the owner of them
838     Bool_t rem = fMacroList->DeleteEntry(key);
839
840     if (rem)
841     {
842 #ifdef ALIEVETRDTRACKLIST_DEBUG
843     printf("AliEveTRDTrackList::RemoveSelectedMacros(): Removed macro: %s\n", iterator->At(i)->GetTitle());
844 #endif
845     }
846     else
847     {
848       Error("AliEveTRDTrackList::RemoveSelectedMacros", Form("Macro \"%s\" could not be removed from the list!", 
849                                                              iterator->At(i)->GetTitle()));
850     }
851   }
852 }
853
854 //______________________________________________________
855 void AliEveTRDTrackList::UpdateTrackStyle(AliEveTRDTrack::AliEveTRDTrackState s, UChar_t ss)
856 {
857   // Updates the track style and sets this style for each track.
858
859   switch(s)
860   {
861     case AliEveTRDTrack::kSource:
862       SETBIT(fSelectedStyle, AliEveTRDTrack::kSource);
863       break;  
864     case AliEveTRDTrack::kPID:
865       CLRBIT(fSelectedStyle, AliEveTRDTrack::kSource);
866       switch(ss)
867       {
868       case AliTRDpidUtil::kLQ:
869         CLRBIT(fSelectedStyle, AliEveTRDTrack::kPID);
870         break;
871       case AliTRDpidUtil::kNN:
872         SETBIT(fSelectedStyle, AliEveTRDTrack::kPID);
873         break;
874       }
875       break;  
876     case AliEveTRDTrack::kTrackCosmics:
877       SETBIT(fSelectedStyle, AliEveTRDTrack::kTrackCosmics);
878       break;  
879     case AliEveTRDTrack::kTrackModel:
880       CLRBIT(fSelectedStyle, AliEveTRDTrack::kTrackCosmics);
881       switch(ss)
882       {
883       case AliEveTRDTrack::kRieman:
884         CLRBIT(fSelectedStyle, AliEveTRDTrack::kTrackModel);
885         break;
886       case AliEveTRDTrack::kKalman:
887         //AliWarning("Kalman fit under testing for the moment.");
888         SETBIT(fSelectedStyle, AliEveTRDTrack::kTrackModel);
889         break;
890       }
891       break;  
892   }
893
894
895   // Walk through the list of tracks     
896   AliEveTRDTrack* track = 0x0;
897   for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter) 
898   {
899     if (!(track = dynamic_cast<AliEveTRDTrack*>(*iter)))  continue;
900
901     track->SetStatus(fSelectedStyle);
902   }
903 }