ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TAM/src/TAModule.cxx
Revision: 1.7
Committed: Thu Jul 16 21:02:05 2009 UTC (15 years, 9 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_032, Mit_031, Mit_025c_branch2, Mit_025c_branch1, Mit_030, Mit_029c, Mit_029b, Mit_030_pre1, Mit_029a, Mit_029, Mit_029_pre1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e, Mit_014d, Mit_014c, Mit_014b, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1, Mit_013d, Mit_013c, Mit_013b, Mit_013a, Mit_013, Mit_013pre1, Mit_012i, Mit_012h, Mit_012g, Mit_012f, Mit_012e, Mit_012d, Mit_012c, Mit_012b, Mit_012a, Mit_012, Mit_011a, Mit_011, Mit_010a, Mit_010, HEAD
Branch point for: Mit_025c_branch
Changes since 1.6: +5 -5 lines
Error occurred while calculating annotation data.
Log Message:
use same include paths as rest of code. Remember to always remove this when committing to the svn version.

File Contents

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