00001 /*!@file Component/ModelManager.H manages a model as collection of ModelComponents */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Component/ModelManager.H $ 00035 // $Id: ModelManager.H 9335 2008-02-27 04:52:34Z rjpeters $ 00036 // 00037 00038 #ifndef MODELMANAGER_H_DEFINED 00039 #define MODELMANAGER_H_DEFINED 00040 00041 #include "Component/ModelComponent.H" 00042 #include "Component/ModelParam.H" 00043 #include "Component/OptionManager.H" 00044 #include "Util/StringConversions.H" 00045 00046 struct ModelOptionDef; 00047 class ParamMap; 00048 00049 //! Manages a collection of ModelComponent objects forming a model 00050 /*! ModelManager should be implemented once in each executable, and 00051 will facilitate the management of a collection of ModelComponent 00052 objects, load/save of tunable ModelParamBase parameters that may be 00053 in those objects, and generation/parsing of command-line 00054 options. ModelComponent objects must manually register with the 00055 ModelManager to fall under its management. Typically, when a 00056 ModelComponent has subcomponents, only the top-level component 00057 should be registered with the ModelManager, as all ModelParamBase 00058 access functions will recurse through the ModelComponent's 00059 subcomponents. See test-model.C and test-audioGrab.C for simple 00060 examples of how to write executables that are managed by 00061 ModelManager. */ 00062 class ModelManager : public OptionManager, public ModelComponent 00063 { 00064 public: 00065 // ###################################################################### 00066 /*! @name Constructors and Destructors */ 00067 //@{ 00068 00069 //! Default constructor 00070 /*! @param descrName descriptine name 00071 @param tagName tag name (see ModelComponent.H) 00072 @param loadCfgOpt create a --load-config-from=X option if true 00073 @param saveCfgOpt create a --save-config-to=X option if true 00074 @param autoLoadCfg try to load config from ~/.execname if true */ 00075 ModelManager(const std::string& descrName = "The Model", 00076 const std::string& tagName = "model", 00077 const bool loadCfgOpt = true, const bool saveCfgOpt = true, 00078 const bool autoLoadCfg = true); 00079 00080 //! Virtual destructor ensures proper destruction of derived classes 00081 virtual ~ModelManager(); 00082 00083 //! Returns true if we are running in debug mode 00084 /*! Debug mode can be invoked via the --debug command-line 00085 option. Programs can use this function to do additional debug 00086 outputs if the manager is in debug mode. In addition, we will 00087 generate a debug printout of all model parameters just before 00088 start() and we will force the log level to LOG_DEBUG (see log.H) 00089 if debug mode is on. */ 00090 bool debugMode() const; 00091 00092 //@} 00093 00094 // ###################################################################### 00095 /*! @name Model option database */ 00096 //@{ 00097 00098 //! Only allow ModelOptionDef's that match the given mask 00099 /*! This mask is used to filter requestOption() calls -- if the 00100 ModelOptionDef's filterFlag isn't part of ModelManager's current 00101 mask, then the requestOption() is ignored. */ 00102 void allowOptions(const int mask); 00103 00104 //! ModelComponent objects may request a command-line option here 00105 /*! @param p the ModelParam data member of c corresponding to the 00106 option 00107 00108 @param useMyVal if true, we will do a setOptionValString() using 00109 the current value of the parameter, so that this value 00110 will be propagated to all OptionedModelParam objects that 00111 have requested this option and will become the new 00112 command-line default value. If false, the ModelParam p 00113 will be updated to the current value of the option. So, 00114 use useMyVal=true if your component wishes to push its 00115 current parameter value as the default for everyone using 00116 this option, and use false if your component wishes to 00117 use the current default instead. */ 00118 virtual void requestOption(OptionedModelParam& p, 00119 const bool useMyVal = false); 00120 00121 //! Request the removal of a param from the command-line options 00122 /*! @param p the ModelParam data member of c corresponding to the option */ 00123 virtual void unRequestOption(OptionedModelParam& p); 00124 00125 //! Users may request model option aliases 00126 /*! @param name the name of the option alias, from ModelOptionDefs.C */ 00127 virtual void requestOptionAlias(const ModelOptionDef* def); 00128 00129 //! Set an option value 00130 /*! All ModelParam objects associated this ModelOptionDef will be 00131 updated with the new value. Will throw a fatal error if the 00132 model has been started (see ModelComponent::start()). */ 00133 virtual void setOptionValString(const ModelOptionDef* def, 00134 const std::string& val); 00135 00136 //! Get an option value 00137 /*! The value returned here is the value currently held by the 00138 ModelManager. This value is updated in three cases: 1) when a 00139 new component requests the option using requestOption() with 00140 useMyVal true; 2) when setOptionValString() is called, and 3) 00141 when the command-line arguments are parsed by ParseCommandLine, 00142 if a value for this option has been specified in the command 00143 line. If ModelComponent objects modify their local ModelParam 00144 values for their local parameter with this name, the value 00145 returned here will not be affected. */ 00146 virtual std::string getOptionValString(const ModelOptionDef* def); 00147 00148 //! Check if anybody has requested the given option. 00149 virtual bool isOptionRequested(const ModelOptionDef* def) const; 00150 00151 //@} 00152 00153 // ###################################################################### 00154 /*! @name Alternative access to internal options 00155 00156 These functions may be useful for alternative methods of 00157 displaying the help for command-line options (e.g. in the Qt 00158 ModelManagerWizard). 00159 */ 00160 //@{ 00161 00162 //! Get the number of ModelOptionDef objects in our list. 00163 virtual uint numOptionDefs() const; 00164 00165 //! Get ModelOptionDef objects from our list, up to the size of the given array. 00166 /*! Returns the number of array entries that were actually filled 00167 with valid ModelOptionDef pointers. */ 00168 virtual uint getOptionDefs(const ModelOptionDef** arr, uint narr); 00169 00170 //! Get the ModelOptionDef for the given name. 00171 /*! Aborts if there is no such ModelOptionDef. */ 00172 virtual const ModelOptionDef* findOptionDef(const char* name) const; 00173 00174 //! Query if the given ModelOptionDef is used in this program. 00175 virtual bool isOptionDefUsed(const ModelOptionDef* def) const; 00176 00177 //@} 00178 00179 // ###################################################################### 00180 /*! @name Command-line parsing */ 00181 //@{ 00182 00183 //! Parse all command-line options and set our params 00184 /*! This function will create a set of command-line options from our 00185 current collection of OptionedModelParam objects. It will then 00186 parse the command-line arguments and set the various option 00187 values accordingly, using a call to setOptionValString(). Any 00188 left-over args (i.e., not formatted as options) will be 00189 available through getExtraArg(), and if the number of such extra 00190 args is not within the specified minarg/maxarg bounds, a usage 00191 message and optionlist will be printed out (also printed out if 00192 a '--help' option is encountered). To decide which options 00193 should be exported by your various ModelComponent objects, 00194 typically you will call exportOptions() on the manager, which 00195 will propagate the call to all registered components. Here we 00196 have an additional default behavior that if exportOptions() has 00197 not been called on us, we will call it with an order to export 00198 all options, just before we start parsing the command-line. So, 00199 if you want to export all options, you don't have to do 00200 anything; if you want to only export special classes of options, 00201 then you will need to call exportOptions() manually some time 00202 before you parse the command-line. Returns true upon fully 00203 successful parse. 00204 00205 @param argc the number of command-line args 00206 @param argv the command-line args 00207 @param usage a textual description of the expected usage format, 00208 describing only what the non-option arguments should be (e.g., 00209 "<input.ppm> <output.ppm>") 00210 @param minarg the minimum number of non-optional arguments 00211 @param maxarg the maximum number of non-optional args, or -1 if 00212 unbounded */ 00213 bool parseCommandLine(const int argc, const char **argv, 00214 const char *usage, 00215 const int minarg, const int maxarg); 00216 00217 //! Overload that takes a argv array of non-const strings 00218 bool parseCommandLine(const int argc, char* const* argv, 00219 const char* usage, 00220 const int minarg, const int maxarg); 00221 00222 //! The core of parseCommandLine(). 00223 /*! This may be called recursively to handle command-line 00224 aliases. Note: beware that the first element of argv will be 00225 ignored (as it usually is the program name). */ 00226 bool parseCommandLineCore(const int argc, const char** argv); 00227 00228 bool parseCommandLineCore(const char* args); 00229 00230 00231 //! Get the number of available extra args 00232 uint numExtraArgs() const; 00233 00234 //! Get an extra arg, by number 00235 std::string getExtraArg(const uint num) const; 00236 00237 //! Get an extra arg converted to type T 00238 template <class T> 00239 inline T getExtraArgAs(const uint num) const; 00240 00241 //! Clear our list of leftover command-line arguments 00242 void clearExtraArgs(); 00243 00244 //@} 00245 00246 // ###################################################################### 00247 /*! @name Persistent ModelParamBase management */ 00248 //@{ 00249 00250 //! Load all our ModelParamBase values from file 00251 /*! This function is automatically called during parseCommandLine() 00252 if --load-config-from=XX option is encountered or autoload was 00253 specified in our constructor (thus ensuring that command-line 00254 options encountered after the option specifying which config file 00255 to load are applied after the config file has been loaded). It may 00256 also be called manually. This function is a no-op if no filename 00257 is in our loadConfigFile internal ModelParam (this parameter can 00258 be set by the --load-config-from=X command-line option). 00259 Otherwise, load the file (which should be a ParamMap) and 00260 configure all our parameters. */ 00261 void loadConfig(); 00262 00263 //! Explicitly load all our ModelParams from file 00264 /*! This function will always load the params from the given file, 00265 even is --load-config-from=X was not specified. */ 00266 void loadConfig(const std::string& fname); 00267 00268 //! Save all our ModelParams to file 00269 /*! This function is a no-op if no filename is in our saveConfigFile 00270 internal ModelParam (this parameter can be set by the 00271 --save-config-to=X command-line option). Otherwise, save all our 00272 params to the file as a ParamMap. Returns true on success. You 00273 should typically call this either some time before you start() 00274 your model, or after you have stop()'ed it. NOTE: There is a 00275 default behavior which is to call this as the first thing in 00276 start(), i.e., just before all our registered components will be 00277 started, unless you have manually called it yourself earlier, in 00278 which case it is not called again. */ 00279 void saveConfig() const; 00280 00281 //! Explicitly save all our ModelParams to file 00282 /*! This function will always save the params to the given file, 00283 even is --save-config-to=X was not specified. */ 00284 void saveConfig(const std::string& fname) const; 00285 00286 //@} 00287 00288 //! Intercept people changing our ModelParam's 00289 /*! See ModelComponent.H; as parsing the command-line or reading a 00290 config file sets our name, we'll also here instantiate a 00291 controller of the proper type (and export its options) */ 00292 virtual void paramChanged(ModelParamBase* const param, 00293 const bool valueChanged, 00294 ParamClient::ChangeStatus* status); 00295 00296 protected: 00297 // these are essentially here for the benefit of MexModelManager (we 00298 // offer these protected member functions, so that all of our member 00299 // data can be private) 00300 void setFPE(bool val); 00301 void unRequestTestMode(); 00302 void unRequestUsingFPE(); 00303 00304 // start and saveConfig first if not saved yet 00305 virtual void start1(); 00306 00307 // start cpu timer 00308 virtual void start2(); 00309 00310 // stop cpu timer 00311 virtual void stop1(); 00312 00313 private: 00314 ModelManager(const ModelManager&); 00315 ModelManager& operator=(const ModelManager&); 00316 00317 class Impl; 00318 Impl* const rep; 00319 }; 00320 00321 // ###################################################################### 00322 // Inline functions 00323 00324 // ###################################################################### 00325 template <class T> 00326 inline T ModelManager::getExtraArgAs(const uint num) const 00327 { 00328 T val; 00329 convertFromString(this->getExtraArg(num), val); 00330 return val; 00331 } 00332 00333 #endif 00334 00335 /* So things look consistent in everyone's emacs... */ 00336 /* Local Variables: */ 00337 /* indent-tabs-mode: nil */ 00338 /* End: */