BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//____________________________________________________________________
//                                                                 
// BrModuleContainer                                               
// -----------------                                               
// Class to manage modules to be executed in sequence in           
// BRAHMS analysis                                                 
//                                                                 
// Description:                                                    
// -----------------                                               
// This class is a container class for BRAHMS Analysis Modules.    
// It is meant to be used to simplify like-kinds of analyis.       
//                                                                 
// This will set up a pipeline of modules that will be asked to go 
// through each of the stages in the analysis.                     
//                                                                 
//                     +-----------+                               
//                     | Container |                               
//                     +-----------+                               
//                        ||...|                                   
//           +------------+|   +-----------+                       
//           |             |               |                       
//      +----------+  +----------+     +----------+                
//      | Module 1 |  | Module 2 | ... | Module N |                
//      +----------+  +----------+     +----------+                
//                                                                 
//       -------------- Execution --------------->                  
//                                                                 
// Please note, that Modules do not see each other in this          
// pipeline. They must communicate via a BrEvent, or some common   
// Manager.                                                        
//                                                                 
// Usage:                                                          
// ------                                                          
// The Object is created, modules previously created are added to  
// it and then is used in the event by event loop to call the      
// Event method of each module that was added.  Usage of this      
// class essentially eliminates a loop.                            
//                                                                 
// This also applies to the Book() and Init() methods implemented  
// for all Modules                                                 
//                                                                 
// See also the BrModule class description for more information,   
// including a flow diagram of the execution of this and the       
// BrModule classes.                                               
//                                                                 
// Example:                                                        
// --------                                                        
//                                                                 
//    BrModuleContainer* digitize  =                                
//      new BrModuleContainer("digitize","Digitize Modules");      
//                                                                  
//    //add t1Digitize, ... previously created                     
//    digitize->AddModule(t1Digitize);                             
//    digitize->AddModule(t2Digitize);                             
//    digitize->AddModule(t3Digitize);                             
//    digitize->AddModule(t4Digitize);                             
//    digitize->AddModule(t5Digitize);                             
//                                                                 
//    // Event Loop                                                
//      // Get GBRAHMS data and create BrEvent *geantevent         
//      BrEvent *digTable   = new BrEvent("Digitized Table",0,0);  
//      digitize->Event(geantevent,digTable);                      
//      //                                                         
//      // Analyze digTable as needed                              
//      //                                                         
//      delete digTable;                                           
//    // End Event Loop                                            
//                                                                 
// See also BrModule class description for a ASCII art flow        
// diagram for modules, module pipelines, and BRAT applications    
//                                                                 
// Packages:
// ---------
// Specialised containers, doing a specific set of task, such as doing
// a full tracking in a TPC or DC, can be defined in terms of the
// appropiate modules.  Simply define a class Br<name>Package,
// inheriting from BrModuleContainer, and in the constructor of that
// class, add the needed modules.  Should one desire to put all
// histograms of the contained module in one directory, the Book
// method can also be overwritten in the package.  No other methods,
// except trivial Getters and Print should be defined in the package.
// Example of packages are BrGlbPackage, BrTpcHitPackage, and
// BrTpcTrackPackage.  All packages should reside in the packages
// directory in the source tree of BRAT. 
//
// Further information: 
// --------------------
// More information on the design of BRAT, in particular the module
// system can be found in "The Hitchhikers Guide to BRAT" avaliable in
// the doc subdiretory of the BRAT source tree.  A pointer to a HTML
// version of that document should be in place at the BRAHMS computing
// webpage. 
// Here
//

//____________________________________________________________________
//
// $Id: BrModuleContainer.cxx,v 1.7 2002/06/13 17:18:17 videbaek Exp $
// $Author: videbaek $
// $Date: 2002/06/13 17:18:17 $ 
//
//  Update History:
//    FV March 28 ,1999
//     Add ListEventStatistics() to asp's
//    April 19, 1999
//     Init() called Book() method corrected to Init() 
//
#ifndef ROOT_TObjArray
#include "TObjArray.h"
#endif 
#ifndef ROOT_TClass
#include "TClass.h"
#endif
#ifndef BRAT_BrModuleContainer
#include "BrModuleContainer.h"
#endif 
#ifndef BRAT_BrModule
#include "BrModule.h"
#endif
#ifndef BRAT_BrEventNode
#include "BrEventNode.h"
#endif
#ifndef WIN32
#ifndef __IOSTREAM__
#include <iostream>
#endif
#ifndef __IOMANIP__
#include <iomanip>
#endif
#else 
#include <iostream.h>
#include <iomanip.h>
#endif 

