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