ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TAM/src/TAMSelector.cxx
Revision: 1.5
Committed: Sat Sep 27 06:02:54 2008 UTC (16 years, 7 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_004
Changes since 1.4: +14 -4 lines
Log Message:
Added const GetCurrentFile, plus use rehash in THashTables.

File Contents

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