//____________________________________________________________________
ClassImp(BrModuleContainer);

//____________________________________________________________________
 BrModuleContainer::BrModuleContainer()
  : BrModule()
{
  // Default constructor. Normal use is named constructor. This method
  // implemented for used by ROOT system, but should not every really
  // be used, since modules (and therefore also containers) are not
  // persistent. 
  //
  SetState(kSetup);
  fStatusLimit = kStop;
  // fModuleList  = new TObjArray();
  fModuleList  = new TOrdCollection();
}

//____________________________________________________________________
 BrModuleContainer::BrModuleContainer(const Char_t *name, const Char_t *title)
 : BrModule(name, title ? title : name)
{
  //Constructor
  //Set up Module list
  SetState(kSetup);
  fStatusLimit = kStop;
  fModuleList  = new TOrdCollection();
  //  fModuleList  = new TObjArray();
}


//____________________________________________________________________
 BrModuleContainer::~BrModuleContainer()
{
  // Destructor
  // Delete module list if it was created
  if(fModuleList)
    delete fModuleList;
}

#if 0
//____________________________________________________________________
 Int_t BrModuleContainer::AddModule(BrModule *module)
{
  // Routine to add a module to the list of modules to be executed
  if(!module){
    cerr << "Illegal Module (Null)" << endl;
    return 0;
  }

  fModuleList->Add(module);
  Info(10, "AddModule", "%s - %s at %d, total of %d modules", 
       module->GetName(), module->GetTitle(), idx,
       fModuleList->GetSize());
}
#endif 

//____________________________________________________________________
 Int_t BrModuleContainer::AddModuleAt(BrModule *module, Int_t position) 
{
  // Add module at position. Exisiting module at position and
  // subsequent modules will be pushed back. 
  if (!module) {
    Error("AddModuleAt", "Invalid null module");
    return 0;
  }
  if (position < 0) {
    Warning("AddModuleAt", "Invalid position %d, will use 0",
	    position); 
    position = 0;
  }
  
  fModuleList->AddAt(module, position);
  Info(10, "AddModuleAt", "%s - %s at %d, total of %d modules", 
       module->GetName(), module->GetTitle(), position,
       fModuleList->GetSize());
  
  return fModuleList->GetSize();
}

//____________________________________________________________________
 Int_t BrModuleContainer::AddModuleBefore(BrModule* before, 
					 BrModule* module) 
{
  // Add a BrModule module before BrModule before.  Module before and
  // subsequent modules are pushed back. Before maybe null, in which
  // case this is the same as AddFirst. 
  if (!module) {
    Error("AddModuleBefore", "Invalid null module");
    return 0;
  }
  fModuleList->AddBefore(before, module); 
  Int_t idx = fModuleList->IndexOf(module);
  if (idx == -1)
    return 0;
  Info(10, "AddModuleBefore", "%s - %s at %d, total of %d modules", 
       module->GetName(), module->GetTitle(), idx,
       fModuleList->GetSize());
  return fModuleList->GetSize();
}

//____________________________________________________________________
 Int_t BrModuleContainer::AddModuleAfter(BrModule* after, 
					 BrModule* module) 
{
  // Add a BrModule module after BrModule after. Modules after module
  // will be pushed back. After maybe null, in which case this is the
  // same as AddLast.  
  if (!module) {
    Error("AddModuleAfter", "Invalid null module");
    return 0;
  }
  fModuleList->AddAfter(after, module); 
  Int_t idx = fModuleList->IndexOf(module);
  if (idx == -1)
    return 0;
  Info(10, "AddModuleAfter", "%s - %s at %d, total of %d modules", 
       module->GetName(), module->GetTitle(), idx,
       fModuleList->GetSize());
  return fModuleList->GetSize();
}

