AlgFactory.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2019, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5  or see $GENIE/LICENSE
6 
7  Author: Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
8  University of Liverpool & STFC Rutherford Appleton Lab
9 
10  For the class documentation see the corresponding header file.
11 
12  Important revisions after version 2.0.0 :
13  @ Dec 06, 2008 - CA
14  Tweak dtor so as not to clutter the output if GENIE exits in err so as to
15  spot the fatal mesg immediately.
16  @ Oct 20, 2009 - CA
17  Added argument in ForceReconfiguration() to ignore algorithm opt-outs.
18  Default is to respect opt-outs.
19 */
20 //____________________________________________________________________________
21 
22 #include <iostream>
23 #include <cstdlib>
24 
25 #include <TROOT.h>
26 #include <TClass.h>
27 
32 
33 using std::endl;
34 
35 using namespace genie;
36 
37 //____________________________________________________________________________
38 namespace genie {
39  ostream & operator<<(ostream & stream, const AlgFactory & algf)
40  {
41  algf.Print(stream);
42  return stream;
43  }
44 }
45 //____________________________________________________________________________
47 //____________________________________________________________________________
49 {
50  fInstance = 0;
51 }
52 //____________________________________________________________________________
54 {
55 // Clean up and report on the concrete algorithms used in this instance.
56 // Don't clutter output if exiting in err.
57 
58  map<string, Algorithm *>::iterator alg_iter;
59  for(alg_iter = fAlgPool.begin(); alg_iter != fAlgPool.end(); ++alg_iter) {
60  Algorithm * alg = alg_iter->second;
61  if(alg) {
62 /*
63  if(!gAbortingInErr) {
64  cout << "- Deleting algorithm: " << alg->Id() << endl;
65  }
66 */
67  delete alg;
68  alg = 0;
69  }
70  }
71  fAlgPool.clear();
72  fInstance = 0;
73 }
74 //____________________________________________________________________________
76 {
77  if(fInstance == 0) {
78  static AlgFactory::Cleaner cleaner;
80 
81  fInstance = new AlgFactory;
82  }
83  return fInstance;
84 }
85 //____________________________________________________________________________
87 {
88 //! Manages the instantiation and "storage/retrieval" of algorithms.
89 //! These algorithms are owned by the factory and it hands over (to the client)
90 //! a "const Algorithm *" that can be dynamically casted to the requested
91 //! Algorithm Interface (eg. XSecAlgorithmI, Decayer, PdfModelI, etc...)
92 
93  return this->GetAlgorithm(algid.Name(), algid.Config());
94 }
95 //____________________________________________________________________________
97 {
98  string key = name + "/" + config;
99 
100  SLOG("AlgFactory", pDEBUG)
101  << "Algorithm: " << key << " requested from AlgFactory";
102 
103  map<string, Algorithm *>::const_iterator alg_iter = fAlgPool.find(key);
104  bool found = (alg_iter != fAlgPool.end());
105 
106  if(found) {
107  LOG("AlgFactory", pDEBUG) << key << " algorithm found in memory";
108  return alg_iter->second;
109  } else {
110  //-- instantiate the factory
111  Algorithm * alg_base = this->InstantiateAlgorithm(name,config);
112 
113  //-- cache the algorithm for future use
114  if(alg_base) {
115  pair<string, Algorithm *> key_alg_pair(key, alg_base);
116  fAlgPool.insert(key_alg_pair);
117  } else {
118  LOG("AlgFactory", pFATAL)
119  << "Algorithm: " << key << " could not be instantiated";
120  exit(1);
121  }
122  return alg_base;
123  }
124  return 0;
125 }
126 //____________________________________________________________________________
128 {
129 //! Hands over an algorithm instance that is owned by the client.
130 //! The client can alter this object (eg. reconfigure) but the AlgFactory does
131 //! not keep track of it and the client is responsible for deleting it.
132 
133  return this->AdoptAlgorithm(algid.Name(), algid.Config());
134 }
135 //____________________________________________________________________________
137 {
138  Algorithm * alg_base = InstantiateAlgorithm(name, config);
139  return alg_base;
140 }
141 //____________________________________________________________________________
142 void AlgFactory::ForceReconfiguration(bool ignore_alg_opt_out)
143 {
144  LOG("AlgFactory", pNOTICE)
145  << " ** Forcing algorithm re-configuration";
146 
147  map<string, Algorithm *>::iterator alg_iter = fAlgPool.begin();
148  for( ; alg_iter != fAlgPool.end(); ++alg_iter) {
149  Algorithm * alg = alg_iter->second;
150  bool reconfig = (ignore_alg_opt_out) ? true : alg->AllowReconfig();
151  if(reconfig) {
152  string config = alg->Id().Config();
153  bool skip_conf = (config=="NoConfig" || config=="");
154  if(!skip_conf) {
155 // LOG("AlgFactory", pINFO) << "Reconfiguring: " << alg->Id().Key();
156  alg->Configure(config);
157  }
158  }//allow?
159  }
160 }
161 //____________________________________________________________________________
163 {
164 //! Instantiate the requested object based on the registration of its TClass
165 //! through the generated ROOT dictionaries
166 //! The class of any object instantiated here must have a LinkDef entry.
167 
168  // Get object through ROOT's TROOT::GetClass() mechanism
169  LOG("AlgFactory", pDEBUG) << "Instantiating algorithm = " << name;
170 
171  TClass * tclass = gROOT->GetClass(name.c_str());
172  if(!tclass) {
173  LOG("AlgFactory", pERROR)
174  << "Failed instantiating algorithm = " << name;
175  return 0;
176  }
177  void * vd_base = tclass->New();
178  Algorithm * alg_base = (Algorithm *) (vd_base);
179 
180  // Configure the instantiated algorithm
181 
182  LOG("AlgFactory", pDEBUG) << "Setting Configuration Set = " << config;
183 
184  bool skip_conf = (config=="NoConfig" || config=="");
185  if ( skip_conf ) {
186  LOG("AlgFactory", pDEBUG) << "Skipping algorithm configuration step!";
187  } else {
188  alg_base->Configure(config);
189  }
190 
191  return alg_base;
192 }
193 //____________________________________________________________________________
194 void AlgFactory::Print(ostream & stream) const
195 {
196  string frame(100,'.');
197 
198  stream << endl;
199  map<string, Algorithm *>::const_iterator alg_iter;
200  for(alg_iter = fAlgPool.begin(); alg_iter != fAlgPool.end(); ++alg_iter) {
201  const Algorithm * alg = alg_iter->second;
202  stream << frame << endl;
203  stream << "Used algorithm: " << alg->Id() << endl;
204  stream << "Printing config:";
205  stream << alg->GetConfig();
206  }
207 
209  const Registry & gc = *(confp->GlobalParameterList());
210 
211  stream << frame << endl;
212  stream << "Printing global parameters list:";
213  stream << gc;
214 }
215 //____________________________________________________________________________
const XML_Char * name
Definition: expat.h:151
void Print(ostream &stream) const
print algorithm factory
Definition: AlgFactory.cxx:194
THE MAIN GENIE PROJECT NAMESPACE
Definition: GeneratorBase.h:8
#define pERROR
Definition: Messenger.h:60
A singleton class holding all configuration registries built while parsing all loaded XML configurati...
Definition: AlgConfigPool.h:41
#define pFATAL
Definition: Messenger.h:57
Algorithm abstract base class.
Definition: Algorithm.h:54
Definition: config.py:1
virtual ~AlgFactory()
Definition: AlgFactory.cxx:53
singleton cleaner
Definition: AlgFactory.h:81
virtual const Registry & GetConfig(void) const
Definition: Algorithm.cxx:254
static AlgFactory * fInstance
sinleton&#39;s self
Definition: AlgFactory.h:75
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:97
string Name(void) const
Definition: AlgId.h:45
void ForceReconfiguration(bool ignore_alg_opt_out=false)
Definition: AlgFactory.cxx:142
virtual void Configure(const Registry &config)
Definition: Algorithm.cxx:70
const Algorithm * GetAlgorithm(const AlgId &algid)
Definition: AlgFactory.cxx:86
Algorithm * AdoptAlgorithm(const AlgId &algid) const
Definition: AlgFactory.cxx:127
Registry * GlobalParameterList(void) const
Algorithm * InstantiateAlgorithm(string name, string config) const
Definition: AlgFactory.cxx:162
Algorithm ID (algorithm name + configuration set name)
Definition: AlgId.h:35
virtual const AlgId & Id(void) const
Get algorithm ID.
Definition: Algorithm.h:98
static AlgFactory * Instance()
Definition: AlgFactory.cxx:75
virtual bool AllowReconfig(void) const
Definition: Algorithm.h:106
ostream & operator<<(ostream &stream, const AlgConfigPool &config_pool)
A registry. Provides the container for algorithm configuration parameters.
Definition: Registry.h:66
exit(0)
#define pNOTICE
Definition: Messenger.h:62
The GENIE Algorithm Factory.
Definition: AlgFactory.h:40
map< string, Algorithm * > fAlgPool
&#39;algorithm key&#39; (namespace::name/config) -> &#39;algorithmic object&#39; map
Definition: AlgFactory.h:78
#define SLOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a short string (using the FUNCTION and...
Definition: Messenger.h:85
static AlgConfigPool * Instance()
#define pDEBUG
Definition: Messenger.h:64
string Config(void) const
Definition: AlgId.h:46