ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TAM/src/TAModule.cxx
Revision: 1.2
Committed: Mon Jun 23 10:53:00 2008 UTC (16 years, 10 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_006, Mit_005, Mit_004, MITHEP_2_0_x
Changes since 1.1: +9 -3 lines
Log Message:
Add BeginRun, EndRun

File Contents

# User Rev Content
1 loizides 1.1 //
2 loizides 1.2 // $Id: TAModule.cxx,v 1.1 2008/05/27 19:13:21 loizides Exp $
3 loizides 1.1 //
4    
5     #include "TAModule.h"
6    
7    
8     #ifndef ROOT_RVersion
9     #include <RVersion.h>
10     #endif
11     #ifndef ROOT_TError
12     #include "TError.h"
13     #endif
14     #ifndef ROOT_TIterator
15     #include "TIterator.h"
16     #endif
17     #ifndef ROOT_TAMOutput
18     #include "TAMOutput.h"
19     #endif
20    
21    
22     //////////////////////////////////////////////////////////////////////////
23     // //
24     // //
25     // TAModule //
26     // //
27     // Abstract base class for processing trees. This class allows the trees//
28     // to be processed in a modular fashion. All iteraction with the tree //
29     // itself is taken care of by TAMSelector. //
30     // //
31     // //
32     // Usage: //
33     // - Make a class that (publically) derives from TAModule //
34     // - The class should have member variables (pointers) to the //
35     // objects that will be read in and used from the tree. //
36     // For example, if a module will need the event info branch //
37     // from the tree, it could have a member variable such as: //
38     // TEventInfo* fEvtInfo; //
39     // Note: Such pointers should be initialized to null. //
40     // DO NOT assign them to 'new' objects as this will //
41     // result in a memory leak. The TAMSelector will //
42     // automatically make these pointers point to valid //
43     // objects after the corresponding tree branch has been //
44     // read in for the current entry. //
45     // - Override any of the following functions as needed: //
46     // - Begin() //
47     // - In Proof, this function is called by the client. //
48     // For most applications, this function will not be needed. //
49     // - SlaveBegin() //
50     // - In Proof, this function is called by each slave server. //
51     // Histograms should be created by a module here. //
52     // All branches that the module may need during Process //
53     // should be requested here using ReqBranch. //
54     // For the above example, one would call: //
55     // ReqBranch("eventInfo",fEvtInfo); //
56     // - Process() //
57     // - The TAMSelector (fSelector) will call this function //
58     // on the TAModule hierarchy for every entry in the tree. //
59     // Here one should only load branches as needed to first //
60     // perform the event selection. If and only if an event //
61     // passes the selection, one should then load the branches //
62     // needed for analysis. This is why requested branches are //
63     // NOT automatically loaded. //
64     // Continuing the example, to load the event info branch: //
65     // LoadBranch("eventInfo"); //
66     // cout << "Event Num=" << fEvtInfo->fEventNum << endl; //
67     // The module can then perform analysis and/or fill //
68     // histograms. //
69     // - SlaveTerminate() //
70     // - In Proof, this function is called by each slave server //
71     // after the Process loop. //
72     // - Terminate() //
73     // - In Proof, this function is called by the client at the //
74     // end of the analysis. //
75     // Here, a module can save results to a file or present them//
76     // graphically. //
77     // //
78     // A module may be active or inactive (controlled by TTask::SetActive). //
79     // When a module is not active, its sub modules are not executed. //
80     // //
81     // Author : Corey Reed 07/20/2004 //
82     // Author : Constantin Loizides 07/12/2006 //
83     // //
84     //////////////////////////////////////////////////////////////////////////
85    
86     ClassImp(TAModule)
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     const Char_t TAModule::kExecBegin = 10;
95     const Char_t TAModule::kExecSlaveBegin = 20;
96     const Char_t TAModule::kExecProcess = 30;
97 loizides 1.2 const Char_t TAModule::kExecBeginRun = 40;
98     const Char_t TAModule::kExecEndRun = 50;
99     const Char_t TAModule::kExecSlaveTerminate = 60;
100     const Char_t TAModule::kExecTerminate = 70;
101 loizides 1.1
102    
103     //______________________________________________________________________________
104     TAModule::TAModule() :
105     fSelector(0),
106     fOutput(0),
107     fDefActv(IsActive()), // in principal, no need to initialze fDefActv
108     fVerbose(0),
109     fStopped(kFALSE)
110     {
111     // Default constructor.
112     }
113    
114    
115     //______________________________________________________________________________
116     TAModule::TAModule(const Char_t* name, const Char_t* title) :
117     TTask(name, title),
118     fSelector(0),
119     fOutput(0),
120     fDefActv(IsActive()), // in principal, no need to initialze fDefActv
121     fVerbose(0),
122     fStopped(kFALSE)
123     {
124     // Normal constructor:
125     // Use SetSelector on the top-most module to recursively set
126     // the selector for all mods.
127     }
128    
129    
130     //______________________________________________________________________________
131     TAModule::~TAModule()
132     {
133     // Destructor.
134     }
135    
136    
137     //______________________________________________________________________________
138     void TAModule::AbortAnalysis()
139     {
140     // Abort the analysis
141    
142     SetDefActive(kFALSE);
143     fSelector->AbortAnalysis();
144     }
145    
146    
147     //______________________________________________________________________________
148     void TAModule::AbortEvent()
149     {
150     // Abort this event
151    
152     fSelector->AbortEvent();
153     }
154    
155    
156     //______________________________________________________________________________
157     void TAModule::AbortModule()
158     {
159     // Abort the module and all sub-modules until the next call in TAMSelector.
160    
161     fSelector->AbortModule(this);
162     }
163    
164    
165     //______________________________________________________________________________
166     Bool_t TAModule::AddObjThisEvt(TObject* obj)
167     {
168     // Add this object to the list of objects stored for this event.
169     // See further description below.
170    
171     if(obj)
172     return AddObjThisEvt(obj,obj->GetName());
173     else {
174     Error("AddObjThisEvt",
175     "Can not add null object to event.");
176     return kFALSE;
177     }
178     }
179    
180    
181     //______________________________________________________________________________
182     Bool_t TAModule::AddObjThisEvt(TObject* obj, const char *name)
183     {
184     // Add this object to the list of objects stored for this event.
185     // NOTE:
186     // - The object must have a unique name.
187     // - The object must be on the heap.
188     // - The object will be owned by the selector and deleted at the
189     // end of the processing of the current event.
190     //
191     // Returns true iff the object meets the requirements and is added to
192     // the list successfully.
193    
194     if (fSelector!=0) {
195     return fSelector->AddObjThisEvt(obj,name);
196     } else {
197     Error("AddObjThisEvt",
198     "No selector exists, so there is no list of objects for "
199     "this event. Object named [%s] not added to this event.",
200     name);
201     }
202     return 0;
203     }
204    
205    
206     //______________________________________________________________________________
207     void TAModule::Browse(TBrowser* b)
208     {
209     // Browse this module's (and its sub modules) output if there is any
210     // otherwise just browse the tree of modules.
211    
212     if (fOutput!=0) fOutput->Browse(b);
213     else TTask::Browse(b);
214     }
215    
216    
217     //______________________________________________________________________________
218     Bool_t TAModule::CheckSelectors(const TAMSelector* sel, const Bool_t warn/*=kTRUE*/) const
219     {
220     // Checks the tree of TAModules to be sure that each module has the
221     // specified selector.
222    
223     Bool_t check = (fSelector->IsEqual(sel));
224     if ( warn && (!check) ) {
225     Warning("CheckSelectors",
226     "Selector of module [%s] is different from specified selector.",
227     GetName());
228     }
229     TAModule* obj=0;
230     TIter nextobj(fTasks);
231     while ( (obj = dynamic_cast<TAModule*>(nextobj())) ) {
232     check &= obj->CheckSelectors(sel);
233     }
234     return check;
235     }
236    
237    
238     //______________________________________________________________________________
239     void TAModule::DeactivateAll()
240     {
241     // Recursively sets the active flag of this and all sub modules
242     // to false. Store their former activity flag in fDefActv so that
243     // they can be reset to that state by ResetAllActiveFlags().
244    
245     TTask::SetActive(kFALSE);
246    
247     TAModule* task=0;
248     TIter nextobj(fTasks);
249     while ( (task = dynamic_cast<TAModule*>(nextobj())) ) {
250     task->DeactivateAll();
251     }
252     }
253    
254    
255     //______________________________________________________________________________
256     void TAModule::Exec(Option_t* option)
257     {
258     // Executes the module corresponding to the given option.
259     // To be called only by TAMSelector.
260     // Checks the address of the private static variables
261     // to ensure that the TTask execute functions can not be
262     // called by derived classes.
263     // This function must not be overridden!
264    
265     R__ASSERT(option);
266    
267     if (option == &kExecBegin) {
268     Begin();
269     } else if (option == &kExecSlaveBegin) {
270     SlaveBegin();
271     } else if (option == &kExecProcess) {
272     Process();
273 loizides 1.2 } else if (option == &kExecBeginRun) {
274     BeginRun();
275     } else if (option == &kExecEndRun) {
276     EndRun();
277 loizides 1.1 } else if (option == &kExecSlaveTerminate) {
278     SlaveTerminate();
279     } else if (option == &kExecTerminate) {
280     Terminate();
281     } else {
282     SendError(kAbortAnalysis,
283     "Exec",
284     "Invalid option [%s] at %p. Function must only be called "
285     "by TAMSelector.",
286     option, static_cast<const void*>(option));
287     };
288     }
289    
290    
291     //______________________________________________________________________________
292     TFile* TAModule::GetCurrentFile() const
293     {
294     // Returns the current file that the tree is in.
295    
296     return (fSelector) ? (fSelector->GetCurrentFile()) : 0;
297     }
298    
299    
300     //______________________________________________________________________________
301     TObject* TAModule::FindObjThisEvt(const Char_t* name) const
302     {
303     // Looks for the object with the specified name that was added to
304     // this event. If not found, returns 0.
305    
306     if (fSelector!=0) {
307     return fSelector->FindObjThisEvt(name);
308     } else {
309     Error("FindObjThisEvt",
310     "No selector exists, so there is no list of objects for "
311     "this event. Could not find object named [%s].",
312     name);
313     }
314     return 0;
315     }
316    
317    
318     //______________________________________________________________________________
319     TObject* TAModule::FindPublicObj(const Char_t* name) const {
320     // Looks for the public object with the specified name. If not found,
321     // returns 0.
322     // Note: TAModules are not public objects and will not be found by this
323     // function.
324    
325     if (fSelector!=0) {
326     return fSelector->FindPublicObj(name);
327     } else {
328     Error("FindPublicObj",
329     "No selector exists, so there is no list of public objects. "
330     "Could not find object named [%s].",
331     name);
332     }
333     return 0;
334     }
335    
336    
337     //______________________________________________________________________________
338     void TAModule::LoadBranch(const Char_t* bname)
339     {
340     // Loads the current entry for the specified branch.
341     // This function should be called by specific TAModules (classes that
342     // inherit from this one) to get the current entry from the tree for
343     // the branch of the specified name.
344     // The branch must have already been requested (see
345     // ReqBranch).
346     // The actual entry is gotten from the tree by TAMSelector
347     // to ensure that the same branch is not loaded more than once
348     // for a given event.
349    
350     if (fSelector!=0) {
351     fSelector->LoadBranch(bname);
352     } else {
353     SendError(kAbortAnalysis,
354     "LoadBranch",
355     "fSelector is null in module [%s]",
356     GetName());
357     }
358     }
359    
360    
361     //______________________________________________________________________________
362     void TAModule::NewOutputList(TList* list)
363     {
364     // Make a hierarchy of TAMOutput objects corresponding to this
365     // module and all its sub modules. This must only be called once! Analysis
366     // will abort if this module already has an associated TAMOutput object.
367     // The input list is assumed to be the fOutput member of the TAMSelector
368     // and must never be null.
369    
370     R__ASSERT(list);
371     if (fOutput!=0) {
372     if (GetVerbosity()>0) {
373     SendError(kWarning,
374     "NewOutputList",
375     "New output list requested in module [%s] but one has "
376     "already been made. This should only happen if the module "
377     "has been added to more than one TAMSelector. "
378     "Set verbosity to 0 to remove this message.", GetName());
379     }
380    
381     if (fOutput->GetMod()!=this) {
382     if ((GetVerbosity()>0) && (fOutput->GetMod()!=0)) {
383     Warning("NewOutputList",
384     "Output of [%s] was associated with module at %p. "
385     "Resetting to this (%p).",
386     GetName(), (void*)fOutput->GetMod(), (void*)this);
387     }
388     fOutput->SetMod(this);
389     }
390    
391     if (list->FindObject(fOutput)==0) {
392     list->Add(fOutput);
393     }
394     } else {
395     fOutput = new TAMOutput(this);
396     fOutput->SetOwner();
397     list->Add(fOutput);
398     }
399    
400     TAModule* task=0;
401     TIter nextobj(fTasks);
402     while ( (task = dynamic_cast<TAModule*>(nextobj())) ) {
403     task->NewOutputList(fOutput);
404     }
405     }
406    
407    
408     //______________________________________________________________________________
409     Bool_t TAModule::NotifyAll() {
410     // recursively call Notify
411    
412     Bool_t ret = Notify();
413     TAModule* task=0;
414     TIter nextobj(fTasks);
415     while ( (task = dynamic_cast<TAModule*>(nextobj())) ) {
416     ret &= task->NotifyAll();
417     }
418     return ret;
419     }
420    
421    
422     //______________________________________________________________________________
423     void TAModule::Print(Option_t *option/*=""*/) const
424     {
425     // Print the modules inside this module and its submodules.
426    
427     TTask::ls(option);
428     }
429    
430    
431     //______________________________________________________________________________
432     Bool_t TAModule::PublishObj(TObject* obj)
433     {
434     // Adds an object to a list of objects which is outside the module
435     // hierarchy. This can be used to pass objects (for example, calibrations)
436     // between modules. Objects in this list are available before Begin
437     // until the end of SlaveTerminate. They are not guaranteed to be available
438     // during or after Terminate.
439     // Checks (by name) if the object is already in the list. If it is, returns
440     // kFALSE and does not publish the object.
441     // NOTE: These objects are NOT owned by the list! Whatever creates these
442     // objects must take care to (1) remove the object from the list using
443     // RetractObj() and (2) delete the object.
444     // Also NOTE: will not publish TAModule objects.
445    
446     if (fSelector!=0) {
447     return fSelector->PublishObj(obj);
448     } else {
449     Error("PublishObj",
450     "No selector exists, so there is no list of public objects. "
451     "Object named [%s] not published.",
452     (obj!=0) ? obj->GetName() : "NULL");
453     }
454     return kFALSE;
455     }
456    
457    
458     //______________________________________________________________________________
459     TObject* TAModule::RemoveObjThisEvt(const Char_t* name)
460     {
461     // Finds the object with the specified name and removes it from
462     // the list of objects added to this event.
463     // Returns the object that was removed.
464    
465     if (fSelector!=0) {
466     return fSelector->RemoveObjThisEvt(name);
467     } else {
468     Error("RemoveObjThisEvt",
469     "No selector exists, so there is no list of objects for "
470     "this event. Object named [%s] not removed from this event.",
471     name);
472     }
473     return 0;
474     }
475    
476    
477     //______________________________________________________________________________
478     void TAModule::RemoveOutput(TObject* obj)
479     {
480     // Remove the object from the list of output objects of this module.
481    
482     R__ASSERT(fOutput);
483     fOutput->RemoveOutput(obj);
484     }
485    
486    
487     //______________________________________________________________________________
488     void TAModule::ResetAllActiveFlags()
489     {
490     // Recursively reset the activity flag of this and all sub modules
491     // to their fDefActv values.
492    
493     if(fStopped) // this module is permanently aborted
494     return;
495    
496     SetActive(fDefActv);
497    
498     TAModule* task=0;
499     TIter nextobj(fTasks);
500     while ( (task = dynamic_cast<TAModule*>(nextobj())) ) {
501     task->ResetAllActiveFlags();
502     }
503     }
504    
505    
506     //______________________________________________________________________________
507     TObject* TAModule::RetractObj(const Char_t* name) {
508     // Finds the public object with the specified name and removes it from
509     // the list of public objects. Returns the object that was retracted.
510     // Note: TAModules are not public objects and will not be removed by
511     // this function.
512    
513     if (fSelector!=0) {
514     return fSelector->RetractObj(name);
515     } else {
516     Error("RetractObj",
517     "No selector exists, so there is no list of public objects. "
518     "Object named [%s] not retracted.",
519     name);
520     }
521     return 0;
522     }
523    
524    
525     //______________________________________________________________________________
526     void TAModule::SendError(const EModResult errLevel,
527     const Char_t* location,
528     const Char_t* formattedMsg, ...)
529     {
530     // Sends an error using the TError facility.
531     // If errLevel is kAbortAnalysis or greater, the error is sent
532     // as type 'kBreak'.
533     // If errLevel is kWarning, the error is sent as type 'kWarning'.
534     // Otherwise it is sent as type 'kError'.
535    
536     va_list ap;
537     va_start(ap,va_(formattedMsg));
538     if (errLevel>=kAbortAnalysis) {
539     DoError(kBreak,location, va_(formattedMsg), ap);
540     AbortAnalysis();
541     } else if (errLevel>=kStopModule) {
542     DoError(kError,location, va_(formattedMsg), ap);
543     StopModule();
544     } else if (errLevel>=kAbortEvent) {
545     DoError(kError,location, va_(formattedMsg), ap);
546     AbortEvent();
547     } else if (errLevel>=kAbortModule) {
548     DoError(kError,location, va_(formattedMsg), ap);
549     AbortModule();
550     } else if (errLevel==kWarning) {
551     DoError(kWarning,location, va_(formattedMsg), ap);
552     } else {
553     Error("SendError",
554     "Unhandled error level [%d] specified when trying to send the "
555     "following error:",static_cast<Int_t>(errLevel));
556     DoError(kError,location, va_(formattedMsg), ap);
557     }
558     va_end(ap);
559     }
560    
561    
562     //______________________________________________________________________________
563     void TAModule::SetAllModOutput(TAMOutput* o)
564     {
565     // Recursively set the output objects for this module and its submodules
566     // see SetModOutput().
567    
568     SetModOutput(o);
569    
570     if ( fTasks->IndexOf(fTasks->Last()) == o->IndexOf(o->Last()) ) {
571     TAModule* task=0;
572     TAMOutput* taskOutput=0;
573     TIter nextobj(fTasks);
574     TIter nextout(o);
575     while ( (task = dynamic_cast<TAModule*>(nextobj())) &&
576     (taskOutput = dynamic_cast<TAMOutput*>(nextout())) ) {
577     task->SetAllModOutput(taskOutput);
578     }
579     } else {
580     SendError(kAbortAnalysis,
581     "SetAllModOutput",
582     "Can not set output for submodules of [%s]. Module contains %d "
583     "submodules, different from the Output which contains %d "
584     "suboutputs.",
585     GetName(),
586     fTasks->IndexOf(fTasks->Last())+1,
587     o->IndexOf(o->Last())+1);
588     }
589     }
590    
591    
592     //______________________________________________________________________________
593     void TAModule::SetModOutput(TAMOutput* o)
594     {
595     // Check that the output object has the same name as this module
596     // If so, set 'o' to be this module's output and set o's module to this.
597    
598     if (o!=0) {
599     TString on(o->GetName());
600     if (on.CompareTo(GetName())==0) {
601     fOutput = o;
602     o->SetMod(this);
603     } else {
604     SendError(kAbortAnalysis,
605     "SetModOutput",
606     "Output named [%s] different from module named [%s]."
607     "Can not set mod output to module.",
608     on.Data(), GetName());
609     }
610     } else {
611     SendError(kAbortAnalysis,
612     "SetModOutput",
613     "Can not set mod output to null object.");
614     }
615     }
616    
617    
618     //______________________________________________________________________________
619     void TAModule::SetSelector(TAMSelector* sel)
620     {
621     // Recursively set the selector for this module and all contained
622     // modules to 'sel'.
623    
624     fSelector = sel;
625    
626     TAModule* obj=0;
627     TIter nextobj(fTasks);
628     while ( (obj = dynamic_cast<TAModule*>(nextobj())) ) {
629     obj->SetSelector(sel);
630     }
631     }
632    
633    
634     //______________________________________________________________________________
635     void TAModule::SkipEvent()
636     {
637     // Aborts the processing of the current event by this task (and prevents
638     // its subtasks from processing the event) without sending an error
639     // message.
640     //
641     // It is designed for use by event selection type modules.
642     //
643     // If an error message is desired, use SendError with an error level of
644     // kSkipModule to both print the message and skip the event. There is no
645     // need to call both SendError(kSkipModule,...) and SkipEvent().
646    
647     AbortModule();
648     }
649    
650    
651     //______________________________________________________________________________
652     void TAModule::StopModule()
653     {
654     // Stop the module for the rest of the analysis.
655    
656     fStopped = kTRUE;
657     fSelector->AbortModule(this);
658     }
659    
660     //______________________________________________________________________________
661     const char *TAModule::Version()
662     {
663     // Return a TAM version string.
664    
665     #ifndef TAM_RELEASE
666     #define TAM_RELEASE "Unknown"
667     #endif
668    
669     return TAM_RELEASE;
670     }