//____________________________________________________________________
 BrModule* BrModuleContainer::RemoveModule(const Char_t* name) 
{
  // Remove the module named name from the container, and return a
  // pointer to that module.  Please note, that the module is _not_
  // deleted.  If no match on name was found, return 0. 
  // 
  // This method is usefull in the case you have a package, but you
  // don't really want to do all the things is does.  For example, to
  // analyse global data output from a BRAG simulation, we'd like to
  // use BrGlbPackage, since that's what's used for real data passes.
  // However, since there's currently (Sat Aug 18 12:09:16 2001) no
  // digisation output from BrZdcDigModule, we don't want the
  // BrZdcRdoModule in the package.  We can therefor simply remove
  // that module from the package, by doing: 
  //  
  //   BrGlbPackage* glbPackage = new BrGlbPackage("glb", "glb"); 
  //   mainModule->AddModule(glbPackage);
  //   if (!useZdc) {
  //     TString name = BrDetectorList::GetDetectorName(kBrZDC);
  //     glbPackage->RemoveModule(name.Data());
  //   }
  BrModule* module = FindModule(name); 
  if (!module) 
    return 0; 
  return (BrModule*)fModuleList->Remove(module);
}

//____________________________________________________________________
 void BrModuleContainer::Begin()
{
  //  The method to be used run by run to reinitialize the modules in
  //  this container.
  //  The loop over the modules will immediately halt, should one of
  //  the modules status become kStop, the status of this
  //  container is set to kFailure, and the method returns. 
  SetState(kBegin);
  BrModule *object = 0;

  TIter next(fModuleList);
  while((object = (BrModule*)next())) {
    Info(5, "Begin", "executing %s::Begin for %s",
	 object->ClassName(), object->GetName());
    object->Begin();
    if (object->GetStatus() >= fStatusLimit) {
      if (DebugLevel() > 3)
        Warning("Begin", "status of '%s' %d > %d, giving up",
                object->GetName(), object->GetStatus(), fStatusLimit);
      SetStatus(object->GetStatus());
      return;
    }
  }
}

//____________________________________________________________________
 void BrModuleContainer::Book()
{
  //  The method can be used to call Booking for all modules in a
  //  container.   
  //  The loop over the modules will immediately halt, should one of
  //  the modules status become bigger than or equal to fStatusLimit,
  //  the status of this container is set to that status, and the
  //  method returns.  
  BrModule *object;

  TIter next(fModuleList);
  while((object = (BrModule*) next())) {
    Info(25, "Book", "executing %s::Book for %s",
	 object->ClassName(), object->GetName());
    object->Book();
    if (object->GetStatus() >= fStatusLimit) {
      if (DebugLevel() > 4)
        Warning("Book", "status of '%s' %d > %d, giving up",
                object->GetName(), object->GetStatus(), fStatusLimit);
      SetStatus(object->GetStatus());
      return;
    }
  }
}

//____________________________________________________________________
 void BrModuleContainer::End()
{
  //  The method to be used run by run to finish the modules in
  //  this container.
  //  The loop over the modules will immediately halt, should one of
  //  the modules status become bigger than or equal to fStatusLimit,
  //  the status of this container is set to that status, and the
  //  method returns.  
  SetState(kEnd);
  BrModule *object = 0;

  TIter next(fModuleList);
  while((object = (BrModule*)next())) {
    Info(5, "End", "executing %s::End for %s",
	 object->ClassName(), object->GetName());
    object->End();
    if (object->GetStatus() >= fStatusLimit) {
      if (DebugLevel() > 3)
        Warning("End", "status of '%s' %d > %d, giving up",
                object->GetName(), object->GetStatus(), fStatusLimit);
      SetStatus(object->GetStatus());
      return;
    }
  }
}

//____________________________________________________________________
 void BrModuleContainer::Event()
{
  //  The method to be used event by event in case there are no
  //  arguments in the Event method of the modules in the list. 
  //  The loop over the modules will immediately halt, should one of
  //  the modules status become bigger than or equal to fStatusLimit,
  //  the status of this container is set to that status, and the
  //  method returns.  
  SetState(kEvent);
  BrModule *object = 0;

  TIter next(fModuleList);
  while((object = (BrModule*)next())) {
    Info(25, "Event", "executing %s::Event for %s",
	 object->ClassName(), object->GetName());
    object->Event();
    if (object->GetStatus() >= fStatusLimit) {
      if (DebugLevel() > 4)
        Warning("Event", "status of '%s' %d > %d, giving up",
                object->GetName(), object->GetStatus(), fStatusLimit);
      SetStatus(object->GetStatus());
      return;
    }
  }
}

