1 // Author: Benjamin Hess 06/11/2009
3 /*************************************************************************
4 * Copyright (C) 2009, Alexandru Bercuci, Benjamin Hess. *
5 * All rights reserved. *
6 *************************************************************************/
9 //////////////////////////////////////////////////////////////////////////
11 // AliEveListAnalyser //
13 // An AliEveListAnalyser is, in principal, a TEveElementList //
14 // with some sophisticated features. You can add macros to this list, //
15 // which then can be applied to the list of tracks (these tracks can be //
16 // added to the list in the same way as for the TEveElementList). //
17 // In general, 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 TGeneralMacroData-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. //
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*); //
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*); //
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 //////////////////////////////////////////////////////////////////////////
60 // Uncomment to display debugging infos
61 //#define AliEveListAnalyser_DEBUG
64 #include <TFunction.h>
65 #include <TMethodArg.h>
69 #include <TObjString.h>
73 #include <TTreeStream.h>
74 #include <TMethodCall.h>
76 #include <AliTRDReconstructor.h>
78 #include <EveDet/AliEveListAnalyser.h>
79 #include <EveDet/AliEveListAnalyserEditor.h>
81 // TODO: Are these files required?
82 //#include <../PWG1/TRD/AliTRDrecoTask.h>
83 //#include <../PWG1/TRD/macros/AliTRDperformanceTrain.h>
85 ClassImp(AliEveListAnalyser)
87 ///////////////////////////////////////////////////////////
88 ///////////// AliEveListAnalyser ////////////////
89 ///////////////////////////////////////////////////////////
90 AliEveListAnalyser::AliEveListAnalyser(const Text_t* n, const Text_t* t, Bool_t doColor):
91 TEveElementList(n, t, doColor),
93 fDataFromMacroList(0x0),
96 fHistoDataSelected(0),
97 fMacroListSelected(0),
98 fSelectedTab(1) // Standard tab: "Apply macros" (index 1)
101 // TODO: Old version with style tab
103 fSelectedTab(1), // Standard tab: "Apply macros" (index 1)
108 // Creates the AliEveListAnalyser.
110 // Only accept childs of type TEveElement
111 SetChildClass(TEveElement::Class());
113 // Allocate memory for the lists and declare them as owners of their contents
114 fDataFromMacroList = new TList();
115 fDataFromMacroList->TCollection::SetOwner(kTRUE);
117 fMacroList = new TMap();
118 // Set map to owner of it's objects to delete them, if they are removed from the map
119 fMacroList->SetOwnerKeyValue(kTRUE, kTRUE);
121 // Set the build directory for AClic
122 if(gSystem->AccessPathName(Form("%s/.QArec" , gSystem->Getenv("HOME")))) gSystem->Exec("mkdir $HOME/.QArec");
123 gSystem->SetBuildDir(Form("%s/.QArec", gSystem->Getenv("HOME")));
125 AddStandardContent();
128 //______________________________________________________
129 AliEveListAnalyser::~AliEveListAnalyser()
131 // Frees allocated memory (lists etc.).
133 // Let the editor know that the list will be destroyed -> The editor will save the data
136 fEditor->SaveMacroList(fMacroList);
140 if (fDataFromMacroList != 0)
142 fDataFromMacroList->Delete();
143 delete fDataFromMacroList;
144 fDataFromMacroList = 0;
153 fMacroList->DeleteAll();
157 // Note: gSystem->AccessPathName(...) returns kTRUE, if the access FAILED!
158 if(!gSystem->AccessPathName(Form("/tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER"))))
159 gSystem->Exec(Form("rm /tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER")));
162 //______________________________________________________
163 Int_t AliEveListAnalyser::AddMacro(const Char_t* path, const Char_t* nameC, Bool_t forceReload)
165 // Checks, if the file exists and if the signature is correct.
166 // If these criteria are fullfilled, the library for this macro is built
167 // and the macro is added to the corresponding list.
168 // Supported macro types:
170 // Bool_t YourMacro(const TObject*)
171 // Bool_t YourMacro(const TObject*, const TObject*)
174 // void YourMacro(const TObject*, Double_t*&, Int_t&)
175 // void YourMacro(const TObject*, const TObject*, Double_t*&, Int_t&)
176 // TH1* YourMacro(const TObject*)
177 // TH1* YourMacro(const TObject*, const TObject*)
179 Char_t pathname[fkMaxMacroPathNameLength];
180 memset(pathname, '\0', sizeof(Char_t) * fkMaxMacroPathNameLength);
182 // Expand the path and create the pathname
183 Char_t* systemPath = gSystem->ExpandPathName(path);
184 sprintf(pathname, "%s/%s", systemPath, nameC);
188 // Delete ".C" from filename
189 Char_t name[fkMaxMacroNameLength];
190 memset(name, '\0', sizeof(Char_t) * fkMaxMacroNameLength);
192 for (UInt_t ind = 0; ind < fkMaxMacroNameLength && ind < strlen(nameC) - 2; ind++) name[ind] = nameC[ind];
194 // Check, if files exists
196 if((fp = fopen(pathname, "rb"))){
199 } else return NOT_EXIST_ERROR;
201 // Clean up root, load the desired macro and then check the type of the macro
202 // A.B. gROOT->Reset();
204 gROOT->ProcessLineSync(Form(".L %s+%c", pathname, forceReload ? '+' : ' '));
208 objectType = GetMacroObjectType(name);
210 // We need this line... otherwise, in some cases, there will be problems concerning ACLIC
211 gROOT->ProcessLineSync(Form(".L %s", pathname));
213 if (!objectType) return UNKNOWN_OBJECT_TYPE_ERROR;
215 AliEveListAnalyserMacroType type = GetMacroType(name, objectType->GetName(), kFALSE);
218 // A.B. gROOT->Reset();
220 // Has not the correct signature!
221 if (type == kUnknown) return SIGNATURE_ERROR;
223 // Only add macro, if it is not already in the list
224 Int_t returnValue = WARNING;
225 if(fMacroList->GetValue(name) == 0)
227 returnValue = AddMacroFast(path, name, type, objectType) ? SUCCESS : ERROR;
233 //______________________________________________________
234 Bool_t AliEveListAnalyser::AddMacroFast(const Char_t* path, const Char_t* name, AliEveListAnalyserMacroType type, TClass* objectType)
236 // Adds a macro (path/name) to the corresponding list. No checks are performed (file exists,
237 // macro already in list/map, signature correct), no libraries are created!
238 // You can use this function only, if the macro has been added successfully before
239 // (and then maybe was removed). The function is very fast. On success kTRUE is returned, otherwise: kFALSE;
241 Bool_t success = kFALSE;
245 case kSingleObjectSelect:
246 case kCorrelObjectSelect:
247 case kSingleObjectAnalyse:
248 case kSingleObjectHisto:
249 case kCorrelObjectAnalyse:
250 case kCorrelObjectHisto:
251 fMacroList->Add(new TObjString(name), new TGeneralMacroData(name, path, type, objectType));
253 // We do not know, where the element has been inserted - deselect this list
254 fMacroListSelected = 0;
258 #ifdef AliEveListAnalyser_DEBUG
259 // Successfull add will only be displayed in debug mode
260 printf("AliEveListAnalyser::AddMacroFast: Added macro \"%s/%s\" with object type \"%s\" to the corresponding list\n", path, name,
261 objectType->GetName());
267 // Error will always be displayed
268 printf("AliEveListAnalyser::AddMacroFast: ERROR: Could not add macro \"%s/%s\" with object type \"%s\" to the corresponding list\n",
269 path, name, objectType->GetName());
279 //______________________________________________________
280 void AliEveListAnalyser::AddStandardContent()
282 // Adds standard macros to the macro list.
284 // Add your standard macros here, e.g.:
285 // To add a macro use:
286 // AddMacro("$(ALICE_ROOT)/myFolder", "myMacroName.C");
287 // -> If the file does not exist, nothing happens. So if you want to handle this,
288 // use the return value of AddMacro (NOT_EXIST_ERROR is returned, if file does not exist)
289 // (-> You can also check for other return values (see AddMacro(...)))
291 const Char_t *libs[] = {"libANALYSIS.so", "libANALYSISalice.so", "libTENDER.so", "libPWG1.so"};
292 Int_t nlibs = static_cast<Int_t>(sizeof(libs)/sizeof(Char_t *));
293 for(Int_t ilib=0; ilib<nlibs; ilib++){
294 if(gSystem->Load(libs[ilib]) >= 0) continue;
295 AliError(Form("Fail loading %s.", libs[ilib]));
299 AliTRDrecoTask *task = 0x0;
301 for(Int_t it=2; it<NTRDQATASKS; it++){
302 TClass c(fgkTRDtaskClassName[it]);
303 task = (AliTRDrecoTask*)c.New();
304 task->SetMCdata(kFALSE);
305 if(!(fPlots = task->GetPlotFunctors())){
306 //AliWarning(Form("No Plot functors defined for task \"%s\"", fgkTRDtaskClassName[it]));
310 if(!(task->Histos())){
311 //AliWarning(Form("No Ref Histograms defined for task \"%s\"", fgkTRDtaskClassName[it]));
316 // export task to CINT and add functions
317 gROOT->ProcessLine(Form("%s* %s = (%s*)0x%lx;", fgkTRDtaskClassName[it], task->GetName(), fgkTRDtaskClassName[it], (void*)task));
318 TIter iter(fPlots); TMethodCall *m = 0x0;
319 while((m = dynamic_cast<TMethodCall*>(iter()))){
320 AddMacroFast("", Form("%s->%s", task->GetName(), m->GetMethodName()), kSingleTrackHisto);
326 //______________________________________________________
327 Bool_t AliEveListAnalyser::ApplyProcessMacros(const TList* selIterator, const TList* procIterator)
329 // Uses the procIterator (for the selected process macros) to apply the selected macros to the data.
330 // Returns kTRUE on success, otherwise kFALSE. If there no process macros selected, kTRUE is returned
331 // (this is no error!).
332 // The single object process macros are applied to all selected objects.
333 // The selIterator (for the selected selection macros) will be used to apply the correlated objects selection
334 // macros to all object pairs (whereby BOTH objects have to be selected, otherwise they will be skipped).
335 // All object pairs that have been selected by ALL correlated objects selection macros will be processed by
336 // the correlated objects process macros.
338 // No process macros need to be processed
339 if (procIterator->GetEntries() <= 0) return kTRUE;
342 // A.B. gROOT->Reset();
344 // Clear old data and re-allocate
345 if (fDataTree == 0x0){
346 TDirectory *cwd = gDirectory;
347 fDataTree = new TTreeSRedirector(Form("/tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER")));
351 Error("Apply process macros", Form("File \"/tmp/ListAnalyserMacroData_%s.root\" could not be accessed properly!",
352 gSystem->Getenv("USER")));
356 if (fDataFromMacroList != 0) {
357 fDataFromMacroList->Delete();
358 delete fDataFromMacroList;
360 fDataFromMacroList = new TList();
361 fDataFromMacroList->TCollection::SetOwner(kTRUE);
363 fHistoDataSelected = 0;
366 TGeneralMacroData* macro = 0;
368 Char_t** procCmds = 0;
369 AliEveListAnalyserMacroType* mProcType = 0;
370 if (procIterator->GetEntries() > 0) {
371 procCmds = new Char_t*[procIterator->GetEntries()];
372 mProcType = new AliEveListAnalyserMacroType[procIterator->GetEntries()];
375 Char_t** selCmds = 0;
376 AliEveListAnalyserMacroType* mSelType = 0;
377 if (selIterator->GetEntries() > 0) {
378 selCmds = new Char_t*[selIterator->GetEntries()];
379 mSelType = new AliEveListAnalyserMacroType[selIterator->GetEntries()];
382 Bool_t selectedByCorrSelMacro = kFALSE;
384 AliEveListAnalyserMacroType macroType = kUnknown;
385 Int_t numHistoMacros = 0;
388 TEveElement* object1 = 0;
389 TEveElement* object2 = 0;
391 // Collect the commands for each process macro and add them to "data-from-list"
392 for (Int_t i = 0; i < procIterator->GetEntries(); i++){
393 procCmds[i] = new Char_t[(fkMaxMacroPathNameLength + fkMaxApplyCommandLength)];
394 memset(procCmds[i], '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
396 macro = (TGeneralMacroData*)fMacroList->GetValue(procIterator->At(i)->GetTitle());
399 Error("Apply process macros",
400 Form("Macro list is corrupted: Macro \"%s\" is not registered!",
401 procIterator->At(i)->GetTitle()));
405 #ifdef AliEveListAnalyser_DEBUG
406 printf("AliEveListAnalyser: Checking process macro: %s\n", macro->GetName());
409 // Find the type of the process macro
410 macroType = macro->GetType();
411 if (macroType == kSingleObjectHisto || macroType == kCorrelObjectHisto){
412 mProcType[i] = macroType;
414 // Create the command
415 sprintf(procCmds[i], macro->GetCmd());
417 // Add to "data-from-list" -> Mark as a histo macro with the substring "(histo macro)"
418 fDataFromMacroList->Add(new TObjString(Form("%s (histo macro)", macro->GetName())));
419 } else if (macroType == kSingleObjectAnalyse || macroType == kCorrelObjectAnalyse) {
420 mProcType[i] = macroType;
421 // Create the command
422 sprintf(procCmds[i], macro->GetCmd());
424 // Add to "data-from-list"
425 fDataFromMacroList->Add(new TObjString(macro->GetName()));
427 Error("Apply process macros",
428 Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a process macro!",
429 macro->GetPath(), macro->GetName()));
430 mProcType[i] = kUnknown;
434 // Collect the commands for each selection macro and add them to "data-from-list"
435 for (Int_t i = 0; i < selIterator->GetEntries(); i++){
436 selCmds[i] = new Char_t[(fkMaxMacroPathNameLength + fkMaxApplyCommandLength)];
437 memset(selCmds[i], '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
439 macro = (TGeneralMacroData*)fMacroList->GetValue(selIterator->At(i)->GetTitle());
442 Error("Apply process macros",
443 Form("Macro list is corrupted: Macro \"%s\" is not registered!",
444 selIterator->At(i)->GetTitle()));
448 #ifdef AliEveListAnalyser_DEBUG
449 printf("AliEveListAnalyser: Checking selection macro: %s\n", macro->GetName());
452 // Find the type of the process macro
453 macroType = macro->GetType();
455 // Single Object select macro
456 if (macroType == kSingleObjectSelect) {
457 // Has already been processed by ApplySTSelectionMacros(...)
458 mSelType[i] = macroType;
460 // Correlated Objects select macro
461 else if (macroType == kCorrelObjectSelect) {
462 mSelType[i] = macroType;
464 // Create the command
465 sprintf(selCmds[i], macro->GetCmd());
467 Error("Apply process macros",
468 Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a selection macro!",
469 macro->GetPath(), macro->GetName()));
470 mSelType[i] = kUnknown;
474 // Allocate memory for the histograms
475 if (numHistoMacros > 0) histos = new TH1*[numHistoMacros];
476 for (Int_t i = 0; i < numHistoMacros; i++) histos[i] = 0x0;
479 //////////////////////////////////
480 // WALK THROUGH THE LIST OF OBJECTS
481 //////////////////////////////////
482 for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter){
483 if(!(object1 = dynamic_cast<TEveElement*>(*iter))) continue;
485 // Skip objects that have not been selected
486 if (!object1->GetRnrState()) continue;
488 // Cast to the "real" object behind
489 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object1));
490 gROOT->ProcessLineSync("TObject* automaticObject_1 = (TObject*)automaticEveElement->GetUserData();");
492 // Collect data for each macro
493 for (Int_t i = 0, histoIndex = 0; i < procIterator->GetEntries(); i++){
494 // Single object histo
495 if (mProcType[i] == kSingleObjectHisto){
496 histos[histoIndex++] = (TH1*)gROOT->ProcessLineSync(procCmds[i]);
497 // Correlated Objects histo
498 } else if (mProcType[i] == kCorrelObjectHisto) {
499 // Loop over all pairs behind the current one - together with the other loop this will be a loop
500 // over all pairs. We have a pair of objects, if and only if both objects of the pair are selected (Rnr-state)
501 // and are not equal.
502 // The correlated objects process macro will be applied to all pairs that will be additionally selected by
503 // all correlated objects selection macros.
504 TEveElement::List_i iter2 = iter;
506 for ( ; iter2 != this->EndChildren(); ++iter2)
508 if(!(object2 = dynamic_cast<TEveElement*>(*iter2))) continue;
510 // Skip objects that have not been selected
511 if (!object2->GetRnrState()) continue;
513 // Cast to the "real" object behind
514 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object2));
515 gROOT->ProcessLineSync("TObject* automaticObject_2 = (TObject*)automaticEveElement->GetUserData();");
517 // Select object by default (so it will be processed, if there are no correlated objects selection macros!)
518 selectedByCorrSelMacro = kTRUE;
519 for (Int_t j = 0; j < selIterator->GetEntries(); j++){
520 if (mSelType[j] == kCorrelObjectSelect){
521 selectedByCorrSelMacro = (Bool_t)gROOT->ProcessLineSync(selCmds[j]);
522 if (!selectedByCorrSelMacro) break;
526 // If the pair has not been selected by the correlated objects selection macros, skip it!
527 if (!selectedByCorrSelMacro) continue;
529 histos[histoIndex] = (TH1*)gROOT->ProcessLineSync(procCmds[i]);
533 // Single object analyse
534 else if (mProcType[i] == kSingleObjectAnalyse) {
535 // Create data pointers in CINT, execute the macro and get the data
536 gROOT->ProcessLineSync("Double_t* results = 0;");
537 gROOT->ProcessLineSync("Int_t n = 0;");
538 gROOT->ProcessLineSync(procCmds[i]);
539 Double_t* results = (Double_t*)gROOT->ProcessLineSync("results;");
540 Int_t nResults = (Int_t)gROOT->ProcessLineSync("n;");
543 Error("Apply macros", Form("Error reading data from macro \"%s\"", procIterator->At(i)->GetTitle()));
546 for (Int_t resInd = 0; resInd < nResults; resInd++){
547 (*fDataTree) << Form("ObjectData%d", i) << Form("Macro%d=", i) << results[resInd] << (Char_t*)"\n";
553 // Correlated objects analyse
554 else if (mProcType[i] == kCorrelObjectAnalyse){
555 // Loop over all pairs behind the current one - together with the other loop this will be a loop
556 // over all pairs. We have a pair of objects, if and only if both objects of the pair are selected (Rnr-state)
557 // and are not equal.
558 // The correlated objects process macro will be applied to all pairs that will be additionally selected by
559 // all correlated objects selection macros.
560 TEveElement::List_i iter2 = iter;
563 for ( ; iter2 != this->EndChildren(); ++iter2) {
564 if(!(object2 = dynamic_cast<TEveElement*>(*iter2))) continue;
566 // Skip objects that have not been selected
567 if (!object2->GetRnrState()) continue;
569 // Cast to the "real" object behind
570 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object2));
571 gROOT->ProcessLineSync("TObject* automaticObject_2 = (TObject*)automaticEveElement->GetUserData();");
573 // Select object by default (so it will be processed, if there are no correlated objects selection macros!)
574 selectedByCorrSelMacro = kTRUE;
575 for (Int_t j = 0; j < selIterator->GetEntries(); j++) {
576 if (mSelType[j] == kCorrelObjectSelect) {
577 selectedByCorrSelMacro = (Bool_t)gROOT->ProcessLineSync(selCmds[j]);
578 if (!selectedByCorrSelMacro) break;
582 // If the pair has not been selected by the correlated objects selection macros, skip it!
583 if (!selectedByCorrSelMacro) continue;
585 // Create data pointers in CINT, execute the macro and get the data
586 gROOT->ProcessLineSync("Double_t* results = 0;");
587 gROOT->ProcessLineSync("Int_t n = 0;");
588 gROOT->ProcessLineSync(procCmds[i]);
589 Double_t* results = (Double_t*)gROOT->ProcessLineSync("results;");
590 Int_t nResults = (Int_t)gROOT->ProcessLineSync("n;");
593 Error("Apply macros", Form("Error reading data from macro \"%s\"", procIterator->At(i)->GetTitle()));
596 for (Int_t resInd = 0; resInd < nResults; resInd++) {
597 (*fDataTree) << Form("ObjectData%d", i) << Form("Macro%d=", i) << results[resInd] << (Char_t*)"\n";
607 for (Int_t i = 0, histoIndex = 0; i < procIterator->GetEntries() && histoIndex < numHistoMacros; i++) {
608 if (mProcType[i] == kSingleObjectHisto || mProcType[i] == kCorrelObjectHisto) {
609 // Might be empty (e.g. no objects have been selected)!
610 if (histos[histoIndex]) {
611 (*fDataTree) << Form("ObjectData%d", i) << Form("Macro%d=", i) << histos[histoIndex] << (Char_t*)"\n";
617 if (fDataTree != 0) delete fDataTree;
620 if (procCmds != 0) delete [] procCmds;
622 if (mProcType != 0) delete mProcType;
625 if (selCmds != 0) delete [] selCmds;
627 if (mSelType != 0) delete mSelType;
630 if (histos != 0) delete [] histos;
634 // A.B. gROOT->Reset();
636 // If there is data, select the first data set
637 if (procIterator->GetEntries() > 0) SETBIT(fHistoDataSelected, 0);
639 // Now the data is stored in "/tmp/ListAnalyserMacroData_$USER.root"
640 // The editor will access this file to display the data
644 //______________________________________________________
645 void AliEveListAnalyser::ApplySTSelectionMacros(const TList* iterator)
647 // Uses the iterator (for the selected selection macros) to apply the selected macros to the data.
648 // The rnr-states of the objects are set according to the result of the macro calls (kTRUE, if all
649 // macros return kTRUE for this object, otherwise: kFALSE).
650 // "ST" stands for "single object". This means that only single object selection macros are applied.
651 // Correlated objects selection macros will be used inside the call of ApplyProcessMacros(...)!
653 TGeneralMacroData* macro = 0;
654 AliEveListAnalyserMacroType macroType = kUnknown;
655 TEveElement* object1 = 0;
656 Bool_t selectedByMacro = kFALSE;
659 // A.B. gROOT->Reset();
661 // Select all objecs at first. A object is then deselected, if at least one selection macro
662 // returns kFALSE for this object.
663 // Enable all objects (Note: EnableListElements(..) will call "ElementChanged", which will cause unforeseen behaviour!)
664 for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter) ((TEveElement*)(*iter))->SetRnrState(kTRUE);
667 for (Int_t i = 0; i < iterator->GetEntries(); i++){
668 macro = (TGeneralMacroData*)fMacroList->GetValue(iterator->At(i)->GetTitle());
671 Error("Apply selection macros",
672 Form("Macro list is corrupted: Macro \"%s\" is not registered!", iterator->At(i)->GetTitle()));
676 #ifdef AliEveListAnalyser_DEBUG
677 printf("AliEveListAnalyser: Applying selection macro: %s\n", macro->GetName());
680 // Determine macro type
681 macroType = macro->GetType();
683 // Single object select macro
684 if (macroType == kSingleObjectSelect){
685 // Walk through the list of objects
686 for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter)
688 object1 = dynamic_cast<TEveElement*>(*iter);
690 if (!object1) continue;
692 // If the object has already been deselected, nothing is to do here
693 if (!object1->GetRnrState()) continue;
695 // Cast to the "real" object behind
696 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object1));
697 gROOT->ProcessLineSync("TObject* automaticObject_1 = (TObject*)automaticEveElement->GetUserData();");
699 selectedByMacro = (Bool_t)gROOT->ProcessLineSync(macro->GetCmd());
700 object1->SetRnrState(selectedByMacro && object1->GetRnrState());
703 // Correlated objects select macro
704 else if (macroType == kCorrelObjectSelect){
705 // Will be processed in ApplyProcessMacros(...)
708 Error("Apply selection macros",
709 Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a selection macro!",
710 macro->GetPath(), macro->GetName()));
715 // A.B. gROOT->Reset();
718 // TODO -> Type checking
719 //______________________________________________________
720 AliEveListAnalyser::AliEveListAnalyserMacroType AliEveListAnalyser::GetMacroType(const Char_t* name, const Char_t* objectType, Bool_t UseList) const
722 // Returns the type of the corresponding macro, that accepts pointers of the class "objectType" as a parametre.
723 // If "UseList" is kTRUE, the type will be looked up in the internal list (very fast). But if this list
724 // does not exist, you have to use kFALSE for this parameter. Then the type will be determined by the
725 // prototype! NOTE: It is assumed that the macro has been compiled! If not, the return value is not
726 // predictable, but normally will be kUnknown.
727 // Note: AddMacro(Fast) will update the internal list and RemoveMacros respectively.
729 AliEveListAnalyserMacroType type = kUnknown;
731 TString* typeStr = 0;
735 typeStr = new TString(objectType);
736 // Remove white-spaces
737 typeStr->ReplaceAll(" ", "");
741 typeStr = new TString("TObject");
744 TString* mangled1Str = new TString();
745 TString* mangled2Str = new TString();
746 TString* mangled3Str = new TString();
747 TString* mangled4Str = new TString();
748 TString* mangledArg1Str = new TString();
749 TString* mangledArg2Str = new TString();
751 // We want "const 'OBJECTTYPE'*"
752 mangled1Str->Append("const ").Append(*typeStr).Append("*");
754 // We want "const 'OBJECTTYPE'*, Double_t*&, Int_t&"
755 mangled2Str->Append("const ").Append(*typeStr).Append("*, Double_t*&, Int_t&");
757 // We want "const 'OBJECTTYPE'*, const 'OBJECTTYPE'*"
758 mangled3Str->Append("const ").Append(*typeStr).Append("*, const ").Append(*typeStr).Append("*");
760 // We want "const 'OBJECTTYPE'*, const 'OBJECTTYPE'*, Double_t*&, Int_t&"
761 mangled4Str->Append("const ").Append(*typeStr).Append("*, const ").Append(*typeStr).Append("*, Double_t*&, Int_t&");
763 // We want "oPconstsP'OBJECTTYPE'mUsP"
764 mangledArg1Str->Append("oPconstsP").Append(*typeStr).Append("mUsP");
766 // We want "cOconstsP'OBJECTTYPE'mUsP"
767 mangledArg2Str->Append("cOconstsP").Append(*typeStr).Append("mUsP");
769 // Re-do the check of the macro type
771 // Single object select macro or single object histo macro?
772 TFunction* f = gROOT->GetGlobalFunctionWithPrototype(name, mangled1Str->Data(), kTRUE);
776 // Some additional check (is the parameter EXACTLY of the desired type?)
777 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0)
779 // Single object select macro?
780 if (!strcmp(f->GetReturnTypeName(), "Bool_t"))
782 type = kSingleObjectSelect;
784 // single object histo macro?
785 else if (!strcmp(f->GetReturnTypeName(), "TH1*"))
787 type = kSingleObjectHisto;
791 // Single object analyse macro?
792 else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, mangled2Str->Data(), kTRUE))
795 if (!strcmp(f->GetReturnTypeName(), "void"))
797 // Some additional check (are the parameters EXACTLY of the desired type?)
798 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0 &&
799 strstr(f->GetMangledName(), "cODouble_tmUaNsP") != 0x0 &&
800 strstr(f->GetMangledName(), "cOInt_taNsP") != 0x0)
802 type = kSingleObjectAnalyse;
806 // Correlated objects select macro or correlated objects histo macro?
807 else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, mangled3Str->Data(), kTRUE))
810 // Some additional check (is the parameter EXACTLY of the desired type?)
811 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0 &&
812 strstr(f->GetMangledName(), mangledArg2Str->Data()) != 0x0)
814 // Correlated objects select macro?
815 if (!strcmp(f->GetReturnTypeName(), "Bool_t"))
817 type = kCorrelObjectSelect;
819 // Correlated objects histo macro?
820 else if (!strcmp(f->GetReturnTypeName(), "TH1*"))
822 type = kCorrelObjectHisto;
826 // Correlated objects analyse macro?
827 else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, mangled4Str->Data(), kTRUE))
830 if (!strcmp(f->GetReturnTypeName(), "void"))
832 // Some additional check (is the parameter EXACTLY of the desired type?)
833 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0 &&
834 strstr(f->GetMangledName(), mangledArg2Str->Data()) != 0x0 &&
835 strstr(f->GetMangledName(), "cODouble_tmUaNsP") != 0x0 &&
836 strstr(f->GetMangledName(), "cOInt_taNsP") != 0x0)
838 type = kCorrelObjectAnalyse;
843 // Use list to look up the macro type
846 TGeneralMacroData* macro = 0;
847 macro = (TGeneralMacroData*)fMacroList->GetValue(name);
848 if (macro == 0) return kUnknown;
850 type = macro->GetType();
853 case kSingleObjectSelect:
854 case kSingleObjectAnalyse:
855 case kSingleObjectHisto:
856 case kCorrelObjectSelect:
857 case kCorrelObjectAnalyse:
858 case kCorrelObjectHisto:
867 if (mangled1Str != 0)
869 mangled1Str->Clear();
873 if (mangled2Str != 0)
875 mangled2Str->Clear();
879 if (mangled3Str != 0)
881 mangled3Str->Clear();
885 if (mangled4Str != 0)
887 mangled4Str->Clear();
891 if (mangledArg1Str != 0)
893 mangledArg1Str->Clear();
894 delete mangledArg1Str;
897 if (mangledArg2Str != 0)
899 mangledArg2Str->Clear();
900 delete mangledArg2Str;
914 // TODO: IMPLEMENTATION + DOCUMENTATION
915 //______________________________________________________
916 TClass* AliEveListAnalyser::GetMacroObjectType(const Char_t* name) const
918 TFunction* f = gROOT->GetGlobalFunction(name, 0 , kTRUE);
924 list = f->GetListOfMethodArgs();
926 if (!list->IsEmpty())
928 m = (TMethodArg*)list->At(0);
930 if (m) return TClass::GetClass(m->GetTypeName());
938 //______________________________________________________
939 void AliEveListAnalyser::RemoveSelectedMacros(const TList* iterator)
941 // Uses the iterator (for the selected macros) to remove the selected macros from
942 // the corresponding list.
946 for (Int_t i = 0; i < iterator->GetEntries(); i++)
948 entry = (TPair*)fMacroList->FindObject(iterator->At(i)->GetTitle());
952 Error("AliEveListAnalyser::RemoveSelectedMacros", Form("Macro \"%s\" not found in list!",
953 iterator->At(i)->GetTitle()));
960 Error("AliEveListAnalyser::RemoveSelectedMacros", Form("Key for macro \"%s\" not found in list!",
961 iterator->At(i)->GetTitle()));
965 // Key and value will be deleted, too, since fMacroList is the owner of them
966 Bool_t rem = fMacroList->DeleteEntry(key);
970 #ifdef AliEveListAnalyser_DEBUG
971 printf("AliEveListAnalyser::RemoveSelectedMacros(): Removed macro: %s\n", iterator->At(i)->GetTitle());
976 Error("AliEveListAnalyser::RemoveSelectedMacros", Form("Macro \"%s\" could not be removed from the list!",
977 iterator->At(i)->GetTitle()));