SLAC PEP-II
BABAR
SLAC<->RAL
Babar logo
Workbook HEPIC Databases PDG HEP preprints
Organization Detector Computing Physics Documentation
Personnel Glossary Sitemap Search Hypernews
Unwrap page!
Wkbk. Search
Wkbk. Sitemap
Introduction
Non SLAC
HOWTO's
Introduction
Logging In
QuickTour
Detector
Info Resources
Software Infrastructure
CM2 Introduction
Unix
OO
SRT
Objectivity
Event Store
Framework
Beta
Modifying Code
Writing and Editing
Compiling
Debugging
Analysis
Framework II
Analysis
Find Data
Batch Processing
PAW
PAW II
ROOT I
ROOT II
ROOT III
Advanced Infrastructure
New Releases
Workdir
Main Packages
Event Displays
Gen/Sim/Reco
Contributing Software
SRT and CVS
Coding
Advanced Topics
Make CM2 Ntuples
New Packages
New Packages 2
Persistent Classes
Java
Site Installation
Check this page for HTML 4.01 Transitional compliance with the
W3C Validator
(More checks...)

Framework Continued

In multiple places throughout the workbook, reference has been made to the Framework's capability for interactive analysis applications. One example of this capability is the user's ability to enable or disable a module in an execution path. The other main interactive feature is centered about the module talk command. This supports the ability to change certain parameters of a module class while running the analysis job. Parameters such as filenames, limits, and booleans used as switches are ideal for this feature. This chapter will focus on the general implementation of the Framework and modules, the module talk command, and how to modify the PExample class to make use of this interactive Framework feature.

Module and Framework Implementation

To begin with, let's take a look at some of the general structure of the Framework and module implementation. Having a base idea of this information proves quite useful. Rather than consider this a digression, use it as a base for further investigation of the header files included in BaBar software packages.

Framework

Some of the public data members of a Framework object are lists of modules, paths, and sequences. The Framework has a list of modules that is initially empty. An analysis program must load the Framework with the modules that it will need. This was why the modules in your analysis sequence needed to be added in the AppUserBuildBase.cc file. The Framework constructs sequences and paths from the modules that are in this list as instructed by tcl scripts, and stores them in respective lists.
   
   AppList< AppModule* >      modules  ( ) const;
   AppList< AppPath* >        paths    ( ) const;
   AppList< AppSequence* >    sequences( ) const;
   AppList< AppInputModule* > inputModules ( ) const;
   AppList< AppOutputModule* > outputModules( ) const;
You can find the definitions of these AppThings (except AppList) in the Framework package. (Note: despite keeping a list of several input and output modules, only one active and enabled input module and one active output module are executed.)

Modules

