ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TAM/src/TAMSelector.cxx
Revision: 1.7
Committed: Tue Oct 7 04:13:54 2008 UTC (16 years, 7 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.6: +35 -30 lines
Log Message:
Introduced flags to indicate read TBranchRef branches.

File Contents

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