ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TAM/src/TAModule.cxx
Revision: 1.4
Committed: Thu Dec 4 13:50:56 2008 UTC (16 years, 5 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_009c, Mit_009b, Mit_009a, Mit_009, Mit_008, Mit_008pre2, Mit_008pre1, Mit_006b, Mit_006a
Changes since 1.3: +38 -5 lines
Log Message:
Have TAModule::ls

File Contents

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