All modules for use in analysis application inherit from a base class AppModule. Recall the class definition for the PExample module.
   class PExample : public AppModule {
The inheritance is used to force a common interface of all analysis modules used in the Framework. It also provides the key feature to the Framework's ability to access parameters.

The AppModule class has a public data member which is a list of AppCommands.

   AppList< AppCommand >* commands     ( ) const;
Each module thus has a list of commands. Any member of this command list can be accessed by the Framework.

Parameters

Parameters that a user may wish to access while doing analysis should be placed in the command list of the module to which they belong. Since the command's list is a list of AppCommands, the parameters must either be of this type or inherit from it. In BaBar software AppCommand is a few generations of inheritance away from the parameter types. The interactive parameter types inherit from the AbsParm class which in turn inherits from the AppCommand class. Here is a list of parameter types that can be accessed from the Framework (these classes are part of the Framework and AbsParm packages):
   AbsParmDouble
   AbsParmGeneral<T>
   AbsParmFilename
   AbsParmString
   AbsParmBool
   AbsParmIfdStrKey
   AbsParmVector<T>
   AbsParmNamedObject<T> 
   AbsParmNamedValue<T>
   AbsParmPairs 
There is some uniform structure to all of these AbsParm parameters. When you declare/initialize one, it is passed three arguments.
  • the command name; a string in double quotes,
  • a module (the parameter's target): use the "this" pointer,
  • a value (of the appropriate parameter type).
The example modules that we have used so far, NTrkExample and PExample, already have an AbsParm parameter as a member function.
   AbsParmIfdStrKey _btaChargedList;
which is initialized in the constructor by:
 _btaChargedList("trackCandidates", this, "ChargedTracks");
This parameter is used in our modules to identify which list in the event should be used in the analysis. Since _btaChargedList is a member function of the NTrkExample module, the 'this' pointer is a reference to NTrkExample. AbsParm parameters make sense only in the context of module classes. The name "trackCandidates" is the name used from the Framework (when talking to NTrkExample) to access the parameter. The string "ChargedTracks" is the value associated with _btaChargedList. This value is what the user can change from within the Framework.

AbsParm parameters also have two common public member functions:

  • value( ) : the accessor
  • set( ) : the mutator
In the Quicktour, the NTrkExample module passed _btaChargedList.value() as the argument to get a beta candidate list from the event:
HepAList<BtaCandidate>* trkList  =
    Ifd<HepAList< BtaCandidate > >::get(anEvent, _btaChargedList.value());
This command would have the same effect if you had put "ChargedTracks" instead of "_btaChargedList.value()". However, it is better to use "_btaChargedList.value()", because you can change this parameter at runtime.

Declaring a module data member of an AbsParm type is not enough to make it accessible to/from the Framework. It needs to be a member of the module's commands list. This is accomplished by the following append command:

   commands()->append(& _name);
This command should be part of the module class constructor function. But this command was not made for the _btaChargedList parameter in the NTrkExample or PExample modules. So up until now, it has not been accessible to/from the Framework.

If this seems somewhat confusing don't worry (yet). After covering some more details of the module talk command we will go through an example of modifying the PExample module class to have its histogram parameters Framework-accessible.


Module Talk

The Implementation

Both the Framework and module classes have member functions by the name talkto( ) or talk( ) (synonyms). When you are running an executable you can issue the module talk <module_name> command at the Framework prompt. Then, if module_name is in the Framework's list of modules, it is passed to Framework's talk( ) member function, which in turn calls the module's talk command.

The Command

In addition to providing a few standard commands the module's talk command also has access to the commands list. Here is the standard set of commands provided by module talk.  (These can be displayed by typing help during a talk with the module.)

Command Definition
echo <arg1> [<arg2> ...] echos the arguments to the standard output.
exit return control to the Framework.
help lists the commands available.
show lists the parameters available and their current value.
sourceFoundFile <file> source the tcl file in the path given by $BFDEFAULTSEARCHPATH or $BFSEARCHPATH.
verbose a boolean parameter that controls standard output.
production a boolean parameter to indicate processing in Production.
enableFrames a boolean to enable frames.

From the Framework prompt issue

   > module talk PExample 
PExample> help
The output should look like this:
   
Command(s) available in the "PExample" module:
      echo  Send text argument to stdout (useful in scripts).
      exit  Leave the current menu, module, or process
      help  Bring up help text for the current context.
      show  Display the value of any parameters or statistics.
      sourceFoundFile   Source file in $BFDEFAULTSEARCHPATH or $BFSEARCHPATH.
      verbose           bool parameter: set or list
      production        bool parameter: set or list
      enableFrames      bool parameter: set or list
Notice that _btaChargedList is not listed as an available command/parameter. Later you will add it to PExample's command list, and then it will be.

All modules inheriting from AppModule have three AbsParm parameters: verbose, production, and enableFrames. The output of help shows what type of AbsParm each is (all three are bools) and what actions you can perform on them (set and list). The syntax for applying an action to a parameter is:

   ModuleName> parameter list
   ModuleName> parameter set value
These two actions perform the expected tasks: 'list' will return the current value of the parameter and 'set' will redefine that value according to the argument you pass.

Some Useful Modules and Parameters

Recall from the Quicktour the command sequence:

   > mod talk KanEventInput
   KanEventInput> input add /store/SP/R18/001237/200309/18.6.0b/SP_001237_013238
   KanEventInput> exit
   >
Here you used the module talk facility to set the data collection (from the cond18boot database) to be analyzed. The KanEventInput module is an input module used to designate the source of initial data. It has a parameter "input add" that selects the input files. The KanEventOutput is an output module, used to handle output data.

The RooTupleEnv module has a parameter "histFileName" that is used to set the name of the histogram output file. In MyMiniAnalysis histFileName is set to "MyMiniAnalysis.root" instead, but in snippet.tcl it is reset to "myHistogram.root". The "set" command in snippet.tcl wins, and the output file is named "myHistogram.root". histFileName is a good parameter to be aware of. After you have modified your analysis module(s) to have framework-accessible parameters you may wish to analyse some events, change parameter values and then analyse more events. In between these two runs you could change the histFileName to keep the data for the two parameter sets separate.


Framework Interactive Module Example

Let's put all of this together by modifying the PExample module to take advantage of the Framework's interactive capabilities. To begin, copy your PExample.cc and .hh files into ones named FrmwkExample.cc and .hh respectively. You will need to uniformly change all instances of PExample to FrmwkExample.

In the FrmwkExample header file add the following private data members to the class definition/declaration. These three AbsParm variables will be used for the histogram parameters (number of bins, and the x axis low and high limits).

AbsParmGeneral<int>    _pnbins;
AbsParmGeneral<double> _pxlow;
AbsParmGeneral<double> _pxhigh;

To use this new data type you will need to #include the appropriate header files in FrmwkExample.hh. Each AbsParm parameter type has an associated header file in the Framework package. These two AbsParm parameter types, int and double, are really templates from one type: AbsParmGeneral. Add the line

#include "Framework/AbsParmGeneral.hh" 
to the top of FrmwkExample.hh

Initialize the variables in the constructor declaration (in the .cc file). There is a similar line for the _btaChargedList parameter. Copy these lines just after it. Values of 50 bins, and an x-axis range of 0 to 2 are a reasonable first start. The parameter names here reflect the data member names, but this is not required.

   , _pnbins("pnbins",this,50)
   , _pxlow("pxlow",this, 0.)
   , _pxhigh("pxhigh",this, 2.0)
For these parameters to be accessible to the Framework they need to be appended to the commands list of the module. To do this, add the following lines to the body of the FrmwkExample class constructor (between the curly brackets "{" and "}"):
   commands()->append(& _pnbins);
commands()->append(& _pxhigh);
commands()->append(& _pxlow);
We might as well add the _btaChargedList variable to the commands list at the same time.
   commands()->append(& _btaChargedList); 
The final step is to use these parameters in the context of the module code. When you booked the momentum histogram you explicitly passed values for the number of bins, low- and high-range values. Now you want the code for your histogram to use these interactive parameters. Recall each AbsParm type of parameter has an accessor function named value(). Use this function to pass the histogram manager each parameter's value.
   _pHisto = manager->histogram("momentum", _pnbins.value() , _pxlow.value(), _pxhigh.value() );
Now changes to these parameter values will be reflected in changes to the different aspects of the histogram.

After making these changes you will need to add FrmwkExample to the Framework by modifying the AppUserBuildBase.cc file. Instead of replacing PExample in the MyMiniAnalysis sequence, you may wish to append FrmwkExample to the same sequence. This way you can compare the two modules from within the Framework. Add the following lines to AppUserBuildBase.cc, just after the equivalent lines for PExample:

#include "BetaMiniUser/FrmwkExample.hh"
  theBuild->add(new FrmwkExample("FrmwkExample", "Framework example module"));

The last step is to modify MyMiniAnalysis.tcl to add your new module to the path. Again after the equivalent line for PExample, put:

path append Everything FrmwkExample

Because you changed C++ code (.cc and .hh files), you will have to recompile and relink for your new module to be added to the framework:

ana30> gmake clean
ana30> rm all.log
ana30> bsub -q bldrecoq -o all.log gmake all
For more detailed instructions about compiling and linking, refer back to the Compile, Link and Run section.

Run the executable and investigate the two modules by looking at the module talk options. Then analyse a few events, change some parameters, and analyse further events. Here is a sample dialog of such an investigation.

A working example of the FrmwkExample module is provided in:

$BFROOT/www/doc/workboook/NewExamples/FrmwkExample/

Setting parameters in a tcl file

If you looked at the investigation, you saw that the FrmwkExample module comes with seven parameters that are accessible to the framework:

verbose
production
enableFrames
pnbins
pxhigh
pxlow 
trackCandidates

You can create a tcl file called FrmwkExample.tcl that sets all of these parameters.


##  FrmwkExample.tcl: Set parameters for FrmwkExample

mod talk FrmwkExample

verbose set f 
production set f
enableFrames set f
pnbins set 50
pxlow set 0
pxhigh set 2
trackCandidates set ChargedTracks

exit

Now when you get to the framework prompt (">"), all you have to do is type:

> sourceFoundFile BetaMiniUser/FrmwkExample.tcl

This will execute your script, and the parameters will be set.

You can make similar tcl scripts for any other commands that you don't want to type all the time. For example, you may get tired of talking to KanEventInput, so you create the following tcl script:


## MyKanEventInput.tcl

mod talk KanEventInput
input add /store/SP/R18/001237/200309/18.6.0b/SP_001237_013238
exit

Then to execute the script, again you just type:
> sourceFoundFile BetaMiniUser/MyKanEventInput.tcl
You can go a step further, and add these sourceFoundFile commands to another tcl file. The place to put them is at the end of MyMiniAnalysis.tcl, because it is after executing MyMiniAnalysis.tcl that the framework would give you a prompt. So at the end of MyMiniAnalysis.tcl, you can put:

sourceFoundFile BetaMiniUser/FrmwkExample.tcl
sourceFoundFile BetaMiniUser/MyKanEventInput.tcl
You can even put the commands to start the job and exit the framework at the end:

ev begin -nev 40
exit
The "exit" command exits the framework, so now you will no longer get a framework prompt (">"). If you want it back, you will need to remove the "exit" command.

(In fact, the original MyMiniAnalysis.tcl did include the "ev begin" and "exit" commands, but they were removed so that you could enter them interactively.)

You can get working examples of these new tcl files in: $BFROOT/www/doc/workbook/NewExamples/FrmwkTCL/

(Note that if you copy these, it will overwrite your current MyMiniAnalysis.tcl file. If you want the old one back, you can copy it again from $BFROOT/www/doc/workbook/NewExamples/FrmwkExample/.) The command to run the job is the same as usual:

workdir> BetaMiniApp snippet.tcl

But now the job runs without stopping.

Now any time you want to change the parameters for FrmwkExample, all you have to do is change FrmwkExample.tcl and run the job again.

In BaBar software it is commmon to see the same name for a .tcl, .cc and .hh file. For example, in BetaMiniUser you have:

MyMiniAnalysis.hh
MyMiniAnalysis.cc
MyMiniAnalysis.tcl

Usually this means that tcl file sets parameters that were made accessible to the framework in the .cc and .hh file. It may also perform other setup or source other tcl files.


Back to Workbook Front Page

Authors: Tracey Marsh

Contributors: Joseph Perl, Asoka De Silva, Jenny Williams


Last modification: 20 January 2006
Last significant update: 13 June 2005