//____________________________________________________________________
 void BrModuleContainer::Event(BrEventNode* indat, BrEventNode* outdat)
{
  //  The method to be used event by event in case there is an input
  //  table and  output table in the Event method of the modules in
  //  the list.  
  //  The loop over the modules will immediately halt, should one of
  //  the modules status become bigger than or equal to fStatusLimit,
  //  the status of this container is set to that status, and the
  //  method returns.  
  SetState(kEvent);
  BrModule *object;
  
  TIter next(fModuleList);
  while((object = (BrModule*)next())) {
    Info(15, "Event", "executing %s::Event for %s",
	 object->ClassName(), object->GetName());
    object->EventStatisticsStart();
    object->Event(indat, outdat);
    object->EventStatisticsEnd();
    if (object->GetStatus() >= fStatusLimit) {
      if (DebugLevel() > 4)
        Warning("Event", "status of '%s' %d > %d, giving up",
                object->GetName(), object->GetStatus(), fStatusLimit);
      SetStatus(object->GetStatus());
      return;
    }
  }
}

//____________________________________________________________________
 void BrModuleContainer::Finish()
{
  //  The method can be used to call Finishing for all modules in a
  //  container.   
  //  The loop over the modules will immediately halt, should one of
  //  the modules status become bigger than or equal to fStatusLimit,
  //  the status of this container is set to that status, and the
  //  method returns.  
  SetState(kFinish);
  BrModule *object;

  TIter next(fModuleList);
  while((object = (BrModule*)next())) {
    Info(25,"Finish", "executing %s::Finish for %s",
	 object->ClassName(), object->GetName());
    object->Finish();
    if (object->GetStatus() >= fStatusLimit) {
      if (DebugLevel() > 4)
        Warning("Finish", "status of '%s' %d > %d, giving up",
                object->GetName(), object->GetStatus(), fStatusLimit);
      SetStatus(object->GetStatus());
      return;
    }
  }
}

//____________________________________________________________________
 void BrModuleContainer::Print(Option_t* option)
{
  // Print information on all modules
  // 
  // Options (see also BrModule::Print())
  //   R        Recusrsively print module information 
  //
  // This non-const version only exists for backward compatiblity with
  // ROOT pre3. 
  TString opt(option);
  opt.ToLower();
  
  if (opt.Contains("b")) {
    cout << "*************************************************" << endl
	 << endl
	 << "  Module container" << endl
	 << "   Class:          " << IsA()->GetName()<< endl
	 << "   Name:           " << GetName() << endl 
	 << "   Title:          " << GetTitle() << endl
	 << endl
	 << "*************************************************" << endl;
  }
  
  if (opt.Contains("d"))
    BrModule::Print("D");

  if (opt.Contains("r")) {
    TIter    next(fModuleList);
    TObject *object;
    while((object = next()))
      object->Print(option);
  }  
}

//____________________________________________________________________
 void BrModuleContainer::Print(Option_t* option) const 
{
  // Print information on all modules
  // 
  // Options (see also BrModule::Print())
  //   R        Recusrsively print module information 
  TString opt(option);
  opt.ToLower();
  
  if (opt.Contains("b")) {
    cout << "*************************************************" << endl
	 << endl
	 << "  Module container" << endl
	 << "   Class:          " << IsA()->GetName()<< endl
	 << "   Name:           " << GetName() << endl 
	 << "   Title:          " << GetTitle() << endl
	 << endl
	 << "-------------------------------------------------" << endl;
  }

  if (opt.Contains("d"))
    BrModule::Print("D");

  if (opt.Contains("r")) {
    TIter    next(fModuleList);
    TObject *object;
    while((object = next()))
      object->Print(option);
  }  
}



