One of the primary reasons one writes a Job Module is to handle the running of one or more Algorithms to produce Candidates. It is desirable to provide "knobs" that allow users to change various parameters that control how the Module and Algorithms perform their tasks. However, it is important to understand how to separate the configuration of Job Modules from that of Algorithms. It is also important to understand where default configuration information is stored and how to produce a modified configuration. This document outlines the policy and gives examples on how to follow it from the point of view of both a Module/Algorithm author and user.
Job Modules should only have configuration information that relates directly to the task performed by the Module and, in particular, should not try to marshal configuration information destined for the Algorithm itself. There is also certain configuration information that a Job Module that runs an Algorithm must supply.
Specifically, all Modules that run Algorithms
Additionally, all Modules which have configuration "knobs"
All Algorithms obtain a default set of configuration parameters by checking a cascade of locations. The first source successfully found is the only one used.
Non-default Algorithm configurations can be maintained via the same methods as shown above but using something other than "default" as the configuration name. One can also create and register a non-default AlgConfig inside the loon job script. In either case, one configures the Job Module that runs the Algorithm to use this non-default AlgConfig via the appropriate parameter. See below for examples.
This example shows how to create a modified AlgConfig based on the "default" version.
#include <string>
// This function goes into a loon script and should be called by the main
// function.
void set_alg_config(const char* experiment)
{
// Get the default and non-default configs, merge default into non-default
// and modify one entry based on the "experiment" argument.
AlgConfig& ac_def = get_algconfig("AlgNobelPrize","default");
AlgConfig& ac_new = get_algconfig("AlgNobelPrize",experiment);
ac_new.Merge(ac_def);
string exps(experiment);
if (exps == "Super-Kamiokande")
ac_new.Set("LikelyhoodToGetOne",1.0);
else if (exps == "MiniBOONE")
ac_new.Set("LikelyhoodToGetOne",0.1);
else
cerr << "Unknown experiment: " << exps << ", using default config\n";
}
void main_function(const char* experiment)
{
set_alg_config(experiment);
// Setup job path including NobelPrizeModule
// running the AlgNobelPrize algorithm
// ...
// Tell the module which alg and algconfig to use
JobCModule& np_mod = jc.Path("thePath").Mod("NobelPrizeModule");
np_mod.Set("NobelPrizeAlgorithm","AlgNobelPrize");
np_mod.Set("NobelPrizeAlgConfig",experiment);
}
A "DBtxt" file is a snippet of C++ code to be interpreted by loon which is responsible for setting an Algorithm's AlgConfig which must take the name "default". An example for a fictional Algorithm is:
void DBtxt_AlgGenerateThesis_default(void)
{
// Get the AlgConfig object (FIXME state what .h to include)
AlgConfig& ac = get_algconfig("AlgGenerateThesis","default");
// FIXME: is this actually needed?
acd.UnLockValues();
// Set default parameters.
acd.Set("PageLimit", 300);
acd.Set("AnticipatedPostDocSallary", 45000*Munits::dollar);
acd.Set("TimeLeftToGraduate", 3.0*Munits::month);
acd.LockValues();
acd.LockKeys();
}
This file should be in the ROOT macro path. Typically this means placing it in $SRT_PUBLIC_CONTEXT/macros/ by adding it to the ROOTMACROS variable in the package's GNUmakefile.
This example gives best practices for following the Module configuration policy. It gives just the code related to configuration.
#include <Algorithm/AlgConfig.h>
// Create and return default config Registry for the module. Use
// a couple static variables to slightly optimize for speed.
void FundingRequestModule::DefaultConfig()
{
static bool been_here = false;
static Registry def_cfg;
if (been_here) return def_cfg;
been_here = true;
string name = this->JobCModule::GetName();
name += ".config.default";
def_cfg.SetName(name.c_str());
// Set defaults
def_cfg.Set("FundingRequestAlgorithm","AlgFundingRequest");
def_cfg.Set("FundingRequestAlgConfig","default");
def_cfg.Set("ProposalListIn","cand_proposal_list");
def_cfg.Set("FundingRequestName","DefaultBeggingForSupport");
def_cfg.Set("LogLevel","Fatal");
return def_cfg;
}
// Create a CandFundingRequest - only config related lines shown
JobCResult FundingRequestModule::Reco(MomNavigator* mom)
{
const char* tmps = 0;
const char* alg_name = 0;
const char* alg_config_name = 0;
const char* list_in = 0;
const char* out_name = 0;
// ...
// One could also make these data members of the Module and fill
// them once in BeginJob(), although this would not allow them to
// change in the middle of the job.
Registry& cfg = this->GetConfig();
if (cfg.Get("FundingRequestAlgorithm",tmps)) alg_name = tmps;
if (cfg.Get("FundingRequestAlgConfig",tmps)) alg_config_name = tmps;
if (cfg.Get("ProposalListIn",tmps)) list_in = tmps;
if (cfg.Get("FundingRequestName",tmps)) out_name = tmps;
// ...
// Get the input
CandProposalListHandle *cplh = dynamic_cast<CandProposalListHandle*>
(candrec->FindCandHandle("CandProposalListHandle",list_in));
// ...
// and set it in CandContext so the Alg can get at it
CandContext cx(this,mom);
cx.SetDataIn(cplh);
// ...
// Finally look up the algorithm by name and cfg name, run it
// to get a candidate and set the candidate name and title.
AlgFactory &af = AlgFactory::GetInstance();
AlgHandle ah = af.GetAlgHandle(alg_name,alg_config_name);
CandFundingRequestHandle cfrh = CandFundingRequest::MakeCandidate(adlh,cx);
cfrh.SetName(out_name);
cfrh.SetTitle(TString("Created by FundingRequestModule from ").Append(list_in));
// ...
}
Last Modified: $Date: 2004/07/19 19:30:05 $