ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TAM/src/TAMSelector.cxx
Revision: 1.9
Committed: Wed Oct 8 11:33:24 2008 UTC (16 years, 7 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_006b, Mit_006a, Mit_006, Mit_005
Changes since 1.8: +8 -5 lines
Log Message:
Cleanup

File Contents

# User Rev Content
1 loizides 1.1 //
2 loizides 1.9 // $Id: TAMSelector.cxx,v 1.8 2008/10/07 16:02:34 bendavid Exp $
3 loizides 1.1 //
4    
5     #include "TAMSelector.h"
6    
7    
8     #ifndef ROOT_RVersion
9     #include <RVersion.h>
10     #endif
11     #ifndef ROOT_TFile
12     #include "TFile.h"
13     #endif
14     #ifndef ROOT_TTree
15     #include "TTree.h"
16     #endif
17     #ifndef ROOT_TError
18     #include "TError.h"
19     #endif
20     #ifndef ROOT_TROOT
21     #include "TROOT.h"
22     #endif
23     #ifndef ROOT_TList
24     #include "TList.h"
25     #endif
26     #ifndef ROOT_TClass
27     #include "TClass.h"
28     #endif
29     #ifndef ROOT_TProcessID
30     #include "TProcessID.h"
31     #endif
32     #if ROOT_VERSION_CODE >= ROOT_VERSION(5,0,0) && \
33     ROOT_VERSION_CODE < ROOT_VERSION(5,11,2)
34     #ifndef ROOT_TUrl
35     #include "TUrl.h"
36     #endif
37     #endif
38 loizides 1.6 #ifndef ROOT_TRefTable
39     #include <TRefTable.h>
40     #endif
41     #ifndef ROOT_TBranchRef
42     #include <TBranchRef.h>
43     #endif
44     #ifndef ROOT_TFriendElement
45     #include "TFriendElement.h"
46     #endif
47 loizides 1.1 #ifndef TAM_TAModule
48     #include "TAModule.h"
49     #endif
50     #ifndef TAM_TAMOutput
51     #include "TAMOutput.h"
52     #endif
53     #ifndef TAM_TAMVirtualLoader
54     #include "TAMVirtualLoader.h"
55     #endif
56     #ifndef TAM_TAMVirtualBranchLoader
57     #include "TAMVirtualBranchLoader.h"
58     #endif
59     #ifndef TAM_TAMTreeLoader
60     #include "TAMTreeLoader.h"
61     #endif
62    
63     //////////////////////////////////////////////////////////////////////////
64     // //
65     // TAMSelector //
66     // //
67     // A selector class for modular processing of a tree (or chain). //
68     // Processing is done by TAModule(s). //
69     // //
70     // Each TAModule contains pointers to the objects that will be read //
71     // in from the tree. For each such pointer, it will call //
72     // ReqBranch(name, pointer) to request that the branch be available for //
73     // processing by the module. The module's pointer would then be //
74     // automatically set to point to the object for the current event by //
75     // the TAMSelector, whenever the module calls LoadBranch. //
76     // //
77     // TAMSelector provides (and hides) all interaction with the tree //
78     // for the TAModule(s). //
79     // //
80     // Author : Corey Reed 07/20/2004 //
81     // Maarten Ballintijn 12/06/2005 //
82     // Constantin Loizides 12/06/2005 //
83     // //
84     //////////////////////////////////////////////////////////////////////////
85    
86     ClassImp(TAMSelector)
87    
88    
89     #if ROOT_VERSION_CODE < ROOT_VERSION(5,11,3)
90     #define R__ASSERT(e) \
91     if (!(e)) Fatal("", kAssertMsg, _QUOTE_(e), __LINE__, __FILE__)
92     #endif
93    
94 loizides 1.6 //______________________________________________________________________________
95     TAMSelector::TAMAutoLoadProxy::TAMAutoLoadProxy(TAMSelector *sel, Bool_t e) :
96     fSel(sel),
97     fOrig(0),
98     fFake(0),
99 loizides 1.7 fCurEntry(-1)
100 loizides 1.6 {
101     // Default constructor.
102    
103     fFake = new TRefTable(this, 10);
104     if (e) Enable();
105 loizides 1.7
106     memset(fBrRead, 0, 1024*sizeof(Bool_t));
107 loizides 1.6 }
108    
109     //______________________________________________________________________________
110     TAMSelector::TAMAutoLoadProxy::~TAMAutoLoadProxy()
111     {
112     // Destructor.
113    
114     Disable();
115     delete fFake;
116     fFake = 0;
117     }
118    
119     //______________________________________________________________________________
120     void TAMSelector::TAMAutoLoadProxy::Disable()
121     {
122     // Disable the proxy.
123    
124     if (fOrig)
125     TRefTable::SetRefTable(fOrig);
126     }
127    
128     //______________________________________________________________________________
129     void TAMSelector::TAMAutoLoadProxy::Enable()
130     {
131     // Enable the proxy.
132 bendavid 1.8
133     TBranchRef *bref = fSel->GetTree()->GetTree()->GetBranchRef();
134     if (bref) {
135     fOrig = bref->GetRefTable();
136     TRefTable::SetRefTable(fFake);
137     }
138 loizides 1.6 }
139    
140     //______________________________________________________________________________
141     Bool_t TAMSelector::TAMAutoLoadProxy::Notify()
142     {
143     // Notification received from TRefTable::Notify. Originally this would
144     // have been address to the TBranchRef owner of the TRefTable, but
145     // we intercept this call.
146    
147     TBranchRef *br = dynamic_cast<TBranchRef*>(fOrig->GetOwner());
148     if (!br)
149     return kFALSE;
150    
151 loizides 1.9 // get the desired uid/pid pair
152 loizides 1.6 UInt_t uid = fFake->GetUID();
153     TProcessID *pid = fFake->GetUIDContext();
154     fOrig->SetUID(uid,pid);
155    
156     if (0) { // this essentially is what ROOT would have done
157 loizides 1.7 Bool_t ret = br->Notify();
158     return ret;
159 loizides 1.6 }
160    
161     // read entry for this event
162 loizides 1.7 Long64_t readentry = br->GetReadEntry();
163     Long64_t tamentry = fSel->fCurEvt;
164     if (readentry!=tamentry) {
165     Fatal("Notify",
166     "Entries from BranchRef (%d) differs from TAM current entry (%d)",
167     readentry, tamentry);
168     }
169 loizides 1.6
170     // read branchref if needed
171 loizides 1.7 if (fCurEntry != readentry) {
172 loizides 1.6 Int_t bytes = br->GetEntry(readentry);
173     if (bytes<0) {
174     Fatal("Notify", "Could not get entry %d from %s branch",
175     readentry, br->GetName());
176     }
177     }
178    
179     // get branch from RefTable
180     TBranch *branch = dynamic_cast<TBranch*>(fOrig->GetParent(uid, pid));
181    
182     if (!branch) { //scan for possible friend Trees
183     TList *friends = fSel->GetTree()->GetListOfFriends();
184     if (friends) {
185 loizides 1.7
186     // reset branch read flags if new entry to be read
187     if (fCurEntry != readentry)
188     memset(fBrRead, 0, 1024*sizeof(Bool_t));
189    
190 loizides 1.6 TObjLink *lnk = friends->FirstLink();
191 loizides 1.7 Int_t nfriend = 0;
192 loizides 1.6 while (lnk) {
193     TFriendElement *elem =
194     static_cast<TFriendElement*>(lnk->GetObject());
195     TBranchRef *bref = elem->GetTree()->GetBranchRef();
196     if (bref) {
197 loizides 1.7 if (!fBrRead[nfriend]) {
198 loizides 1.6 bref->GetEntry(readentry);
199 loizides 1.7 fBrRead[nfriend] = kTRUE;
200     }
201 loizides 1.6 TBranch *branch = dynamic_cast<TBranch*>
202     (bref->GetRefTable()->GetParent(uid, pid));
203     if (branch)
204     break; // found branch
205     }
206     lnk = lnk->Next();
207 loizides 1.7 ++nfriend;
208     R__ASSERT(nfriend<1024);
209 loizides 1.6 }
210     }
211     }
212    
213 loizides 1.7 // cache last branch read attempt
214     fCurEntry = readentry;
215    
216 loizides 1.6 if (!branch) {
217     return kFALSE;
218     }
219    
220 loizides 1.9 // access the main branch
221 loizides 1.6 TBranch *readbranch = branch->GetMother();
222     if (!readbranch) {
223     return kFALSE;
224     }
225    
226 loizides 1.9 // check if TAMBranchInfo already exists
227     // and if not add it
228 loizides 1.6 const char *brname = readbranch->GetName();
229     TObject *brInfo = fSel->fBranchTable.FindObject(brname);
230 bendavid 1.8 TAMBranchInfo *branchInfo;
231 loizides 1.6 if (brInfo==0) {
232 bendavid 1.8 branchInfo = new TAMBranchInfo(brname);
233     fSel->fBranchTable.Add(branchInfo);
234 loizides 1.6 }
235 bendavid 1.8 else
236     branchInfo = dynamic_cast<TAMBranchInfo*>(brInfo);
237 loizides 1.6
238 loizides 1.9 // load the branch
239 bendavid 1.8 fSel->LoadBranch(branchInfo);
240 loizides 1.6
241     return kTRUE;
242     }
243    
244 loizides 1.1
245     //______________________________________________________________________________
246     TAMSelector::TAMSelector() :
247     fTree(0),
248 loizides 1.6 fProxy(new TAMAutoLoadProxy(this)),
249 loizides 1.5 fBranchTable(TCollection::kInitHashTableCapacity, 1),
250     fEventObjs(TCollection::kInitHashTableCapacity, 1),
251 loizides 1.1 fAModules(new TAModule("TAMTopModule",
252     "Top-most module containing all other modules.")),
253     fCurEvt(-1),
254     fOwnInput(0),
255     fAnalysisAborted(kFALSE),
256     fModAborted(kFALSE),
257     fEventAborted(kFALSE),
258     fActNotify(kFALSE),
259     fObjCounter(0),
260     fVerbosity(0),
261 loizides 1.6 fDoProxy(kFALSE),
262 loizides 1.1 fLoaders()
263     {
264     // Default constructor.
265    
266     fBranchTable.SetOwner(kTRUE);
267     fEventObjs.SetOwner(kTRUE);
268     gROOT->GetListOfBrowsables()->Add(fAModules,"Analysis Modules");
269     fLoaders.SetName("TAM_LOADERS");
270     }
271    
272    
273     //______________________________________________________________________________
274     TAMSelector::~TAMSelector()
275     {
276     // Destructor.
277    
278     gROOT->GetListOfBrowsables()->Remove(fAModules);
279     TList *submods = fAModules->GetListOfTasks();
280     if (submods!=0) submods->Clear("nodelete");
281     delete fAModules;
282     delete fOwnInput;
283     }
284    
285    
286     //______________________________________________________________________________
287     void TAMSelector::AbortAnalysis()
288     {
289     // Aborts the analysis by aborting all modules and never executing
290     // further module funtions.
291    
292     // no way known to propagate the stop of analysis in PROOF from
293     // one slave to the other slaves (and master).
294     Fatal("AbortAnalysis", "Analysis aborted!");
295    
296     fAModules->DeactivateAll();
297     fAnalysisAborted = kTRUE;
298     }
299    
300    
301     //______________________________________________________________________________
302     void TAMSelector::AbortEvent()
303     {
304     // Aborts the current event by setting all modules inactive.
305    
306     fAModules->DeactivateAll();
307     fEventAborted = kTRUE;
308     }
309    
310    
311     //______________________________________________________________________________
312     void TAMSelector::AbortModule(TAModule *mod)
313     {
314     // Abort the specified module by setting it (and its sub modules) inactive.
315    
316     mod->DeactivateAll();
317     fModAborted = kTRUE;
318     }
319    
320    
321     //______________________________________________________________________________
322     void TAMSelector::AddInput(TAModule *mod)
323     {
324     // Adds the module to the top-most module in the hierarchy.
325     // The "misnomer" on the function name is intentional:
326     // This allows users to call gProof->AddInput(myMod) when
327     // using proof and mySelector->AddInput(myMod) when not
328     // using proof.
329    
330     fAModules->Add(mod);
331     }
332    
333     //______________________________________________________________________________
334     Bool_t TAMSelector::AddObjThisEvt(TObject *obj)
335     {
336     // Add this object to the list of objects stored for this event.
337     // See further description below.
338    
339 paus 1.4 if (obj)
340 loizides 1.1 return AddObjThisEvt(obj,obj->GetName());
341     else {
342 paus 1.4 Error("AddObjThisEvt","Can not add null object to event.");
343 loizides 1.1 return kFALSE;
344     }
345     }
346    
347    
348     //______________________________________________________________________________
349     Bool_t TAMSelector::AddObjThisEvt(TObject *obj, const char *name)
350     {
351     // Add this object to the list of objects stored for this event.
352     // NOTE:
353     // - The object must have a unique name.
354     // - The object must be on the heap.
355     // - The object will be owned by the selector and deleted at the
356     // end of the processing of the current event.
357     //
358     // Returns true iff the object meets the requirements and is added to
359     // the list successfully.
360    
361     if (obj!=0) {
362     if (FindObjThisEvt(name)==0) {
363     if (obj->IsOnHeap()) {
364     fEventObjs.Add(new TAMEvtObj(obj,name));
365 loizides 1.5 return kTRUE;
366 loizides 1.1 } else {
367     Error("AddObjThisEvt",
368     "Object [%s] does not appear to be on heap. "
369     "Can not add object.",
370     name);
371     }
372     } else {
373     Error("AddObjThisEvt",
374     "Object with name [%s] already added to this event.",
375     name);
376     }
377     } else {
378     Error("AddObjThisEvt",
379     "Can not add null object to event.");
380     }
381     return kFALSE;
382     }
383    
384    
385     //______________________________________________________________________________
386     void TAMSelector::AddNewOutputLists()
387     {
388     // Make a new hierarchy of TAMOutput objects and add it to
389     // the output of this selector. Note that this should only be called
390     // ONCE (by SlaveBegin())!!
391    
392     fAModules->NewOutputList(GetOutputList());
393     }
394    
395    
396     //______________________________________________________________________________
397     void TAMSelector::Begin(TTree */*tree*/)
398     {
399     // The Begin() function is called at the start of the query.
400     // When running with PROOF Begin() is only called on the client.
401     // The tree argument is deprecated (on PROOF 0 is passed).
402     // It checks the tree of modules to be sure each module is set
403     // up to use this selector.
404     // Adds the tree of modules to the input list of this selector.
405     // Builds the hierarchy of TAMOutput objects in the output list.
406     // Then calls Begin() on the TAModule(s). At the end, it adds the
407     // list of loaders to the input list.
408    
409     if (fAnalysisAborted) {
410     return;
411     } else {
412     if (fInput==0) {
413     fOwnInput = new TList;
414     SetInputList(fOwnInput);
415     }
416     CopyModsFromInput();
417     fAModules->SetSelector(this);
418     if (fAModules->CheckSelectors(this)) {
419     if (fModAborted) {
420     fAModules->ResetAllActiveFlags();
421     fModAborted = kFALSE;
422     }
423     fAModules->ExecuteTask(&TAModule::kExecBegin);
424     if (fEventObjs.IsEmpty()==kFALSE) fEventObjs.Delete();
425     } else {
426     Error("Begin",
427     "One or more module is not set up to use this selector.");
428     R__ASSERT(0);
429     }
430     }
431    
432     fInput->AddLast(&fLoaders);
433     }
434    
435    
436     //______________________________________________________________________________
437     void TAMSelector::ClearAllLoaders()
438     {
439     // Go through the list of requested branches and clear the
440     // loaders that were used.
441    
442     TIter nextBr(fBranchTable.MakeIterator());
443 paus 1.4 while (TAMBranchInfo *br = dynamic_cast<TAMBranchInfo*>(nextBr())) {
444 loizides 1.1
445     if (!br->fIsLoaded) continue;
446     // don't bother with branches that weren't loaded
447    
448     TAMVirtualBranchLoader *l = br->GetLoader();
449     if (l) {
450     l->Clear();
451     } else {
452     Error("ClearAllLoaders",
453     "Could not get loader for [%s]. Unable to "
454     "try to clear loader for this branch.",
455     br->GetName());
456     }
457     }
458     }
459    
460    
461     //______________________________________________________________________________
462     void TAMSelector::CopyModsFromInput()
463     {
464     // Find all TAModules in the input list and copy them to fAModules.
465    
466     R__ASSERT(fInput!=0);
467    
468     if (fInput->IsEmpty()) return;
469    
470     TObject *obj=fInput->First(), *tobj=0;
471     while (obj!=0) {
472     tobj = fInput->After(obj);
473     if (obj->InheritsFrom(TAModule::Class())) {
474     AddInput(dynamic_cast<TAModule*>(obj));
475     }
476     obj = tobj;
477     }
478     }
479    
480    
481     //______________________________________________________________________________
482     Bool_t TAMSelector::FindLoader(TAMBranchInfo *brInfo)
483     {
484     // Find the loader responsible for the given branch info. Return kFALSE
485     // if none could be found in the list of loaders.
486    
487     const char *bname = brInfo->GetName();
488     TIter next(&fLoaders);
489    
490     while( TAMVirtualLoader *l = dynamic_cast<TAMVirtualLoader*>(next()) ) {
491     TAMVirtualBranchLoader *bl = l->CreateBranchLoader(fTree, brInfo);
492     if (bl != 0) {
493     Info("FindLoader","branch '%s' use loader %s",
494     bname, bl->IsA()->GetName());
495     brInfo->SetLoader(bl);
496     return kTRUE;
497     }
498     }
499    
500     Error("FindLoader","No loader found for branch '%s'", bname);
501     return kFALSE;
502     }
503    
504    
505     //______________________________________________________________________________
506     TAMOutput *TAMSelector::FindModOutput(const TAModule *mod)
507     {
508     // Find the TAMOutput object corresponding to the given module.
509    
510     TAMOutput *obj=0, *tobj=0;
511     TIter nextObj(GetOutputList());
512     while ( (obj = dynamic_cast<TAMOutput*>(nextObj())) ) {
513     tobj = obj->FindModOutput(mod); // search mod and sub mods
514     if (tobj!=0) return tobj;
515     }
516     return 0;
517     }
518    
519    
520     //______________________________________________________________________________
521     TObject *TAMSelector::FindObjThisEvt(const Char_t *name) const
522     {
523     // Looks for the object with the specified name that was added to
524     // this event. If not found, returns zero.
525    
526     TAMEvtObj *eo = dynamic_cast<TAMEvtObj*>(fEventObjs.FindObject(name));
527     if (eo!=0) {
528     return eo->fObj;
529     }
530     return 0;
531     }
532    
533    
534     //______________________________________________________________________________
535     TObject *TAMSelector::FindPublicObj(const Char_t *name) const
536     {
537     // Looks for the public object with the specified name. If not found,
538     // returns zero.
539     // Note: TAModules are not public objects and will not be found by this
540     // function.
541    
542     if (fInput!=0) {
543     TIter nextObj(fInput);
544     TObject *obj=0;
545     TString nm(name);
546     while ( (obj = nextObj()) ) {
547     if ( (nm.CompareTo(obj->GetName())==0) &&
548     (obj->InheritsFrom(TAModule::Class())==kFALSE) ) {
549     return obj;
550     }
551     }
552     } else {
553     Error("FindPublicObj",
554     "Input list is null. No public objects exist.");
555     }
556     return 0;
557     }
558    
559    
560     //______________________________________________________________________________
561 loizides 1.5 const TFile *TAMSelector::GetCurrentFile() const
562     {
563     // Returns the current file that the tree is in.
564    
565     return (fTree) ? (const_cast<const TFile *>(fTree->GetCurrentFile())) : 0;
566     }
567    
568    
569     //______________________________________________________________________________
570     TFile *TAMSelector::GetCurrentFile()
571 loizides 1.1 {
572     // Returns the current file that the tree is in.
573    
574     return (fTree) ? (fTree->GetCurrentFile()) : 0;
575     }
576    
577    
578     //______________________________________________________________________________
579     const TAMOutput *TAMSelector::GetModOutput() const
580     {
581     // Return the top-most module output object.
582    
583     return fAModules->GetModOutput();
584     }
585    
586    
587     //______________________________________________________________________________
588     TAMOutput *TAMSelector::GetModOutput()
589     {
590     // Return the top-most module output object.
591    
592     return fAModules->GetModOutput();
593     }
594    
595    
596     //______________________________________________________________________________
597     void TAMSelector::Init(TTree *tree) {
598     // Set the tree for this selector. The Init() function is called
599     // when the selector needs to initialize a new tree (or chain).
600     // It will be called many times when running with PROOF. The
601     // list of requested branches must been constructed
602     // already.
603    
604     if (tree==0) {
605     Error("Init", "Specified tree is null.");
606     AbortAnalysis();
607     }
608    
609     fTree = tree;
610    
611     TIter nextBranch(fBranchTable.MakeIterator());
612     while ( TAMBranchInfo *brInfo =
613     dynamic_cast<TAMBranchInfo*>(nextBranch()) ) {
614     brInfo->Init();
615     }
616     }
617    
618     //______________________________________________________________________________
619 bendavid 1.8 void TAMSelector::LoadBranch(const Char_t *bname)
620 loizides 1.1 {
621 bendavid 1.8 // Loads branch by name, getting the pointer to the corresponding
622 loizides 1.9 // TAMBranchInfo and then use it in the call of the protected LoadBranch
623     // function.
624 bendavid 1.8
625 loizides 1.1 if(fCurEvt==-1) {
626     Error("LoadBranch",
627 loizides 1.2 "Can not load branch with name [%s] at this point (fCurEvt==-1).",
628 loizides 1.1 bname);
629     AbortAnalysis();
630     }
631    
632     TAMBranchInfo *brInfo =
633     dynamic_cast<TAMBranchInfo*>( fBranchTable.FindObject(bname) );
634    
635     if (brInfo==0) {
636     Error("LoadBranch",
637     "Could not find branch with name [%s] in requested branch list.",
638     bname);
639     AbortAnalysis();
640 bendavid 1.8 }
641    
642     LoadBranch(brInfo);
643     }
644    
645     //______________________________________________________________________________
646     void TAMSelector::LoadBranch(TAMBranchInfo* brInfo)
647     {
648     // Loads the selected branch and get the current entry (number fCurEvt)
649     // if the branch has not yet been loaded for this event. It then makes
650     // sure each module's pointer to the branch object point to the address
651     // of this branch.
652 loizides 1.1
653 loizides 1.6 if (brInfo->IsLoaded())
654 loizides 1.1 return;
655    
656     // find loader for branch info if needed and notify
657     if (brInfo->GetLoader() == 0) {
658    
659     if ( !FindLoader(brInfo) ) {
660     Error("LoadBranch","Branch [%s] FindLoader() failed in file [%s].",
661     brInfo->GetName(),
662     (GetCurrentFile()!=0) ? (GetCurrentFile()->GetName()) : "null");
663    
664     AbortAnalysis();
665     }
666    
667     if ( !brInfo->Notify(fTree) )
668     Error("LoadBranch","Branch [%s] Notify() failed in file [%s].",
669     brInfo->GetName(),
670     (GetCurrentFile()!=0) ? (GetCurrentFile()->GetName()) : "null");
671    
672     // have to reset our object counter to take care of objects
673     // created in the notify of the loader
674 loizides 1.6 //fObjCounter=TProcessID::GetObjectCount();
675     }
676 loizides 1.1
677     // load the entry
678     Int_t ret = brInfo->GetEntry(fCurEvt);
679     if(ret<0) {
680     Error("LoadBranch",
681     "Error in file [%s] when accessing branch with name [%s] in "
682     "requested branch list.",
683     (GetCurrentFile()!=0) ? (GetCurrentFile()->GetName())
684 bendavid 1.8 : "null", brInfo->GetName());
685 loizides 1.1
686     AbortAnalysis();
687     }
688 loizides 1.6
689     // make sure autoload proxy is enabled
690 loizides 1.7 if (fDoProxy)
691     fProxy->Enable();
692 loizides 1.1 }
693    
694    
695     //______________________________________________________________________________
696     Bool_t TAMSelector::Notify()
697     {
698     // Sets the branch pointers, checks that the types of the module's
699     // pointers correspond to what is in the tree and calls SetBranchAddress
700     // if necessary. Finally, it also notifies the modules.
701     // The Notify() function is called when a new file is opened. This
702     // can be either for a new TTree in a TChain or when a new TTree
703     // is started when using PROOF.
704    
705 loizides 1.6 // we are just in Notify(), therefore we ignore this call
706 loizides 1.1 if(fActNotify) return kTRUE;
707     fActNotify = kTRUE; //"lock" to protect for recursive calls
708    
709     #if ROOT_VERSION_CODE >= ROOT_VERSION(5,0,0) && \
710     ROOT_VERSION_CODE < ROOT_VERSION(5,11,2)
711    
712 loizides 1.6 // workaround for older ROOT: give file name to
713 loizides 1.1 // TFile that accidentally stripped the protocol
714 loizides 1.6 const TUrl *url = (GetCurrentFile()!=0)
715     ? GetCurrentFile()->GetEndpointUrl() : 0;
716 loizides 1.1
717 loizides 1.6 if (url==0) {
718     Warning("Notify","Could not get URL for file [%s].",
719     (GetCurrentFile()!=0) ? (GetCurrentFile()->GetName())
720     : "null");
721     } else {
722 loizides 1.1
723 loizides 1.6 if(GetCurrentFile()!=0)
724     GetCurrentFile()->SetName((const_cast<TUrl*>(url)->GetUrl()));
725     // the const_cast is for some version of
726     // 5.08.00 that didn't have GetUrl const.
727     }
728 loizides 1.1 #endif
729    
730     if (fVerbosity>0) {
731     Info("Notify","Opening file [%s] at current event [%d].",
732     (GetCurrentFile()!=0) ? (GetCurrentFile()->GetName()) : "null",
733     fCurEvt);
734     }
735    
736 loizides 1.6 // status (return value) of notify
737 loizides 1.1 Bool_t notifyStat = kTRUE;
738    
739     // no event yet processed eg, no loaders assigned,
740     // so that the notify is being delayed to LoadBranch()
741     if(fCurEvt>=0) {
742    
743     TIter nextBranch(fBranchTable.MakeIterator());
744    
745     while ( TAMBranchInfo *brInfo =
746     dynamic_cast<TAMBranchInfo*>(nextBranch()) ) {
747    
748     // notify the branchinfo and its corresponding loader
749     notifyStat &= brInfo->Notify(fTree);
750    
751     // have to reset our object counter to take care of objects
752     // created in the notify of the loader
753 loizides 1.6 //fObjCounter=TProcessID::GetObjectCount();;
754 loizides 1.1
755     if (notifyStat==kFALSE) {
756     Error("Notify","Branch [%s] Notify() failed in file [%s].",
757     brInfo->GetName(),
758     (GetCurrentFile()!=0) ? (GetCurrentFile()->GetName())
759     : "null");
760    
761     AbortAnalysis();
762     }
763     }
764     }
765    
766     if (notifyStat && (fAnalysisAborted==kFALSE)) {
767     notifyStat &= fAModules->NotifyAll();
768     }
769    
770     //release "lock" on notify
771     fActNotify = kFALSE;
772    
773     return notifyStat;
774     }
775    
776    
777     //______________________________________________________________________________
778     Bool_t TAMSelector::Process(Long64_t entry)
779     {
780     // Zero's all TAModule(s)'s branch addresses and calls Process()
781     // on the TAModule(s). Then clear any requested clones arrays and
782     // clear the list of event-stored objects.
783     //
784     // The Process() function is called for each entry in the tree (or possibly
785     // keyed object in the case of PROOF) to be processed.
786    
787     if (fAnalysisAborted) {
788     // There is currently no reliable way to exit cleanly back to the
789     // interpreter, so simply return immediately.
790     return kFALSE;
791 loizides 1.2 }
792 loizides 1.1
793 loizides 1.6 // prepare for event
794 loizides 1.2 fCurEvt = entry;
795     ZeroAllBranches();
796     if (fModAborted) {
797     fAModules->ResetAllActiveFlags();
798     fModAborted = kFALSE;
799     } else if (fEventAborted) {
800     fAModules->ResetAllActiveFlags();
801     fEventAborted = kFALSE;
802     }
803 loizides 1.1
804 loizides 1.6 // store object counter for run boundaries
805 loizides 1.2 if (BeginRun()) {
806     fObjCounterRun=TProcessID::GetObjectCount();;
807     fAModules->ExecuteTask(&TAModule::kExecBeginRun);
808     }
809 loizides 1.1
810 loizides 1.6 // store object counter and process event
811 loizides 1.2 fObjCounter=TProcessID::GetObjectCount();;
812     if (fVerbosity>9) {
813     if ((entry % 100)==0) {
814     fprintf(stderr,"Processing entry %lld... \r",
815     entry);
816     }
817     }
818 loizides 1.6
819 loizides 1.2 fAModules->ExecuteTask(&TAModule::kExecProcess);
820    
821 loizides 1.6 // update object counter on run boundaries
822 loizides 1.2 if (EndRun()) {
823     fAModules->ExecuteTask(&TAModule::kExecEndRun);
824     fObjCounter=fObjCounterRun;
825     }
826    
827 loizides 1.6 // cleanup
828 loizides 1.2 ClearAllLoaders();
829     if (fEventObjs.IsEmpty()==kFALSE)
830     fEventObjs.Delete();
831 loizides 1.1
832 loizides 1.2 // restore object counter
833     TProcessID::SetObjectCount(fObjCounter);
834 loizides 1.1
835     return kTRUE;
836     }
837    
838    
839     //______________________________________________________________________________
840     Bool_t TAMSelector::PublishObj(TObject *obj)
841     {
842     // Adds an object to a list of objects which is outside the module
843     // hierarchy. This can be used to pass objects (for example, calibrations)
844     // between modules. Objects in this list are available before Begin
845     // until the end of SlaveTerminate. They are not guaranteed to be available
846     // during or after Terminate.
847     // Checks (by name) if the object is already in the list. If it is, returns
848     // kFALSE and does not publish the object.
849     // NOTE: These objects are NOT owned by the list! Whatever creates these
850     // objects must take care to (1) remove the object from the list using
851     // RetractObj() and (2) delete the object.
852     // Also NOTE: This will not publish TAModule objects.
853    
854     if (obj!=0) {
855     TObject *ob = FindPublicObj(obj->GetName());
856     if (ob==0) {
857     if (obj->InheritsFrom(TAModule::Class())) {
858     // Disallow publishing of TAModules since it breaks the assumption
859     // that all TAModules in the input list were added by AddInput and
860     // are intended to be executed. (Such modules would be found by
861     // TakeModsFromInput and CopyModsFromInput.)
862     Warning("PublishObj",
863     "Can not publish a TAModule. Object named [%s] not "
864     "published.",
865     obj->GetName());
866     } else {
867     if (fInput!=0) {
868     fInput->Add(obj);
869     return kTRUE;
870     } else {
871     Error("PublishObj",
872     "Input list is null. Could not publish object named [%s].",
873     obj->GetName());
874     }
875     }
876     } else {
877     Warning("PublishObj",
878     "Public object named [%s] already exists.",
879     obj->GetName());
880     }
881     } else {
882     Error("PublishObj",
883     "Can not publish null object.");
884     }
885     return kFALSE;
886     }
887    
888    
889     //______________________________________________________________________________
890     TObject *TAMSelector::RemoveObjThisEvt(const Char_t *name)
891     {
892     // Finds the object with the specified name and removes it from
893     // the list of objects added to this event.
894     // Returns the object that was removed.
895    
896     TAMEvtObj *eo = dynamic_cast<TAMEvtObj*>(fEventObjs.FindObject(name));
897     if (eo!=0) {
898     fEventObjs.Remove(eo);
899     TObject *obj = eo->fObj;
900     eo->fObj = 0; // so it won't delete the object
901     delete eo;
902     return obj;
903     }
904     return 0;
905     }
906    
907    
908     //______________________________________________________________________________
909     TObject *TAMSelector::RetractObj(const Char_t *name)
910     {
911     // Finds the public object with the specified name and removes it from
912     // the list of public objects.
913     // Returns the object that was retracted.
914     // Note: TAmodules are not public objects and will not be removed by this
915     // function.
916    
917     TObject *obj = FindPublicObj(name);
918     if (obj!=0) {
919     return fInput->Remove(obj);
920     }
921     return 0;
922     }
923    
924    
925     //______________________________________________________________________________
926     void TAMSelector::SlaveBegin(TTree *tree)
927     {
928     // Inits the tree and calls SlaveBegin() on the TAModule(s)
929     //
930     // The SlaveBegin() function is called after the Begin() function.
931     // When running with PROOF SlaveBegin() is called on each slave server.
932     // The tree argument is deprecated (on PROOF 0 is passed).
933    
934     if (fAnalysisAborted) {
935     return;
936     } else {
937     // call SlaveBegin first so the modules can call ReqBranch and
938     // build the fBranchTable
939     if (fModAborted) {
940     fAModules->ResetAllActiveFlags();
941     fModAborted = kFALSE;
942     }
943     // remove the modules from the input list and put them in the top-most
944     // module of this selector. make sure they use this selector
945     TakeLoadersFromInput();
946     TakeModsFromInput();
947     fAModules->SetSelector(this);
948     if (fAModules->CheckSelectors(this)) {
949     // build the module output hierarchy
950     AddNewOutputLists();
951     // set up the module's output members
952     if (fAModules->fOutput != 0) {
953     fAModules->fOutput->SetAllOutputMembers(kFALSE);
954     }
955    
956     fAModules->ExecuteTask(&TAModule::kExecSlaveBegin);
957     } else {
958     Error("SlaveBegin",
959     "One or more module is not set up to use this selector.");
960     R__ASSERT(0);
961     }
962    
963     // init requires fBranchTable to be built already
964     // in Proof, this is called automatically when a new tree is loaded
965 loizides 1.6 if (tree)
966     Init(tree);
967     if (fEventObjs.IsEmpty()==kFALSE)
968     fEventObjs.Delete();
969 loizides 1.1 }
970     }
971    
972    
973     //______________________________________________________________________________
974     void TAMSelector::SlaveTerminate()
975     {
976     // Calls SlaveTerminate() on the TAModule(s)
977     // The SlaveTerminate() function is called after all entries or objects
978     // have been processed. When running with PROOF SlaveTerminate() is called
979     // on each slave server.
980    
981     if (fAnalysisAborted) {
982     return;
983     } else {
984     if (fModAborted) {
985     fAModules->ResetAllActiveFlags();
986     fModAborted = kFALSE;
987     }
988     fAModules->ExecuteTask(&TAModule::kExecSlaveTerminate);
989     if (fEventObjs.IsEmpty()==kFALSE) fEventObjs.Delete();
990     }
991     }
992    
993    
994     //______________________________________________________________________________
995     void TAMSelector::TakeModsFromInput()
996     {
997     // Find all TAModules in the input list and move them to fAModules.
998    
999     R__ASSERT(fInput!=0);
1000    
1001     if (fInput->IsEmpty()==kFALSE) {
1002     TObject *obj=fInput->First(), *tobj=0;
1003     while (obj!=0) {
1004     tobj = fInput->After(obj);
1005     if (obj->InheritsFrom(TAModule::Class())) {
1006     AddInput(dynamic_cast<TAModule*>(obj));
1007     fInput->Remove(obj);
1008     }
1009     obj = tobj;
1010     }
1011     }
1012     }
1013    
1014    
1015     //______________________________________________________________________________
1016     void TAMSelector::TakeLoadersFromInput()
1017     {
1018     // Find all TAModules in the input list and copy them to fAModules.
1019    
1020     R__ASSERT(fInput!=0);
1021    
1022     TList *loaders = dynamic_cast<TList*>(fInput->FindObject("TAM_LOADERS"));
1023     if (loaders != 0) {
1024     TIter next(loaders);
1025     while ( TAMVirtualLoader *l =
1026     dynamic_cast<TAMVirtualLoader*>(next()) ) {
1027     if (loaders != &fLoaders) fLoaders.AddLast(l);
1028     }
1029     }
1030    
1031     fLoaders.AddLast(new TAMTreeLoader());
1032     }
1033    
1034    
1035     //______________________________________________________________________________
1036     void TAMSelector::Terminate()
1037     {
1038     // Calls Terminate() on the TAModule(s).
1039     // When running under Proof, will copy the TAMOutput object
1040     // from the fOutput list to the top most TAModule object. Assumes
1041     // that the only TAMOutput object in fOutput is the one belonging
1042     // to the top most module.
1043     // The Terminate() function is the last function to be called during
1044     // a query. It always runs on the client, it can be used to present
1045     // the results graphically or save the results to file.
1046    
1047     if (fAnalysisAborted) {
1048     return;
1049     }
1050    
1051     if (fModAborted) {
1052     fAModules->ResetAllActiveFlags();
1053     fModAborted = kFALSE;
1054     }
1055    
1056     if (fAModules->GetModOutput()==0) {
1057     // When running under Proof, copy the module output hierarchy to
1058     // this selector's top most module.
1059     TIter nextObj(GetOutputList());
1060     TAMOutput *tout=0;
1061     TObject *obj=0;
1062     Bool_t alreadySet=kFALSE;
1063     while ( (obj = nextObj()) ) {
1064     if (obj->InheritsFrom(TAMOutput::Class())) {
1065     tout = dynamic_cast<TAMOutput*>(obj);
1066     if (alreadySet) {
1067     Warning("Terminate",
1068     "Found more than one TAMOutput object in the "
1069     "output list. Assuming the first one is from the "
1070     "top-most module. The output list contains:");
1071     GetOutputList()->ls();
1072     } else {
1073     // copy module output hierarchy
1074     fAModules->SetAllModOutput(tout);
1075     // try to set module's pointers to their output objects
1076     tout->SetAllOutputMembers(kTRUE);
1077     alreadySet=kTRUE;
1078     }
1079     }
1080     }
1081     if (alreadySet==kFALSE) {
1082     Error("Terminate",
1083     "Did not find TAMOutput object in the output list! "
1084     "The output list contains:");
1085     GetOutputList()->ls();
1086     }
1087     }
1088    
1089     // move output objs from current objects to stored objects
1090     // incase the module wants to write output to a file
1091     if (fAModules->GetModOutput()!=0) {
1092     fAModules->GetModOutput()->StoreAllOutputObjs();
1093     } else {
1094     Error("Terminate",
1095     "Could not store output objects from this process run.");
1096     }
1097    
1098     fAModules->ExecuteTask(&TAModule::kExecTerminate);
1099     if (fEventObjs.IsEmpty()==kFALSE) fEventObjs.Delete();
1100    
1101     // store output objects again, in case a module added any output
1102     // objects during terminate
1103     if (fAModules->GetModOutput()!=0) {
1104     fAModules->GetModOutput()->StoreAllOutputObjs();
1105     } else {
1106     Error("Terminate",
1107     "Could not store output objects after terminate.");
1108     }
1109     }
1110    
1111    
1112     //______________________________________________________________________________
1113     void TAMSelector::ZeroAllBranches()
1114     {
1115     // Loops through all branches in fBranchTable and sets all user addresses
1116     // for each branch to zero.
1117    
1118     TIter nextBranch(fBranchTable.MakeIterator());
1119 paus 1.4 while (TAMBranchInfo *brInfo =
1120     dynamic_cast<TAMBranchInfo*>(nextBranch())) {
1121 loizides 1.1 brInfo->ZeroUsrAddrs();
1122     }
1123     }