modelbuilding.dxy

00001 
00002 // //////////////////////////////////////////////////////////////////// //
00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2002   //
00004 // by the University of Southern California (USC) and the iLab at USC.  //
00005 // See http://iLab.usc.edu for information about this project.          //
00006 // //////////////////////////////////////////////////////////////////// //
00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00009 // in Visual Environments, and Applications'' by Christof Koch and      //
00010 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00011 // pending; application number 09/912,225 filed July 23, 2001; see      //
00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00013 // //////////////////////////////////////////////////////////////////// //
00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00015 //                                                                      //
00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00017 // redistribute it and/or modify it under the terms of the GNU General  //
00018 // Public License as published by the Free Software Foundation; either  //
00019 // version 2 of the License, or (at your option) any later version.     //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00024 // PURPOSE.  See the GNU General Public License for more details.       //
00025 //                                                                      //
00026 // You should have received a copy of the GNU General Public License    //
00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00029 // Boston, MA 02111-1307 USA.                                           //
00030 // //////////////////////////////////////////////////////////////////// //
00031 //
00032 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00033 // $Id: modelbuilding.dxy 11684 2009-09-10 22:52:30Z beobot $
00034 //
00035 
00036 
00037 // ######################################################################
00038 // ######################################################################
00039 
00040 
00041 /*! \page modelbuilding Building models using the toolkit
00042 
00043 <h1>Overview</h1>
00044 
00045 A number of facilities are provided to allow easy creation of new
00046 models. These off-load most of the work involved in having tunable
00047 persistent parameters in your models and in being able to generate and
00048 parse command-line options in your executables.
00049 
00050 To allow this, a computational model is defined as a managed
00051 collection of ModelComponent derivative objects. These objects are
00052 instantiated as a hierachical collection that varies from model to
00053 model and may also vary within one model through run-time selection of
00054 certain components or behaviors. ModelComponent provides a basic
00055 facility for building such hierarchies. In addition, it provides
00056 facilities for holding a number of ModelParam data members. These are
00057 persistent parameters, in the sense that their values can be saved to
00058 a file and later re-loaded from that file (using a ParamMap
00059 structure).  ModelParam objects typically are private to a model
00060 component and the hierarchical file format used to store them ensures
00061 that no conflict between identical parameters across several
00062 components should occur.  Finally, ModelComponent objects may request
00063 that some command-line option be created for some of their ModelParam
00064 members, so that the ModelParam values may be set via the
00065 command-line. Because typically those options may be shared among a
00066 variety of ModelComponents (e.g., radius of the focus of attention, or
00067 verbosity level), there is a single namespace for all the ModelParam
00068 names that may become valid command-line options (see
00069 ModelOptionDef.C). So, in order to be exportable as a command-line
00070 option, a ModelParam should have its name registered in a global list
00071 of all possible command-line options. When the command-line is parsed,
00072 all ModelParam objects with maching name will be updated to the value
00073 supplied in the command-line.
00074 
00075 <h1>The bottom-up view</h1>
00076 
00077 The following classes are available to implement the above
00078 functionality.
00079 
00080 - ModelParamBase is a base class (that cannot be instantiated directly
00081   because it has some virtual methods) for a persistent model
00082   parameter. At the base level, such parameter is just defined by its
00083   name and the base does not yet hold any data. However, it provides
00084   an interface for name access, registration of the parameter with its
00085   parent component, and other functionality.
00086 
00087 - ModelParam<T> is a template class that derives from
00088   ModelParamBase. It adds the actual parameter data as a single
00089   instance of a value of type T. When the parameter is saved to a
00090   ParamMap, it will appear as a "name value" pair in the file.
00091 
00092 - ModelComponent is a base class that facilitates building hierarchies
00093   of objects that may hold ModelParam<T> parameters, that may request
00094   command-line options, and that may have other ModelComponent
00095   derivatives as sub-components.
00096 
00097 - ModelManager is a class that facilitates loading/saving of
00098   ModelParam values to a config file, run-time generation of a set of
00099   command-line options that depends on which options have been
00100   requested by the particular collection of ModelComponent objects
00101   currently instantiated, parsing of the command-line options and
00102   automatic update of the ModelParam<T> contents for those parameters
00103   that have been associated with the option, and saving of config
00104   files (plus some added functionality).
00105 
00106 - ModelOptionDef.C contains a global, shared list of all possible
00107   command-line options that may be used by any model in our source
00108   tree. When ModelComponent objects request an option to be added to
00109   the command-line, it must exist in this list. There are at least
00110   three reasons for having such global shared list rather than having
00111   each component fully specify all the characteristics of some
00112   command-line option it may wish to instantiate:
00113     -# it is easier to ensure that two option names will not be used
00114        in two different parts of the codebase with different meanings
00115     -# it allows several unrelated components to easily share the
00116        value specified at the command-line (both components just need
00117        to request the correct option name; in comparison, realizing
00118        that two options are equal although they have been fully
00119        defined in two different objects would require that all
00120        meta-information (name, long option name, short option name,
00121        description, valid values) match. This would make updates a
00122        nightmare (e.g., updating the description of an option that has
00123        been used by 25 differnt components defined in 25 separate
00124        source files)).
00125     -# When you wish to create a new command-line option, it would be
00126        nearly impossible to check whether a similar one does not
00127        already exist if all the definitions were spread out all over
00128        the code.
00129 
00130 Below we walk through a typical use of these facilities to build and
00131 run a computational model that is composed of a run-rime selectable
00132 collection of ModelComponent derivatives.
00133 
00134 <h1>The top-down view and building models</h1>
00135 
00136 Typically, building a new model entails the following sequence of
00137 actions (for a fuller yet simple example, see test-audioGrab.C):
00138 
00139 - start a main() function
00140 
00141 \code
00142 int main(const int argc, const char **argv)
00143 {
00144 \endcode
00145 
00146 - instantiate a ModelManager object. It will be in charge of managing
00147   a collection of ModelComponent objects, of loading/saving their
00148   persistent data, and of creating and parsing the command-line
00149   options depending on the requests of the current collection of
00150   components:
00151 
00152 \code
00153 ModelManager manager("My cool model");
00154 \endcode
00155 
00156 - Instantiate a hierarchy of ModelComponent objects. The natural way
00157   to do that in this framework is to immediately attach the objects to
00158   a SharedPtr. Typically, each ModelComponent object will hold a
00159   number of ModelParam persistent data members. In addition,
00160   ModelComponent may request that certain command-line options be
00161   added to the command-line. This is done by calling
00162   ModelManager::requestOption(this, param) where the name of the param
00163   must correspond to one of the possible command-line option names
00164   defined in the global list in ModelOptionDef.C:
00165 
00166 \code
00167 SharedPtr<MyComponent> mycomp(new MyComponent(manager));
00168 \endcode
00169 
00170 - Register the top-level components with the manager. Upon load/save
00171   of parameter files, the manager will invoke the corresponding
00172   load/save functions on all its registered components. Those
00173   functions are recursive. so that each component will invoke the same
00174   function in all of its subcomponents:
00175 
00176 \code
00177 manager.registerComponent(mycomp);
00178 \endcode
00179 
00180 - Once you have registered your hierarchy of components, you may
00181   optionally decide which of their internal parameters you wish to
00182   export as command-line options; you may do that in batch style using
00183   (see ModelOptionDef.H for possible values to use here):
00184 
00185 \code
00186 // Note: this is optional; if you don't do this call explicitly, it
00187 // will be made automatically (exporting ALL options) just before
00188 // we start parsing the command line:
00189 manager.exportOptions(OPTEXP_ALL);
00190 \endcode
00191 
00192 - In addition, if you wish to explicitly export a ModelParam from one
00193   of your components as a command-line option (assuming the component
00194   has not already done so), you can do that using
00195   ModelComponent::doRequestOption() here (this is a recursive call so
00196   that it can also turn on option export in deeply nested
00197   sub-components that you may not have direct access to):
00198 
00199 \code
00200 mycomp->doRequestOption("MyParamName", true, true, true);
00201 \endcode
00202 
00203 - Parse the command-line, using the ModelManager built-in mechanism.
00204   This will update the values of all the requested model options,
00205   depending on which ones are specified on the command-line.  The
00206   min/max number of expected non-option arguments are passed, along
00207   with a text description of what those are, to parseCommandLine(). If
00208   an incorrect number of arguments is found, or bogus options are
00209   specified, parseCommandLine() will print a usage message and return
00210   false. There are several special command-line options that are
00211   implemented by the manager itself, including --debug, --test-mode,
00212   --load-config-from=file and --save-config-to=file. If the
00213   --load-config-from option is encountered during parsing, the config
00214   file is loaded and all ModelParam values are updated immediately. So
00215   any command-line option specified before the --load-config-file is
00216   likely to be overwritten by the values in the config file. Any
00217   command-line option specified afterwards, however, will be applied
00218   after the config file has been loaded. --save-config-to has no
00219   immediate effect. Rather, one should call manager::saveConfig() at
00220   some appropriate time (for example, after a successful run of the
00221   model), which will automatically save the config file if the option
00222   was specified, or be a no-op if the option was not
00223   specified. Finally, one last feature is that the manager may attempt
00224   to automatically load a config file named "~/.executablename" just
00225   before parsing the first option, if it was instructed to do so at
00226   construction (by default, all three of these features are on. See
00227   the ModelManager constructor for details):
00228 
00229 \code
00230 if (manager.parseCommandLine(argc, argv, "<input.ppm> <output.ppm>",
00231                                2, 2) == false) return(1);
00232 \endcode
00233 
00234 - Get the extra non-option arguments:
00235 
00236 \code
00237 int numargs = manager.numExtraArgs();
00238 std::string infilename = manager.getExtraArg(0);
00239 std::string outfilename = manager.getExtraArg(1);
00240 \endcode
00241 
00242 - If any additional configuration needs to be made now that the
00243   command-line options have been parsed, they should be made
00244   here. This may for instance include instantiation of components
00245   whose nature is defined at run-time through some command-line
00246   option.
00247 
00248 - The configuration may be automatically saved if --save-config-to was
00249   specified on the command-line (the call below will be a no-op
00250   otherwise). The call below is optional, and will be made as part of
00251   start() below if it has not been made explicitly:
00252 
00253 \code
00254 // Note: This call is optinal too, and if you don't make it
00255 // explicitly, it will be made from within start():
00256 manager.saveConfig();
00257 \endcode
00258 
00259 - Start all the components through a single recursive call. Typically
00260   each component will then perform any additional setup that could not
00261   be done in its constructor because it depended on command-line or
00262   persistent parameter values:
00263 
00264 \code
00265 manager.start();
00266 \endcode
00267 
00268 - Use the model and get some interesting results. Once the model has
00269   started, all functions that modify ModelParam<T> values will throw a
00270   fatal error if used, so that external people cannot mess with the
00271   guts of a ModelComponent once it has started.
00272 
00273 - If you need to revert your model to its initial state (e.g., your
00274   program runs three independent simulations between the start() and
00275   stop() calls), try a:
00276 
00277 \code
00278 manager.reset();
00279 \endcode
00280 
00281   to reset your model. But check that your various model components
00282   indeed do implement reset(), as reset() has been implemented only on
00283   a few components to date (since most programs run only one
00284   simulation and hence to not need any reset() capability).
00285 
00286 - Once done with a simulation, proper termination of the executable
00287   starts by recursively stopping all components.
00288 
00289 \code
00290 manager.stop();
00291 \endcode
00292 
00293 - We are now ready for an exit that will destroy the manager and the
00294   hierarchy of components.
00295 
00296 \code
00297 return 0;
00298 }
00299 \endcode
00300 
00301  */
00302 
00303 // ######################################################################
00304 /* So things look consistent in everyone's emacs... */
00305 /* Local Variables: */
00306 /* indent-tabs-mode: nil */
00307 /* End: */
Generated on Sun May 8 08:40:06 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3