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

File Contents

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