//____________________________________________________________________
 void BrModuleContainer::Init()
{
  //  The method can be used to call Init for all modules in a
  //  container. Init is always implemented as a dummy default at the
  //  minimum. 
  //  The loop over the modules will immediately halt, should one of
  //  the modules status become bigger than or equal to fStatusLimit,
  //  the status of this container is set to that status, and the
  //  method returns.  
  SetState(kInit);
  BrModule *object = 0;

  TIter next(fModuleList);
  while((object = (BrModule*)next())) {
    object->Init();
    if (object->GetStatus() == BrModule::kAbort){
      SetStatus(BrModule::kAbort);
      return;
    }
    if (object->GetStatus() >= fStatusLimit) {
      if (DebugLevel() > 4)
        Warning("Init", "status of '%s' %d > %d, giving up",
                object->GetName(), object->GetStatus(),
		fStatusLimit);
      SetStatus(BrModule::kFailure);
      return;
    }
  }
}


//____________________________________________________________________
 void BrModuleContainer::ListEventStatistics()
{
  //  Call The ListEventStatistics for all Modules in the container
  //  
  BrModule *object;

  TIter next(fModuleList);
  while((object = (BrModule*)next()))
    object->ListEventStatistics();
}

//____________________________________________________________________
 void BrModuleContainer::ListModules()
{
  //  Routine to list the names of all modules that have been added.
  TObject *object = 0;
  Int_t num       = 0;
  TIter next(fModuleList);

  while((object = next()))
    cout << num++ << ": " << object << " - " << object->GetName() 
	 << " " << object->GetTitle() << endl;
}

//____________________________________________________________________
 void BrModuleContainer::Reset()
{
  // Set the status of all contained modules to kOk. 
  BrModule::Reset();

  BrModule *object = 0;
  TIter next(fModuleList);
  while((object = (BrModule*)next()))
    object->Reset();
}

//____________________________________________________________________
 void BrModuleContainer::SetDebugLevel(const int level)
{
  // Set debug level of all contained modules 
  BrModule::SetDebugLevel(level);

  BrModule *object = 0;
  TIter next(fModuleList);
  while((object = (BrModule*)next()))
    object->SetDebugLevel(level);
}

//____________________________________________________________________
 void BrModuleContainer::SetVerbose(const int level)
{
  // Set the verbosity of all contained modules 
  BrModule::SetVerbose(level);

  BrModule *object = 0;
  TIter next(fModuleList);
  while((object = (BrModule*)next()))
    object->SetVerbose(level);
}

//____________________________________________________________________
 void BrModuleContainer::SetStatusLimit(EBrModuleStatus status=kStop) 
{
  // Set the limit for when to stop module pipeline
  fStatusLimit = status;
}


