ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TAM/src/TAMSelector.cxx
Revision: 1.13
Committed: Wed Feb 18 16:37:48 2009 UTC (16 years, 2 months ago) by bendavid
Content type: text/plain
Branch: MAIN
Changes since 1.12: +4 -4 lines
Log Message:
Bugfix to autloading

File Contents

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