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 YourObjectType*); //
42 // Bool_t YourMacro(const YourObjectType*, const YourObjectType*); //
45 // void YourMacro(const YourObjectType*, Double_t*&, Int_t&); //
46 // void YourMacro(const YourObjectType*, const YourObjectType*, //
47 // Double_t*&, Int_t&); //
48 // TH1* YourMacro(const YourObjectType*); //
49 // TH1* YourMacro(const YourObjectType*, const YourObjectType*); //
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 //TODO - NEW -> Ordering! resp. remove the non-needed files
78 #include <TEveManager.h>
79 #include <TGLSelectRecord.h>
80 #include <TGLViewer.h>
82 #include <AliTRDReconstructor.h>
84 #include <EveDet/AliEveListAnalyser.h>
85 #include <EveDet/AliEveListAnalyserEditor.h>
87 ClassImp(AliEveListAnalyser)
89 ///////////////////////////////////////////////////////////
90 ///////////// AliEveListAnalyser ////////////////
91 ///////////////////////////////////////////////////////////
92 AliEveListAnalyser::AliEveListAnalyser(const Text_t* n, const Text_t* t, Bool_t doColor):
93 TEveElementList(n, t, doColor),
95 fDataFromMacroList(0x0),
99 fHistoDataSelected(0),
100 fMacroListSelected(0),
101 fSelectedTab(2) // Standard tab: "Apply macros" (index 2)
103 // Creates the AliEveListAnalyser.
105 // Only accept childs of type TEveElement
106 SetChildClass(TEveElement::Class());
108 // Allocate memory for the lists and declare them as owners of their contents
109 fDataFromMacroList = new TList();
110 fDataFromMacroList->TCollection::SetOwner(kTRUE);
112 fMacroList = new TMap();
113 // Set map to owner of it's objects to delete them, if they are removed from the map
114 fMacroList->SetOwnerKeyValue(kTRUE, kTRUE);
116 // Set the build directory for AClic
117 if(gSystem->AccessPathName(Form("%s/.QArec" , gSystem->Getenv("HOME")))) gSystem->Exec("mkdir $HOME/.QArec");
118 gSystem->SetBuildDir(Form("%s/.QArec", gSystem->Getenv("HOME")));
120 AddStandardContent();
123 //______________________________________________________
124 AliEveListAnalyser::~AliEveListAnalyser()
126 // Frees allocated memory (lists etc.).
128 // Stop adding objects
131 // Let the editor know that the list will be destroyed -> The editor will save the data
134 fEditor->SaveMacroList(fMacroList);
138 if (fDataFromMacroList != 0)
140 fDataFromMacroList->Delete();
141 delete fDataFromMacroList;
142 fDataFromMacroList = 0;
151 fMacroList->DeleteAll();
155 // Note: gSystem->AccessPathName(...) returns kTRUE, if the access FAILED!
156 if(!gSystem->AccessPathName(Form("/tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER"))))
157 gSystem->Exec(Form("rm /tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER")));
160 //______________________________________________________
161 Int_t AliEveListAnalyser::AddMacro(const Char_t* path, const Char_t* nameC, Bool_t forceReload)
163 // Checks, if the file exists and if the signature is correct.
164 // If these criteria are fullfilled, the library for this macro is built
165 // and the macro is added to the corresponding list.
166 // Supported macro types:
168 // Bool_t YourMacro(const YourObjectType*)
169 // Bool_t YourMacro(const YourObjectType*, const YourObjectType*)
172 // void YourMacro(const YourObjectType*, Double_t*&, Int_t&)
173 // void YourMacro(const YourObjectType*, const TObject*, Double_t*&, Int_t&)
174 // TH1* YourMacro(const YourObjectType*)
175 // TH1* YourMacro(const YourObjectType*, const YourObjectType*)
177 Char_t pathname[fkMaxMacroPathNameLength];
178 memset(pathname, '\0', sizeof(Char_t) * fkMaxMacroPathNameLength);
180 // Expand the path and create the pathname
181 Char_t* systemPath = gSystem->ExpandPathName(path);
182 sprintf(pathname, "%s/%s", systemPath, nameC);
186 // Delete ".C" from filename
187 Char_t name[fkMaxMacroNameLength];
188 memset(name, '\0', sizeof(Char_t) * fkMaxMacroNameLength);
190 for (UInt_t ind = 0; ind < fkMaxMacroNameLength && ind < strlen(nameC) - 2; ind++) name[ind] = nameC[ind];
192 // Check, if files exists
194 if((fp = fopen(pathname, "rb"))){
197 } else return NOT_EXIST_ERROR;
199 // Clean up root, load the desired macro and then check the type of the macro
200 // A.B. gROOT->Reset();
202 gROOT->ProcessLineSync(Form(".L %s+%c", pathname, forceReload ? '+' : ' '));
206 objectType = GetMacroObjectType(name);
208 // We need this line... otherwise, in some cases, there will be problems concerning ACLIC
209 gROOT->ProcessLineSync(Form(".L %s", pathname));
211 if (!objectType) return UNKNOWN_OBJECT_TYPE_ERROR;
213 AliEveListAnalyserMacroType type = GetMacroType(name, objectType->GetName(), kFALSE);
216 // A.B. gROOT->Reset();
218 // Has not the correct signature!
219 if (type == kUnknown) return SIGNATURE_ERROR;
221 // Only add macro, if it is not already in the list
222 Int_t returnValue = WARNING;
223 if(fMacroList->GetValue(name) == 0)
225 returnValue = AddMacroFast(path, name, type, objectType) ? SUCCESS : ERROR;
231 //______________________________________________________
232 Bool_t AliEveListAnalyser::AddMacroFast(const Char_t* path, const Char_t* name, AliEveListAnalyserMacroType type, TClass* objectType)
234 // Adds a macro (path/name) to the corresponding list. No checks are performed (file exists,
235 // macro already in list/map, signature correct), no libraries are created!
236 // You can use this function only, if the macro has been added successfully before
237 // (and then maybe was removed). The function is very fast. On success kTRUE is returned, otherwise: kFALSE;
239 Bool_t success = kFALSE;
243 case kSingleObjectSelect:
244 case kCorrelObjectSelect:
245 case kSingleObjectAnalyse:
246 case kSingleObjectHisto:
247 case kCorrelObjectAnalyse:
248 case kCorrelObjectHisto:
249 fMacroList->Add(new TObjString(name), new TGeneralMacroData(name, path, type, objectType));
251 // We do not know, where the element has been inserted - deselect this list
252 fMacroListSelected = 0;
256 #ifdef AliEveListAnalyser_DEBUG
257 // Successfull add will only be displayed in debug mode
258 printf("AliEveListAnalyser::AddMacroFast: Added macro \"%s/%s\" with object type \"%s\" to the corresponding list\n", path, name,
259 objectType->GetName());
265 // Error will always be displayed
266 printf("AliEveListAnalyser::AddMacroFast: ERROR: Could not add macro \"%s/%s\" with object type \"%s\" to the corresponding list\n",
267 path, name, objectType->GetName());
277 //TODO - NEW - To be implemented, tested, documented
278 //______________________________________________________
279 void AliEveListAnalyser::AddObjectToList(Int_t pointId)
281 TEvePointSet* ps = dynamic_cast<TEvePointSet*>((TQObject*) gTQSender);
285 Error("AliEveListAnalyser::AddObjectToList", "Zero pointer!\n");
289 // Check, if object is already there. If so, remove it!
291 // 1st possibility: Object of the list clicked
292 if (this->HasChild(ps))
294 this->RemoveElement(ps);
298 TObject* obj = ps->GetPointId(pointId);
301 // 2nd possibility: Same object clicked again
302 TEveElement* listObj = 0x0;
303 listObj = this->FindChild(Form("[viewer:%d] %s%d", obj->GetUniqueID(), obj->GetName(), pointId));
306 this->RemoveElement(listObj);
310 // Object clicked that is not in the list -> Add this object to list
311 TEvePointSet* newPS = new TEvePointSet(Form("[viewer:%d] %s%d", obj->GetUniqueID(), obj->GetName(), pointId));
312 Double_t x = 0, y = 0, z = 0;
313 ps->GetPoint(pointId, x, y, z);
314 newPS->SetPoint(0, x, y, z);
315 newPS->SetUserData(obj);
316 newPS->SetMarkerColor(5);
317 newPS->SetMarkerStyle(2);
318 newPS->SetMarkerSize(2.0);
325 Error("AliEveListAnalyser::AddObjectToList", "Selected object is NULL and therefore ignored!");
329 TGLSelectRecord rec = gEve->GetDefaultGLViewer()->GetSelRec();
331 printf("Objects (%d):\n", rec.GetN());
332 for (int i = 0; i < rec.GetN(); i++)
334 //printf("%s\n", ((TObject*)rec.GetItem(i))->IsA()->GetName());
338 //printf("Type: %s\npointID: %s\n\n", ps->IsA()->GetName(), pointId);
339 //printf("Type objectsender: %s\nType sender: %s\n", ((TQObject*)gTQSender)->IsA()->GetName(), ((TQObjSender*)gTQSender)->IsA()->GetName());
342 //______________________________________________________
343 void AliEveListAnalyser::AddStandardContent()
345 // Adds standard macros to the macro list.
347 // Add your standard macros here, e.g.:
348 // To add a macro use:
349 // AddMacro("$(ALICE_ROOT)/myFolder", "myMacroName.C");
350 // -> If the file does not exist, nothing happens. So if you want to handle this,
351 // use the return value of AddMacro (NOT_EXIST_ERROR is returned, if file does not exist)
352 // (-> You can also check for other return values (see AddMacro(...)))
356 //______________________________________________________
357 Bool_t AliEveListAnalyser::ApplyProcessMacros(const TList* selIterator, const TList* procIterator)
359 // Uses the procIterator (for the selected process macros) to apply the selected macros to the data.
360 // Returns kTRUE on success, otherwise kFALSE. If there no process macros selected, kTRUE is returned
361 // (this is no error!).
362 // The single object process macros are applied to all selected objects.
363 // The selIterator (for the selected selection macros) will be used to apply the correlated objects selection
364 // macros to all object pairs (whereby BOTH objects have to be selected, otherwise they will be skipped).
365 // All object pairs that have been selected by ALL correlated objects selection macros will be processed by
366 // the correlated objects process macros.
368 // No process macros need to be processed
369 if (procIterator->GetEntries() <= 0) return kTRUE;
372 // A.B. gROOT->Reset();
374 // Clear old data and re-allocate
375 if (fDataTree == 0x0){
376 TDirectory *cwd = gDirectory;
377 fDataTree = new TTreeSRedirector(Form("/tmp/ListAnalyserMacroData_%s.root", gSystem->Getenv("USER")));
381 Error("Apply process macros", Form("File \"/tmp/ListAnalyserMacroData_%s.root\" could not be accessed properly!",
382 gSystem->Getenv("USER")));
386 if (fDataFromMacroList != 0) {
387 fDataFromMacroList->Delete();
388 delete fDataFromMacroList;
390 fDataFromMacroList = new TList();
391 fDataFromMacroList->TCollection::SetOwner(kTRUE);
393 fHistoDataSelected = 0;
396 TGeneralMacroData* macro = 0;
398 Char_t** procCmds = 0;
399 AliEveListAnalyserMacroType* mProcType = 0;
400 if (procIterator->GetEntries() > 0) {
401 procCmds = new Char_t*[procIterator->GetEntries()];
402 mProcType = new AliEveListAnalyserMacroType[procIterator->GetEntries()];
405 TClass** mProcObjectType = 0;
406 if (procIterator->GetEntries() > 0) {
407 mProcObjectType = new TClass*[procIterator->GetEntries()];
410 Char_t** selCmds = 0;
411 AliEveListAnalyserMacroType* mSelType = 0;
412 if (selIterator->GetEntries() > 0) {
413 selCmds = new Char_t*[selIterator->GetEntries()];
414 mSelType = new AliEveListAnalyserMacroType[selIterator->GetEntries()];
417 TClass** mSelObjectType = 0;
418 if (selIterator->GetEntries() > 0) {
419 mSelObjectType = new TClass*[selIterator->GetEntries()];
422 Bool_t selectedByCorrSelMacro = kFALSE;
424 AliEveListAnalyserMacroType macroType = kUnknown;
425 Int_t numHistoMacros = 0;
428 TEveElement* object1 = 0;
429 TEveElement* object2 = 0;
431 // Collect the commands for each process macro and add them to "data-from-list"
432 for (Int_t i = 0; i < procIterator->GetEntries(); i++){
433 procCmds[i] = new Char_t[(fkMaxMacroPathNameLength + fkMaxApplyCommandLength)];
434 memset(procCmds[i], '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
436 macro = (TGeneralMacroData*)fMacroList->GetValue(procIterator->At(i)->GetTitle());
439 Error("Apply process macros",
440 Form("Macro list is corrupted: Macro \"%s\" is not registered!",
441 procIterator->At(i)->GetTitle()));
445 #ifdef AliEveListAnalyser_DEBUG
446 printf("AliEveListAnalyser: Checking process macro: %s\n", macro->GetName());
449 // Find the object type of the macro
450 mProcObjectType[i] = macro->GetObjectType();
452 // Find the type of the process macro
453 macroType = macro->GetType();
454 if (macroType == kSingleObjectHisto || macroType == kCorrelObjectHisto){
455 mProcType[i] = macroType;
457 // Create the command
458 sprintf(procCmds[i], macro->GetCmd());
460 // Add to "data-from-list" -> Mark as a histo macro with the substring "(histo macro)"
461 fDataFromMacroList->Add(new TObjString(Form("%s (histo macro)", macro->GetName())));
462 } else if (macroType == kSingleObjectAnalyse || macroType == kCorrelObjectAnalyse) {
463 mProcType[i] = macroType;
464 // Create the command
465 sprintf(procCmds[i], macro->GetCmd());
467 // Add to "data-from-list"
468 fDataFromMacroList->Add(new TObjString(macro->GetName()));
470 Error("Apply process macros",
471 Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a process macro!",
472 macro->GetPath(), macro->GetName()));
473 mProcType[i] = kUnknown;
477 // Collect the commands for each selection macro and add them to "data-from-list"
478 for (Int_t i = 0; i < selIterator->GetEntries(); i++){
479 selCmds[i] = new Char_t[(fkMaxMacroPathNameLength + fkMaxApplyCommandLength)];
480 memset(selCmds[i], '\0', sizeof(Char_t) * (fkMaxMacroNameLength + fkMaxApplyCommandLength));
482 macro = (TGeneralMacroData*)fMacroList->GetValue(selIterator->At(i)->GetTitle());
485 Error("Apply process macros",
486 Form("Macro list is corrupted: Macro \"%s\" is not registered!",
487 selIterator->At(i)->GetTitle()));
491 #ifdef AliEveListAnalyser_DEBUG
492 printf("AliEveListAnalyser: Checking selection macro: %s\n", macro->GetName());
495 // Find the object type of the macro
496 mSelObjectType[i] = macro->GetObjectType();
498 // Find the type of the process macro
499 macroType = macro->GetType();
501 // Single Object select macro
502 if (macroType == kSingleObjectSelect) {
503 // Has already been processed by ApplySTSelectionMacros(...)
504 mSelType[i] = macroType;
506 // Correlated Objects select macro
507 else if (macroType == kCorrelObjectSelect) {
508 mSelType[i] = macroType;
510 // Create the command
511 sprintf(selCmds[i], macro->GetCmd());
513 Error("Apply process macros",
514 Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a selection macro!",
515 macro->GetPath(), macro->GetName()));
516 mSelType[i] = kUnknown;
520 // Allocate memory for the histograms
521 if (numHistoMacros > 0) histos = new TH1*[numHistoMacros];
522 for (Int_t i = 0; i < numHistoMacros; i++) histos[i] = 0x0;
525 //////////////////////////////////
526 // WALK THROUGH THE LIST OF OBJECTS
527 //////////////////////////////////
528 for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter){
529 if(!(object1 = dynamic_cast<TEveElement*>(*iter))) continue;
531 // Skip objects that have not been selected
532 if (!object1->GetRnrState()) continue;
534 // Cast to the "real" object behind
535 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object1));
536 gROOT->ProcessLineSync("TObject* automaticObject_1 = (TObject*)automaticEveElement->GetUserData();");
538 // Collect data for each macro
539 for (Int_t i = 0, histoIndex = 0; i < procIterator->GetEntries(); i++){
540 // Find the type of the object and relate it to the macro object type
541 // Only apply macro to this object, if...
542 // ... the macro takes objects of exactly this type.
543 // ... the macro object type is a child of this object's type.
544 // Otherwise: Continue
546 // Finally, via procCmds[i], the automatic objects are casted to the correct type and analysed by each macro!
547 if (((TObject*)object1->GetUserData())->IsA() != mProcObjectType[i] &&
548 !((TObject*)object1->GetUserData())->InheritsFrom(mProcObjectType[i])) continue;
551 // Single object histo
552 if (mProcType[i] == kSingleObjectHisto){
553 histos[histoIndex++] = (TH1*)gROOT->ProcessLineSync(procCmds[i]);
554 // Correlated Objects histo
555 } else if (mProcType[i] == kCorrelObjectHisto) {
556 // Loop over all pairs behind the current one - together with the other loop this will be a loop
557 // over all pairs. We have a pair of objects, if and only if both objects of the pair are selected (Rnr-state)
558 // and are not equal.
559 // The correlated objects process macro will be applied to all pairs that will be additionally selected by
560 // all correlated objects selection macros.
561 TEveElement::List_i iter2 = iter;
563 for ( ; iter2 != this->EndChildren(); ++iter2)
565 if(!(object2 = dynamic_cast<TEveElement*>(*iter2))) continue;
567 // Skip objects that have not been selected
568 if (!object2->GetRnrState()) continue;
570 // Same check of the macro object type as before
571 if (((TObject*)object2->GetUserData())->IsA() != mProcObjectType[i] &&
572 !((TObject*)object2->GetUserData())->InheritsFrom(mProcObjectType[i])) continue;
574 // Cast to the "real" object behind
575 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object2));
576 gROOT->ProcessLineSync("TObject* automaticObject_2 = (TObject*)automaticEveElement->GetUserData();");
578 // Select object by default (so it will be processed, if there are no correlated objects selection macros!)
579 selectedByCorrSelMacro = kTRUE;
580 for (Int_t j = 0; j < selIterator->GetEntries(); j++){
581 if (mSelType[j] == kCorrelObjectSelect){
582 // Check, whether the macro can deal with both objects. If not, skip it.
583 // Note: Again, via selCmds[i], the automatic objects are casted to the correct type!
584 if (((TObject*)object1->GetUserData())->IsA() != mSelObjectType[j] &&
585 !((TObject*)object1->GetUserData())->InheritsFrom(mSelObjectType[j])) continue;
586 if (((TObject*)object2->GetUserData())->IsA() != mSelObjectType[j] &&
587 !((TObject*)object2->GetUserData())->InheritsFrom(mSelObjectType[j])) continue;
589 selectedByCorrSelMacro = (Bool_t)gROOT->ProcessLineSync(selCmds[j]);
590 if (!selectedByCorrSelMacro) break;
594 // If the pair has not been selected by the correlated objects selection macros, skip it!
595 if (!selectedByCorrSelMacro) continue;
597 histos[histoIndex] = (TH1*)gROOT->ProcessLineSync(procCmds[i]);
601 // Single object analyse
602 else if (mProcType[i] == kSingleObjectAnalyse) {
603 // Create data pointers in CINT, execute the macro and get the data
604 gROOT->ProcessLineSync("Double_t* results = 0;");
605 gROOT->ProcessLineSync("Int_t n = 0;");
606 gROOT->ProcessLineSync(procCmds[i]);
607 Double_t* results = (Double_t*)gROOT->ProcessLineSync("results;");
608 Int_t nResults = (Int_t)gROOT->ProcessLineSync("n;");
611 Error("Apply macros", Form("Error reading data from macro \"%s\"", procIterator->At(i)->GetTitle()));
614 for (Int_t resInd = 0; resInd < nResults; resInd++){
615 (*fDataTree) << Form("ObjectData%d", i) << Form("Macro%d=", i) << results[resInd] << (Char_t*)"\n";
621 // Correlated objects analyse
622 else if (mProcType[i] == kCorrelObjectAnalyse){
623 // Loop over all pairs behind the current one - together with the other loop this will be a loop
624 // over all pairs. We have a pair of objects, if and only if both objects of the pair are selected (Rnr-state)
625 // and are not equal.
626 // The correlated objects process macro will be applied to all pairs that will be additionally selected by
627 // all correlated objects selection macros.
628 TEveElement::List_i iter2 = iter;
631 for ( ; iter2 != this->EndChildren(); ++iter2) {
632 if(!(object2 = dynamic_cast<TEveElement*>(*iter2))) continue;
634 // Skip objects that have not been selected
635 if (!object2->GetRnrState()) continue;
637 // Same check of the macro object type as before
638 if (((TObject*)object2->GetUserData())->IsA() != mProcObjectType[i] &&
639 !((TObject*)object2->GetUserData())->InheritsFrom(mProcObjectType[i])) continue;
641 // Cast to the "real" object behind
642 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object2));
643 gROOT->ProcessLineSync("TObject* automaticObject_2 = (TObject*)automaticEveElement->GetUserData();");
645 // Select object by default (so it will be processed, if there are no correlated objects selection macros!)
646 selectedByCorrSelMacro = kTRUE;
647 for (Int_t j = 0; j < selIterator->GetEntries(); j++) {
648 if (mSelType[j] == kCorrelObjectSelect) {
649 // Check, whether the macro can deal with both objects. If not, skip it.
650 // Note: Again, via selCmds[i], the automatic objects are casted to the correct type!
651 if (((TObject*)object1->GetUserData())->IsA() != mSelObjectType[j] &&
652 !((TObject*)object1->GetUserData())->InheritsFrom(mSelObjectType[j])) continue;
653 if (((TObject*)object2->GetUserData())->IsA() != mSelObjectType[j] &&
654 !((TObject*)object2->GetUserData())->InheritsFrom(mSelObjectType[j])) continue;
656 selectedByCorrSelMacro = (Bool_t)gROOT->ProcessLineSync(selCmds[j]);
657 if (!selectedByCorrSelMacro) break;
661 // If the pair has not been selected by the correlated objects selection macros, skip it!
662 if (!selectedByCorrSelMacro) continue;
664 // Create data pointers in CINT, execute the macro and get the data
665 gROOT->ProcessLineSync("Double_t* results = 0;");
666 gROOT->ProcessLineSync("Int_t n = 0;");
667 gROOT->ProcessLineSync(procCmds[i]);
668 Double_t* results = (Double_t*)gROOT->ProcessLineSync("results;");
669 Int_t nResults = (Int_t)gROOT->ProcessLineSync("n;");
672 Error("Apply macros", Form("Error reading data from macro \"%s\"", procIterator->At(i)->GetTitle()));
675 for (Int_t resInd = 0; resInd < nResults; resInd++) {
676 (*fDataTree) << Form("ObjectData%d", i) << Form("Macro%d=", i) << results[resInd] << (Char_t*)"\n";
686 for (Int_t i = 0, histoIndex = 0; i < procIterator->GetEntries() && histoIndex < numHistoMacros; i++) {
687 if (mProcType[i] == kSingleObjectHisto || mProcType[i] == kCorrelObjectHisto) {
688 // Might be empty (e.g. no objects have been selected)!
689 if (histos[histoIndex]) {
690 (*fDataTree) << Form("ObjectData%d", i) << Form("Macro%d=", i) << histos[histoIndex] << (Char_t*)"\n";
696 if (fDataTree != 0) delete fDataTree;
699 if (procCmds != 0) delete [] procCmds;
701 if (mProcObjectType != 0) delete mProcObjectType;
703 if (mProcType != 0) delete mProcType;
706 if (selCmds != 0) delete [] selCmds;
708 if (mSelObjectType != 0) delete mSelObjectType;
710 if (mSelType != 0) delete mSelType;
713 if (histos != 0) delete [] histos;
717 // A.B. gROOT->Reset();
719 // If there is data, select the first data set
720 if (procIterator->GetEntries() > 0) SETBIT(fHistoDataSelected, 0);
722 // Now the data is stored in "/tmp/ListAnalyserMacroData_$USER.root"
723 // The editor will access this file to display the data
727 //______________________________________________________
728 void AliEveListAnalyser::ApplySTSelectionMacros(const TList* iterator)
730 // Uses the iterator (for the selected selection macros) to apply the selected macros to the data.
731 // The rnr-states of the objects are set according to the result of the macro calls (kTRUE, if all
732 // macros return kTRUE for this object, otherwise: kFALSE).
733 // "ST" stands for "single object". This means that only single object selection macros are applied.
734 // Correlated objects selection macros will be used inside the call of ApplyProcessMacros(...)!
736 TGeneralMacroData* macro = 0;
737 AliEveListAnalyserMacroType macroType = kUnknown;
738 TEveElement* object1 = 0;
739 Bool_t selectedByMacro = kFALSE;
742 // A.B. gROOT->Reset();
744 // Select all objecs at first. A object is then deselected, if at least one selection macro
745 // returns kFALSE for this object.
746 // Enable all objects (Note: EnableListElements(..) will call "ElementChanged", which will cause unforeseen behaviour!)
747 for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter) ((TEveElement*)(*iter))->SetRnrState(kTRUE);
750 for (Int_t i = 0; i < iterator->GetEntries(); i++){
751 macro = (TGeneralMacroData*)fMacroList->GetValue(iterator->At(i)->GetTitle());
754 Error("Apply selection macros",
755 Form("Macro list is corrupted: Macro \"%s\" is not registered!", iterator->At(i)->GetTitle()));
759 #ifdef AliEveListAnalyser_DEBUG
760 printf("AliEveListAnalyser: Applying selection macro: %s\n", macro->GetName());
763 // Determine macro type
764 macroType = macro->GetType();
766 // Single object select macro
767 if (macroType == kSingleObjectSelect){
768 // Walk through the list of objects
769 for (TEveElement::List_i iter = this->BeginChildren(); iter != this->EndChildren(); ++iter)
771 object1 = dynamic_cast<TEveElement*>(*iter);
773 if (!object1) continue;
775 // If the object has already been deselected, nothing is to do here
776 if (!object1->GetRnrState()) continue;
778 // Find the type of the object and relate it to the macro object type
779 // Only apply macro to this object, if...
780 // ... the macro takes objects of exactly this type.
781 // ... the macro object type is a child of this object's type.
782 // Otherwise: Continue
783 if (((TObject*)object1->GetUserData())->IsA() != macro->GetObjectType() &&
784 !((TObject*)object1->GetUserData())->InheritsFrom(macro->GetObjectType())) continue;
786 // Cast to the "real" object behind
787 gROOT->ProcessLineSync(Form("TEveElement *automaticEveElement = (TEveElement*)0x%xl;", object1));
788 gROOT->ProcessLineSync("TObject* automaticObject_1 = (TObject*)automaticEveElement->GetUserData();");
790 // GetCmd() will cast the automatic objects to the correct type for each macro!
791 selectedByMacro = (Bool_t)gROOT->ProcessLineSync(macro->GetCmd());
792 object1->SetRnrState(selectedByMacro && object1->GetRnrState());
795 // Correlated objects select macro
796 else if (macroType == kCorrelObjectSelect){
797 // Will be processed in ApplyProcessMacros(...)
800 Error("Apply selection macros",
801 Form("Macro list corrupted: Macro \"%s/%s.C\" is not registered as a selection macro!",
802 macro->GetPath(), macro->GetName()));
807 // A.B. gROOT->Reset();
810 //______________________________________________________
811 AliEveListAnalyser::AliEveListAnalyserMacroType AliEveListAnalyser::GetMacroType(const Char_t* name, const Char_t* objectType, Bool_t UseList) const
813 // Returns the type of the corresponding macro, that accepts pointers of the class "objectType" as a parametre.
814 // If "UseList" is kTRUE, the type will be looked up in the internal list (very fast). But if this list
815 // does not exist, you have to use kFALSE for this parameter. Then the type will be determined by the
816 // prototype! NOTE: It is assumed that the macro has been compiled! If not, the return value is not
817 // predictable, but normally will be kUnknown.
818 // Note: AddMacro(Fast) will update the internal list and RemoveMacros respectively.
820 AliEveListAnalyserMacroType type = kUnknown;
822 TString* typeStr = 0;
826 typeStr = new TString(objectType);
827 // Remove white-spaces
828 typeStr->ReplaceAll(" ", "");
832 typeStr = new TString("TObject");
835 TString* mangled1Str = new TString();
836 TString* mangled2Str = new TString();
837 TString* mangled3Str = new TString();
838 TString* mangled4Str = new TString();
839 TString* mangledArg1Str = new TString();
840 TString* mangledArg2Str = new TString();
842 // We want "const 'OBJECTTYPE'*"
843 mangled1Str->Append("const ").Append(*typeStr).Append("*");
845 // We want "const 'OBJECTTYPE'*, Double_t*&, Int_t&"
846 mangled2Str->Append("const ").Append(*typeStr).Append("*, Double_t*&, Int_t&");
848 // We want "const 'OBJECTTYPE'*, const 'OBJECTTYPE'*"
849 mangled3Str->Append("const ").Append(*typeStr).Append("*, const ").Append(*typeStr).Append("*");
851 // We want "const 'OBJECTTYPE'*, const 'OBJECTTYPE'*, Double_t*&, Int_t&"
852 mangled4Str->Append("const ").Append(*typeStr).Append("*, const ").Append(*typeStr).Append("*, Double_t*&, Int_t&");
854 // We want "oPconstsP'OBJECTTYPE'mUsP"
855 mangledArg1Str->Append("oPconstsP").Append(*typeStr).Append("mUsP");
857 // We want "cOconstsP'OBJECTTYPE'mUsP"
858 mangledArg2Str->Append("cOconstsP").Append(*typeStr).Append("mUsP");
860 // Re-do the check of the macro type
862 // Single object select macro or single object histo macro?
863 TFunction* f = gROOT->GetGlobalFunctionWithPrototype(name, mangled1Str->Data(), kTRUE);
867 // Some additional check (is the parameter EXACTLY of the desired type?)
868 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0)
870 // Single object select macro?
871 if (!strcmp(f->GetReturnTypeName(), "Bool_t"))
873 type = kSingleObjectSelect;
875 // single object histo macro?
876 else if (!strcmp(f->GetReturnTypeName(), "TH1*"))
878 type = kSingleObjectHisto;
882 // Single object analyse macro?
883 else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, mangled2Str->Data(), kTRUE))
886 if (!strcmp(f->GetReturnTypeName(), "void"))
888 // Some additional check (are the parameters EXACTLY of the desired type?)
889 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0 &&
890 strstr(f->GetMangledName(), "cODouble_tmUaNsP") != 0x0 &&
891 strstr(f->GetMangledName(), "cOInt_taNsP") != 0x0)
893 type = kSingleObjectAnalyse;
897 // Correlated objects select macro or correlated objects histo macro?
898 else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, mangled3Str->Data(), kTRUE))
901 // Some additional check (is the parameter EXACTLY of the desired type?)
902 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0 &&
903 strstr(f->GetMangledName(), mangledArg2Str->Data()) != 0x0)
905 // Correlated objects select macro?
906 if (!strcmp(f->GetReturnTypeName(), "Bool_t"))
908 type = kCorrelObjectSelect;
910 // Correlated objects histo macro?
911 else if (!strcmp(f->GetReturnTypeName(), "TH1*"))
913 type = kCorrelObjectHisto;
917 // Correlated objects analyse macro?
918 else if ((f = gROOT->GetGlobalFunctionWithPrototype(name, mangled4Str->Data(), kTRUE))
921 if (!strcmp(f->GetReturnTypeName(), "void"))
923 // Some additional check (is the parameter EXACTLY of the desired type?)
924 if (strstr(f->GetMangledName(), mangledArg1Str->Data()) != 0x0 &&
925 strstr(f->GetMangledName(), mangledArg2Str->Data()) != 0x0 &&
926 strstr(f->GetMangledName(), "cODouble_tmUaNsP") != 0x0 &&
927 strstr(f->GetMangledName(), "cOInt_taNsP") != 0x0)
929 type = kCorrelObjectAnalyse;
934 // Use list to look up the macro type
937 TGeneralMacroData* macro = 0;
938 macro = (TGeneralMacroData*)fMacroList->GetValue(name);
939 if (macro == 0) return kUnknown;
941 type = macro->GetType();
944 case kSingleObjectSelect:
945 case kSingleObjectAnalyse:
946 case kSingleObjectHisto:
947 case kCorrelObjectSelect:
948 case kCorrelObjectAnalyse:
949 case kCorrelObjectHisto:
958 if (mangled1Str != 0)
960 mangled1Str->Clear();
964 if (mangled2Str != 0)
966 mangled2Str->Clear();
970 if (mangled3Str != 0)
972 mangled3Str->Clear();
976 if (mangled4Str != 0)
978 mangled4Str->Clear();
982 if (mangledArg1Str != 0)
984 mangledArg1Str->Clear();
985 delete mangledArg1Str;
988 if (mangledArg2Str != 0)
990 mangledArg2Str->Clear();
991 delete mangledArg2Str;
1005 // TODO: DOCUMENTATION
1006 //______________________________________________________
1007 TClass* AliEveListAnalyser::GetMacroObjectType(const Char_t* name) const
1009 TFunction* f = gROOT->GetGlobalFunction(name, 0 , kTRUE);
1015 list = f->GetListOfMethodArgs();
1017 if (!list->IsEmpty())
1019 m = (TMethodArg*)list->At(0);
1021 if (m) return TClass::GetClass(m->GetTypeName());
1029 //______________________________________________________
1030 void AliEveListAnalyser::RemoveSelectedMacros(const TList* iterator)
1032 // Uses the iterator (for the selected macros) to remove the selected macros from
1033 // the corresponding list.
1037 for (Int_t i = 0; i < iterator->GetEntries(); i++)
1039 entry = (TPair*)fMacroList->FindObject(iterator->At(i)->GetTitle());
1043 Error("AliEveListAnalyser::RemoveSelectedMacros", Form("Macro \"%s\" not found in list!",
1044 iterator->At(i)->GetTitle()));
1051 Error("AliEveListAnalyser::RemoveSelectedMacros", Form("Key for macro \"%s\" not found in list!",
1052 iterator->At(i)->GetTitle()));
1056 // Key and value will be deleted, too, since fMacroList is the owner of them
1057 Bool_t rem = fMacroList->DeleteEntry(key);
1061 #ifdef AliEveListAnalyser_DEBUG
1062 printf("AliEveListAnalyser::RemoveSelectedMacros(): Removed macro: %s\n", iterator->At(i)->GetTitle());
1067 Error("AliEveListAnalyser::RemoveSelectedMacros", Form("Macro \"%s\" could not be removed from the list!",
1068 iterator->At(i)->GetTitle()));
1073 //______________________________________________________
1074 void AliEveListAnalyser::ResetObjectList()
1076 // Remove all objects from the list.
1081 //______________________________________________________
1082 Bool_t AliEveListAnalyser::StartAddingObjects()
1084 // Start adding objects for the analysis. Returns kTRUE on success.
1086 if (fConnected == kFALSE)
1088 fConnected = TQObject::Connect("TEvePointSet", "PointSelected(Int_t)", "AliEveListAnalyser", this, "AddObjectToList(Int_t)");
1089 //fConnected = TQObject::Connect("TEvePointSet", "Message(char*)", "AliEveListAnalyser", this, "AddObjectToList(char*)");
1090 if (fConnected) return kTRUE;
1092 Error("AliEveListAnalyser::StartAddingObjects", "Connection failed!");
1098 //______________________________________________________
1099 Bool_t AliEveListAnalyser::StopAddingObjects()
1101 // Stop adding objects for the analysis. Returns kTRUE on success.
1105 //if (TQObject::Disconnect("TEvePointSet", "AddObjectToList(Char_t*)")) fConnected = kFALSE;
1106 if (TQObject::Disconnect("TEvePointSet", "PointSelected(Int_t)", this, "AddObjectToList(Int_t)"))
1108 fConnected = kFALSE;
1113 Error("AliEveListAnalyser::StopAddingObjects", "Disconnection failed!");