//////////////////////////////////////////////////////////////////////
//
//	$Log: BrModuleContainer.cxx,v $
//	Revision 1.7  2002/06/13 17:18:17  videbaek
//	change Info/debug level
//	
//	Revision 1.6  2002/01/25 17:10:32  videbaek
//	Set failure to kAbort if retuned from sub-module.
//	Fix the labeling for Info- they were all labelled Finish - only slightly
//	confusing.
//	
//	Revision 1.5  2001/12/14 15:32:40  cholm
//	Removed the method Info(void) due to the introduction of other methods in
//	BrModule.
//	
//	Revision 1.4  2001/10/23 14:49:56  cholm
//	Changed the debugging output from various methods to depend on the
//	DebugLevel > 4, and also use TObject::Warning rather than explicit
//	cerr output.  This should make the output more legiable.
//	
//	Revision 1.3  2001/10/09 16:31:44  videbaek
//	Added more verbose output in case a module in a container stops or fails
//	This is quite useful for finding problems in scriptsAdded more verbose output in case a module in a container stops or fails
//	This is quite useful for finding problems in scripts..
//	
//	Revision 1.2  2001/08/18 13:19:22  cholm
//	Added methods to remove modules from a container. Also expanded and
//	corrected some of the documentation.
//	
//	Revision 1.1.1.1  2001/06/21 14:55:04  hagel
//	Initial revision of brat2
//	
//	Revision 1.22  2001/06/02 15:14:27  ouerdane
//	In BrIOModule, old directory is restored after the Close message.
//	In BrModuleContainer, added a verbosity print out in the Event method
//	to write out which modules are executed.
//	
//	Revision 1.21  2001/05/31 01:46:38  cholm
//	Rewrote BrModuleContainer to use TOrdCollection rather than TObjArray,
//	since that allows us to use the AddBefore, AddAfter, AddFirst, AddLAst
//	and AddAt methods for adding modules in arbitiary positions in a
//	given package or module container.
//	
//	Revision 1.20  2001/05/28 15:35:02  pchristi
//	Small changes. Added const arguments to container constructor and
//	modified/added delete methods to BrDataTable.
//	
//	Revision 1.19  2001/03/07 12:15:48  cholm
//	* Defined standard BrModule methods in BrIOModule.
//	* Add the (simple) class BrHistIOModule.
//	* BrAppOptionManager and BrAppOption classes changed to not use
//	  BrExceptions.
//	* Added the method Int_t BrMainModule::Main() to do EVERYTHING.
//	* Made the method BrModule::Info() const obsolete in favour of
//	  BrModule::Print(Option_t* option="B") const. Impact on other classes.
//	
//	Revision 1.18  2001/01/30 23:56:57  cholm
//	Added method Reset to reset status to kOk.
//	
//	Revision 1.17  2001/01/22 19:58:30  cholm
//	Corrected const-ness of BrAppOption::Compare for old ROOT versions.
//	Fixed BrModule::Streamer to work with new ROOT. Changed the avaliable
//	module status values to kStop, kFailure, kAbort, and updated
//	BrModuleContainer and BrModule accordingly. Also renamed BrIOModule::fStatus
//	to BrIOModule::fIOStatus. BrEventIO uses Stop, Failure, and Abort now.
//	Also fix of BrEventIO::Streamer for ROOT 3.00/00+
//	
//	Revision 1.16  2001/01/19 16:36:09  cholm
//	Updated BrAppOption for const'ness of compare.
//	Added state and status information to BrModule. A container may inspect
//	these react accordingly, for example by aborting the processing of the
//	current event, sequnce, run, job, etc.
//	
//	Revision 1.15  2000/12/27 21:39:45  videbaek
//	remove conflict introduced by latest commit
//	
//	Revision 1.14  2000/12/27 21:36:48  videbaek
//	Cosmetic- added checks for non-existing modules added.
//	
//	Revision 1.13  2000/12/26 16:24:19  videbaek
//	Add SetDebugLevel() to container class
//	
//	Revision 1.12  2000/09/26 20:35:26  cholm
//	* Cleaned up BrModule e.g., d_Debug => fDebug
//	* Made BrModuleContainer a BrModule
//	* Added the class BrMainModule (singleton) for complex structuring of
//	  modules in any application using BrModules
//	
//	Revision 1.11  2000/07/20 16:14:12  videbaek
//	Fixed problme in IsEventSync and IsEvent.
//	Added Finish method in Module container.
//	Moved comments CVSlog
//	
//	Revision 1.10  2000/05/17 10:36:26  ouerdane
//	see top of file
//	
//	Revision 1.9  1999/04/21 14:44:05  videbaek
//	Init called wrong method (Book)
//	
//	Revision 1.8  1999/04/09 19:36:46  videbaek
//	Clean up code; add ListStatistics to container class
//	Improve include guards.
//
//	Revision 1.7  1998/12/21 20:18:34  videbaek
//	Added magnet voluems. Additional features for Modules.
//	New BrMatch intended to replace TSonataMath. Some changes in
//	matrix routines.
//
//	Revision 1.6  1998/10/09 19:30:08  videbaek
//	improve constructor; cosmetic print changes
//
//	Revision 1.5  1998/09/08 15:23:27  alv
//	Added fVerbose=0 in constructor.
//
//	Revision 1.4  1998/08/26 16:43:48  hagel
//	Added Documentation for HTML facility
//
//	Revision 1.3  1998/07/03 15:57:39  hagel
//	Clean up g++ warnings
//
//	Revision 1.2  1998/04/06 21:11:51  videbaek
//	Clean up and additions for Win95
//
//	Revision 1.1.1.1  1998/03/04 21:32:48  brahmlib
//	Brat base
//
//

This page automatically generated by script docBrat by Christian Holm

Copyright ; 2002 BRAHMS Collaboration <brahmlib@rcf.rhic.bnl.gov>
Last Update on by

Validate HTML
Validate CSS