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