]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveDet/AliEveTRDTrackList.cxx
protections and extended selection of tracks (Ben)
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveTRDTrackList.cxx
1 // Uncomment to display debugging infos
2 //#define ALIEVETRDTRACKLIST_DEBUG
3
4 #include "AliEveTRDTrackList.h"
5
6 #include <AliTRDtrackV1.h>
7 #include <TFile.h>
8 #include <TFunction.h>
9 #include <TH1.h>
10 #include <TList.h>
11 #include <TObjString.h>
12 #include <TROOT.h>
13 #include <TSystem.h>
14 #include <TTree.h>
15 #include <TTreeStream.h>
16 #include <EveDet/AliEveTRDData.h>
17
18 ClassImp(AliEveTRDTrackList)
19
20 ///////////////////////////////////////////////////////////
21 /////////////   AliEveTRDTrackList ////////////////////////
22 ///////////////////////////////////////////////////////////
23 AliEveTRDTrackList::AliEveTRDTrackList(const Text_t* n, const Text_t* t, Bool_t doColor):
24   TEveElementList(n, t, doColor),
25   fMacroList(0),
26   fMacroSelList(0),
27   fDataFromMacroList(0),
28   fDataTree(0),
29   fHistoDataSelected(0),
30   fMacroListSelected(0),
31   fMacroSelListSelected(0),
32   fSelectedTab(1)             // Standard tab: "Apply macros" (index 1)
33 {
34   // Only accept childs of type AliEveTRDTrack
35   SetChildClass(AliEveTRDTrack::Class());
36
37   fMacroList = new TList();
38   fMacroSelList = new TList();
39   fDataFromMacroList = new TList();
40
41   //fDataTree = new TTreeSRedirector("TRD.TrackListMacroData.root");
42
43   AddStandardMacros();
44 }
45
46 //______________________________________________________
47 AliEveTRDTrackList::~AliEveTRDTrackList()
48 {
49   if (fMacroList != 0)
50   {
51     fMacroList->Delete();
52     delete fMacroList;
53     fMacroList = 0;
54   }
55   if (fMacroSelList != 0)
56   {
57     fMacroSelList->Delete();
58     delete fMacroSelList;
59     fMacroSelList = 0;
60   } 
61   if (fDataFromMacroList != 0)
62   {
63     fDataFromMacroList->Delete();
64     delete fDataFromMacroList;
65     fDataFromMacroList = 0;
66   } 
67   if (fDataTree != 0)
68   {
69     delete fDataTree;
70     fDataTree = 0;
71   } 
72 }
73
74 //______________________________________________________
75 Int_t AliEveTRDTrackList::AddMacro(const Char_t* path, const Char_t* nameC, Bool_t forceReload)
76 {
77   // First check the type of the macro:
78   // If it has the signature of a selection macro:
79   // Bool_t MacroName(AliTRDtrackV1*)
80   // it is assumed to be a selection macro.
81   // If it has the signature of a process macro:
82   // void MacroName(AliTRDtrackV1*, Double_t*&, Int_t&)
83   // it is assumed to be a process macro.
84   // In all other cases: Macro is rejected
85   Bool_t isHistoMacro = kFALSE;
86   Bool_t isSelectionMacro = kFALSE;
87   Bool_t hasCorrectSignature = kFALSE;
88   
89
90   Char_t* entryName = MakeMacroEntry(path, nameC);
91
92   Char_t pathname[fkMaxMacroPathNameLength];
93   memset(pathname, '\0', sizeof(Char_t) * fkMaxMacroPathNameLength);
94
95   // Expand the path and create the pathname
96   Char_t* systemPath = gSystem->ExpandPathName(path);
97   sprintf(pathname, "%s/%s", systemPath, nameC);
98   delete systemPath;
99   systemPath = 0;
100
101   // Delete ".C" from filename
102   Char_t name[fkMaxMacroNameLength];
103   memset(name, '\0', sizeof(Char_t) * fkMaxMacroNameLength);
104   
105   for (UInt_t ind = 0; ind < fkMaxMacroNameLength && ind < strlen(nameC) - 2; ind++)  name[ind] = nameC[ind];
106
107   // Check, if files exists
108   FILE* fp = 0;
109
110   fp = fopen(pathname, "rb");
111   if (fp != 0)
112   {
113     fclose(fp);
114     fp = 0;
115   }
116   else
117   {
118     if (entryName != 0)  delete entryName;
119     entryName = 0;
120
121     return NOT_EXIST_ERROR;
122   }
123
124   // Clean up root, load the desired macro and then check the type of the macro
125   //gROOT->Reset("a");
126   gROOT->Reset();
127  
128   if (forceReload)  gROOT->ProcessLineSync(Form(".L %s++", pathname));
129   else              gROOT->ProcessLineSync(Form(".L %s+", pathname));
130
131   // Selection macro or process macro of type 2 (histo)?
132   TFunction* f = gROOT->GetGlobalFunctionWithPrototype(name, "const AliTRDtrackV1*", kTRUE);
133   if (f != 0x0)
134   {
135     // Some additional check (is the parameter EXACTLY of the desired type?)
136     if (strstr(f->GetMangledName(), "oPconstsPAliTRDtrackV1mUsP") != 0x0)
137     {
138       // Selection macro?
139       if (!strcmp(f->GetReturnTypeName(), "Bool_t")) 
140       {      
141         hasCorrectSignature = kTRUE;
142         isSelectionMacro = kTRUE;
143         isHistoMacro = kFALSE;
144       }
145       // Process macro of type 2 (histo)?
146       else if (!strcmp(f->GetReturnTypeName(), "TH1*"))
147       {
148         hasCorrectSignature = kTRUE;
149         isSelectionMacro = kFALSE;
150         isHistoMacro = kTRUE;
151       }
152     }
153   }
154   // Process macro of type 1?
155   else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, "const AliTRDtrackV1*, Double_t*&, Int_t&", kTRUE)) != 0x0)
156   {
157     if (!strcmp(f->GetReturnTypeName(), "void"))
158     {
159       // Some additional check (are the parameters EXACTLY of the desired type?)
160       if (strstr(f->GetMangledName(), "oPconstsPAliTRDtrackV1mUsP") != 0x0 &&
161           strstr(f->GetMangledName(), "cODouble_tmUaNsP") != 0x0 &&
162           strstr(f->GetMangledName(), "cOInt_taNsP") != 0x0)
163       {
164         hasCorrectSignature = kTRUE;
165         isSelectionMacro = kFALSE;
166         isHistoMacro = kFALSE;
167       }
168     }
169   }
170
171   //// Clean up again / unload this function
172   //gROOT->ProcessLineSync(Form(".U %s", pathname));
173   //gROOT->Reset("a");
174   // Clean up again
175   gROOT->Reset();
176   
177   // Has not the correct signature!
178   if (!hasCorrectSignature) 
179   {
180     if (entryName != 0)  delete entryName;
181     entryName = 0;
182     return SIGNATURE_ERROR;
183   }
184
185   Int_t returnValue = WARNING;
186
187   // Only add macro, if it is not already in the list
188   if (!isSelectionMacro && fMacroList->FindObject(entryName) == 0)
189   {
190     fMacroList->Add(new TObjString(entryName));
191     fMacroList->Sort();
192
193     // We do not know, where the element has been inserted - deselect this list
194     fMacroListSelected = 0;
195
196     returnValue = SUCCESS;
197   }
198   else if (isSelectionMacro && fMacroSelList->FindObject(entryName) == 0)
199   {
200     fMacroSelList->Add(new TObjString(entryName));
201     fMacroSelList->Sort();
202   
203     // We do not know, where the element has been inserted - deselect this list
204     fMacroSelListSelected = 0;
205     
206     returnValue = SUCCESS;
207   }
208   else  returnValue = WARNING;
209
210   if (entryName != 0)  delete entryName;
211   entryName = 0;
212
213   return returnValue;
214 }
215
216 //______________________________________________________
217 void AliEveTRDTrackList::AddMacroFast(const Char_t* entry, Bool_t toSelectionList)
218 {
219   if (toSelectionList)
220   {
221     fMacroSelList->Add(new TObjString(entry));
222     fMacroSelList->Sort();
223
224     // We do not know, where the element has been inserted - deselect this list
225     fMacroSelListSelected = 0;
226   }
227   else 
228   {
229     fMacroList->Add(new TObjString(entry));
230     fMacroList->Sort();
231
232     // We do not know, where the element has been inserted - deselect this list
233     fMacroListSelected = 0;
234   }
235 }
236
237 //______________________________________________________
238 void AliEveTRDTrackList::AddMacroFast(const Char_t* path, const Char_t* name, Bool_t toSelectionList)
239 {
240   Char_t* entry = MakeMacroEntry(path, name);
241   if (entry != 0)
242   {
243     AddMacroFast(entry, toSelectionList);
244
245 #ifdef ALIEVETRDTRACKLIST_DEBUG
246     // Successfull add will only be displayed in debug mode
247     printf("#AliEveTRDTrackList::AddMacroFast: Added macro \"%s/%s\" to %s list\n", path, name, 
248            (toSelectionList ? "selection" : "process"));
249 #endif
250     
251     delete entry;
252     entry = 0;
253   }
254   else
255   {
256     // Error will always be displayed
257     printf("#AliEveTRDTrackList::AddMacroFast: ERROR: Could not add macro \"%s/%s\" to %s list\n", path, name, 
258            (toSelectionList ? "selection" : "process"));
259   }
260 }
261
262 //______________________________________________________
263 void AliEveTRDTrackList::AddStandardMacros()
264 {
265   // Add your standard macros here, e.g.: 
266   // To add a macro without any checks (very fast, but unsafe):
267   // AddMacroFast("$(ALICE_ROOT)/myFolder", "myMacroName.C", isSelMacro);
268   // To add a macro with checks (slower, but safe):
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   AddMacro("$(ALICE_ROOT)/TRD/qaRec/macros", "clusterSelection.C");
274   AddMacro("$(ALICE_ROOT)/TRD/qaRec/macros", "chargeDistr.C");
275   AddMacro("$(ALICE_ROOT)/TRD/qaRec/macros", "clusterResiduals.C");
276   AddMacro("$(ALICE_ROOT)/TRD/qaRec/macros", "PH.C");
277 }
278
279 //______________________________________________________
280 void AliEveTRDTrackList::ApplyProcessMacros(TList* iterator)
281 {
282   if (iterator->GetEntries() <= 0)  return;
283
284   Char_t name[fkMaxMacroNameLength];
285   Char_t** cmds = new Char_t*[iterator->GetEntries()];
286   Bool_t* isHistoMacro = new Bool_t[iterator->GetEntries()];
287
288   Int_t numHistoMacros = 0;
289   TH1** histos = 0;
290
291   AliEveTRDTrack* track = 0;
292   AliTRDtrackV1 *trackv1 = 0;
293   TH1* returnedHist = 0x0;
294
295   // Clear root
296   gROOT->Reset();
297   
298   // Clear old data and re-allocate
299   if (fDataFromMacroList != 0) delete fDataFromMacroList;
300   fDataFromMacroList = new TList();
301
302   fHistoDataSelected = 0;
303
304   if (fDataTree == 0) fDataTree = new TTreeSRedirector("TRD.TrackListMacroData.root");
305
306   // Collect the commands for each macro and add them to "data-from-list"
307   for (Int_t i = 0; i < iterator->GetEntries(); i++)
308   {
309     memset(name, '\0', sizeof(Char_t) * fkMaxMacroNameLength);
310     
311     cmds[i] = new Char_t[(fkMaxMacroPathNameLength + fkMaxApplyCommandLength)];
312     memset(cmds[i], '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
313
314 #ifdef ALIEVETRDTRACKLIST_DEBUG
315     printf("AliEveTRDTrackList: Applying process macro: %s\n", iterator->At(i)->GetTitle());
316 #endif
317  
318     // Extract the name
319     sscanf(iterator->At(i)->GetTitle(), "%s (Path: %*s)", name);
320    
321     // Delete ".C" at the end 
322     // -> Note: Physical address pointer, do NOT delete. / Changes "name" as well!
323     Char_t* dotC = (Char_t*)strrchr(name, '.');
324     if (dotC != 0)
325     {
326       *dotC = '\0';
327       dotC++;
328       *dotC = '\0';
329     }
330
331     // Add to "data-from-list"
332     fDataFromMacroList->Add(new TObjString(name));
333
334     // Find the type of the process macro
335     if (!IsHistogramMacro(name))
336     {
337       // Type 1
338       isHistoMacro[i] = kFALSE;
339       // Create the command 
340       sprintf(cmds[i], "%s(automaticTrackV1, results, n);", name);
341     }
342     else
343     {
344       // Type 2 (histo)
345       isHistoMacro[i] = kTRUE;
346       numHistoMacros++;
347       // Create the command 
348       sprintf(cmds[i], "%s(automaticTrackV1);", name);
349     } 
350   }  
351
352   // Allocate memory for the histograms
353   if (numHistoMacros > 0)  histos = new TH1*[numHistoMacros];
354   for (Int_t i = 0; i < numHistoMacros; i++)  histos[i] = 0;
355   
356   // Walk through the list of tracks     
357   for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter)
358   {
359     track = dynamic_cast<AliEveTRDTrack*>(*iter);
360
361     if (!track)  continue;
362     
363     // Skip tracks that have not been selected
364     if (!track->GetRnrState())  continue;
365       
366     trackv1 = (AliTRDtrackV1*)track->GetUserData();
367
368     track->ExportToCINT((Text_t*)"automaticTrack");
369     // Cast to AliTRDtrackV1
370     gROOT->ProcessLineSync("AliTRDtrackV1* automaticTrackV1 = (AliTRDtrackV1*)automaticTrack->GetUserData();");
371
372     // Collect data for each macro
373     for (Int_t i = 0, histoIndex = 0; i < iterator->GetEntries(); i++)
374     {
375       // Process for macro type 2 (histo)
376       if (isHistoMacro[i])
377       {
378         returnedHist = (TH1*)gROOT->ProcessLineSync(cmds[i]);
379         if (returnedHist != 0x0)
380         {
381           if (histos[histoIndex] == 0)  histos[histoIndex] = (TH1*)gROOT->ProcessLineSync(cmds[i]);
382           else  histos[histoIndex]->Add((const TH1*)gROOT->ProcessLineSync(cmds[i]));
383       
384           delete returnedHist;
385           returnedHist = 0;
386         }
387         histoIndex++;
388       }
389       // Process for macro type 1
390       else
391       {
392         // Create data pointers in CINT, execute the macro and get the data
393         gROOT->ProcessLineSync("Double_t* results = 0;");
394         gROOT->ProcessLineSync("Int_t n = 0;");
395         gROOT->ProcessLineSync(cmds[i]);
396         Double_t* results = (Double_t*)gROOT->ProcessLineSync("results;");
397         Int_t nResults = (Int_t)gROOT->ProcessLineSync("n;");
398         
399         if (results == 0)
400         {
401           Error("Apply macros", Form("Error reading data from macro \"%s\"", iterator->At(i)->GetTitle()));
402           continue;
403         }
404         for (Int_t resInd = 0; resInd < nResults; resInd++)
405         {
406           (*fDataTree) << Form("TrackData%d", i) << Form("Macro%d=", i) << results[resInd] << (Char_t*)"\n";   
407         }
408
409         delete results;
410         results = 0;
411       }
412     }
413   }    
414
415   for (Int_t i = 0, histoIndex = 0; i < iterator->GetEntries() && histoIndex < numHistoMacros; i++)
416   {
417     if (isHistoMacro[i])
418     {
419       // Might be empty (e.g. no tracks have been selected)!
420       if (histos[histoIndex] != 0)
421       {
422         (*fDataTree) << Form("TrackData%d", i) << Form("Macro%d=", i) << histos[histoIndex] << (Char_t*)"\n";
423       }
424       histoIndex++;
425     }
426   }
427
428   if (fDataTree != 0) delete fDataTree;
429   fDataTree = 0;
430
431   if (cmds != 0)  delete [] cmds;
432   if (isHistoMacro != 0)  delete isHistoMacro;
433   isHistoMacro = 0;
434
435   if (histos != 0)  delete [] histos;
436   histos = 0;
437
438   // Clear root
439   gROOT->Reset();
440   
441   // If there is data, select the first data set
442   if (iterator->GetEntries() > 0) SETBIT(fHistoDataSelected, 0);
443
444   // Now the data is stored in "TRD.TrackListMacroData.root"
445   // The editor will access this file to display the data
446 }
447
448 //______________________________________________________
449 void AliEveTRDTrackList::ApplySelectionMacros(TList* iterator)
450 {
451   Char_t name[fkMaxMacroNameLength];
452   Char_t cmd[(fkMaxMacroNameLength + fkMaxApplyCommandLength)];
453
454   AliEveTRDTrack* track = 0;
455   AliTRDtrackV1 *trackv1 = 0;
456   Bool_t selectedByMacro = kFALSE;
457
458   // Clear root
459   gROOT->Reset();
460
461   // Select all tracks at first. A track is then deselect, if at least one selection macro
462   // returns kFALSE for this track
463   // Enable all tracks (Note: EnableListElements(..) will call "ElementChanged", which will cause unforseen behaviour!)
464   for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter)
465   {
466     ((TEveElement*)(*iter))->SetRnrState(kTRUE);
467   }
468   SetRnrState(kTRUE);
469   
470   for (Int_t i = 0; i < iterator->GetEntries(); i++)
471   {
472
473     memset(name, '\0', sizeof(Char_t) * fkMaxMacroNameLength);
474     memset(cmd, '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
475
476 #ifdef ALIEVETRDTRACKLIST_DEBUG
477     printf("AliEveTRDTrackList: Applying selection macro: %s\n", iterator->At(i)->GetTitle());
478 #endif
479     
480     // Extract the name
481     sscanf(iterator->At(i)->GetTitle(), "%s (Path: %*s)", name);
482     // Delete ".C" at the end 
483     // -> Note: Physical address pointer, do NOT delete. / Changes "name" as well!
484     Char_t* dotC = (Char_t*)strrchr(name, '.');
485     if (dotC != 0)
486     {
487       *dotC = '\0';
488       dotC++;
489       *dotC = '\0';
490     }
491
492     // Create the command
493     sprintf(cmd, "%s(automaticTrackV1);", name);
494
495     // Walk through the list of tracks
496     for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter)
497     {
498       track = dynamic_cast<AliEveTRDTrack*>(*iter);
499
500       if (!track) continue;
501       
502       trackv1 = (AliTRDtrackV1*)track->GetUserData();
503
504       track->ExportToCINT((Text_t*)"automaticTrack");
505       // Cast to AliTRDtrackV1
506       gROOT->ProcessLineSync("AliTRDtrackV1* automaticTrackV1 = (AliTRDtrackV1*)automaticTrack->GetUserData();");
507       selectedByMacro = (Bool_t)gROOT->ProcessLineSync(cmd);
508       track->SetRnrState(selectedByMacro && track->GetRnrState());         
509     }
510   }
511
512   // Clear root
513   gROOT->Reset();  
514 }
515
516 //______________________________________________________
517 Char_t* AliEveTRDTrackList::MakeMacroEntry(const Char_t* path, const Char_t* name)
518 {
519   Char_t* entry = new Char_t[(fkMaxMacroPathNameLength + 30)];
520   memset(entry, '\0', sizeof(Char_t) * (fkMaxMacroPathNameLength + 30));
521
522   Char_t* systemPath = gSystem->ExpandPathName(path);
523   sprintf(entry, "%s (Path: %s)", name, systemPath);
524   delete systemPath;
525   systemPath = 0;
526
527   return entry;
528 }
529
530 //______________________________________________________
531 Bool_t AliEveTRDTrackList::IsHistogramMacro(const Char_t* name) 
532 {
533   TFunction* f = 0x0;
534   if ((f = gROOT->GetGlobalFunctionWithPrototype(name, "const AliTRDtrackV1*", kTRUE)) != 0x0)
535     if (strcmp(f->GetReturnTypeName(), "TH1*") == 0)  return kTRUE;
536
537   return kFALSE;  
538 }
539
540 //______________________________________________________
541 void AliEveTRDTrackList::RemoveProcessMacros(TList* iterator) 
542 {
543   TObjString* obj = 0;
544   for (Int_t i = 0; i < iterator->GetEntries(); i++)
545   {
546     obj = (TObjString*)fMacroList->Remove(fMacroList->FindObject(iterator->At(i)->GetTitle()));
547     
548     if (obj != 0) delete obj;
549   }
550   obj = 0;
551 }
552
553 //______________________________________________________
554 void AliEveTRDTrackList::RemoveSelectionMacros(TList* iterator) 
555 {
556   TObjString* obj = 0;
557   for (Int_t i = 0; i < iterator->GetEntries(); i++)
558   {
559     obj = (TObjString*)fMacroSelList->Remove(fMacroSelList->FindObject(iterator->At(i)->GetTitle()));
560     if (obj != 0) delete obj;
561   }
562   obj = 0;
563 }
564