ROOT logo
// @(#)root/tmva $Id$   
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : Configurable                                                          *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Base class for all classes with option parsing                            *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Joerg Stelzer   <Joerg.Stelzer@cern.ch>  - CERN, Switzerland              *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         * 
 *      MPI-K Heidelberg, Germany                                                 * 
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

#ifndef ROOT_TMVA_Configurable
#define ROOT_TMVA_Configurable

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Configurable                                                         //
//                                                                      //
// Base class for all classes with option parsing                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TList
#include "TList.h"
#endif

#ifndef ROOT_TMVA_Option
#include "TMVA/Option.h"
#endif

namespace TMVA {

   class Configurable : public TObject {

   public:

      // constructur
      Configurable( const TString& theOption = "" );
      
      // default destructur
      virtual ~Configurable();

      // parse the internal option string
      virtual void ParseOptions();

      // print list of defined options
      void PrintOptions() const;

      virtual const char* GetName()      const { return GetConfigName(); }
      const char* GetConfigName()        const { return fConfigName; }
      const char* GetConfigDescription() const { return fConfigDescription; }
      void SetConfigName       ( const char* n ) { fConfigName        = TString(n); }
      void SetConfigDescription( const char* d ) { fConfigDescription = TString(d); }

      // Declare option and bind it to a variable
      template<class T> 
      OptionBase* DeclareOptionRef( T& ref, const TString& name, const TString& desc = "" );

      template<class T> 
      OptionBase* DeclareOptionRef( T*& ref, Int_t size, const TString& name, const TString& desc = "" );

      // Add a predefined value to the last declared option
      template<class T>
      void AddPreDefVal(const T&);

      // Add a predefined value to the option named optname
      template<class T>
      void AddPreDefVal(const TString&optname ,const T&);

      
      void CheckForUnusedOptions() const;

      const TString& GetOptions() const { return fOptions; }
      void SetOptions(const TString& s) { fOptions = s; }

      void WriteOptionsToStream ( std::ostream& o, const TString& prefix ) const;
      void ReadOptionsFromStream( std::istream& istr );

      void AddOptionsXMLTo( void* parent ) const;
      void ReadOptionsFromXML( void* node );

   protected:
      
      Bool_t LooseOptionCheckingEnabled() const { return fLooseOptionCheckingEnabled; }
      void   EnableLooseOptions( Bool_t b = kTRUE ) { fLooseOptionCheckingEnabled = b; }

      void   WriteOptionsReferenceToFile();

      void   ResetSetFlag();

      const TString& GetReferenceFile() const { return fReferenceFile; }

   private:

      // splits the option string at ':' and fills the list 'loo' with the primitive strings
      void SplitOptions(const TString& theOpt, TList& loo) const;

      TString     fOptions;                          //! options string
      Bool_t      fLooseOptionCheckingEnabled;       //! checker for option string

      // classes and method related to easy and flexible option parsing
      OptionBase* fLastDeclaredOption;  //! last declared option
      TList       fListOfOptions;       //! option list

      TString     fConfigName;          // the name of this configurable
      TString     fConfigDescription;   // description of this configurable
      TString     fReferenceFile;       // reference file for options writing

   protected:

      // the mutable declaration is needed to use the logger in const methods
      MsgLogger& Log() const { return *fLogger; }                       

   public:

      // set message type
      void SetMsgType( EMsgType t ) { fLogger->SetMinType(t); }


   private:

      mutable MsgLogger* fLogger;                     //! message logger

      template <class T>
      void AssignOpt( const TString& name, T& valAssign ) const;
      
   public:

      ClassDef(Configurable,0)  // Virtual base class for all TMVA method

   };
} // namespace TMVA

// Template Declarations go here

//______________________________________________________________________
template <class T>
TMVA::OptionBase* TMVA::Configurable::DeclareOptionRef( T& ref, const TString& name, const TString& desc) 
{
   // set the reference for an option
   OptionBase* o = new Option<T>(ref, name, desc);
   fListOfOptions.Add(o);
   fLastDeclaredOption = o;
   return o;
}

template <class T>
TMVA::OptionBase* TMVA::Configurable::DeclareOptionRef( T*& ref, Int_t size, const TString& name, const TString& desc) 
{
   // set the reference for an option
   OptionBase* o = new Option<T*>(ref, size, name, desc);
   fListOfOptions.Add(o);
   fLastDeclaredOption = o;
   return o;
}

//______________________________________________________________________
template<class T>
void TMVA::Configurable::AddPreDefVal(const T& val) 
{
   // add predefined option value to the last declared option
   Option<T>* oc = dynamic_cast<Option<T>*>(fLastDeclaredOption);
   if(oc!=0) oc->AddPreDefVal(val);
}

//______________________________________________________________________
template<class T>
void TMVA::Configurable::AddPreDefVal(const TString &optname, const T& val) 
{
   // add predefined option value to the option named optname

  TListIter optIt( &fListOfOptions );   
  while (OptionBase * op = (OptionBase *) optIt()) {
    if (optname == TString(op->TheName())){
      Option<T>* oc = dynamic_cast<Option<T>*>(op);
      if(oc!=0){
        oc->AddPreDefVal(val);
        return;
      }
      else{
        Log() << kFATAL << "Option \"" << optname 
              << "\" was found, but somehow I could not convert the pointer propperly.. please check the syntax of your option declaration" << Endl;
        return;
      }
      
    }
  }
  Log() << kFATAL << "Option \"" << optname 
        << "\" is not declared, hence cannot add predefined value, please check the syntax of your option declaration" << Endl;
  
}

//______________________________________________________________________
template <class T>
void TMVA::Configurable::AssignOpt(const TString& name, T& valAssign) const 
{
   // assign an option
   TObject* opt = fListOfOptions.FindObject(name);
   if (opt!=0) valAssign = ((Option<T>*)opt)->Value();
   else 
      Log() << kFATAL << "Option \"" << name 
            << "\" not declared, please check the syntax of your option string" << Endl;
}

#endif

 Configurable.h:1
 Configurable.h:2
 Configurable.h:3
 Configurable.h:4
 Configurable.h:5
 Configurable.h:6
 Configurable.h:7
 Configurable.h:8
 Configurable.h:9
 Configurable.h:10
 Configurable.h:11
 Configurable.h:12
 Configurable.h:13
 Configurable.h:14
 Configurable.h:15
 Configurable.h:16
 Configurable.h:17
 Configurable.h:18
 Configurable.h:19
 Configurable.h:20
 Configurable.h:21
 Configurable.h:22
 Configurable.h:23
 Configurable.h:24
 Configurable.h:25
 Configurable.h:26
 Configurable.h:27
 Configurable.h:28
 Configurable.h:29
 Configurable.h:30
 Configurable.h:31
 Configurable.h:32
 Configurable.h:33
 Configurable.h:34
 Configurable.h:35
 Configurable.h:36
 Configurable.h:37
 Configurable.h:38
 Configurable.h:39
 Configurable.h:40
 Configurable.h:41
 Configurable.h:42
 Configurable.h:43
 Configurable.h:44
 Configurable.h:45
 Configurable.h:46
 Configurable.h:47
 Configurable.h:48
 Configurable.h:49
 Configurable.h:50
 Configurable.h:51
 Configurable.h:52
 Configurable.h:53
 Configurable.h:54
 Configurable.h:55
 Configurable.h:56
 Configurable.h:57
 Configurable.h:58
 Configurable.h:59
 Configurable.h:60
 Configurable.h:61
 Configurable.h:62
 Configurable.h:63
 Configurable.h:64
 Configurable.h:65
 Configurable.h:66
 Configurable.h:67
 Configurable.h:68
 Configurable.h:69
 Configurable.h:70
 Configurable.h:71
 Configurable.h:72
 Configurable.h:73
 Configurable.h:74
 Configurable.h:75
 Configurable.h:76
 Configurable.h:77
 Configurable.h:78
 Configurable.h:79
 Configurable.h:80
 Configurable.h:81
 Configurable.h:82
 Configurable.h:83
 Configurable.h:84
 Configurable.h:85
 Configurable.h:86
 Configurable.h:87
 Configurable.h:88
 Configurable.h:89
 Configurable.h:90
 Configurable.h:91
 Configurable.h:92
 Configurable.h:93
 Configurable.h:94
 Configurable.h:95
 Configurable.h:96
 Configurable.h:97
 Configurable.h:98
 Configurable.h:99
 Configurable.h:100
 Configurable.h:101
 Configurable.h:102
 Configurable.h:103
 Configurable.h:104
 Configurable.h:105
 Configurable.h:106
 Configurable.h:107
 Configurable.h:108
 Configurable.h:109
 Configurable.h:110
 Configurable.h:111
 Configurable.h:112
 Configurable.h:113
 Configurable.h:114
 Configurable.h:115
 Configurable.h:116
 Configurable.h:117
 Configurable.h:118
 Configurable.h:119
 Configurable.h:120
 Configurable.h:121
 Configurable.h:122
 Configurable.h:123
 Configurable.h:124
 Configurable.h:125
 Configurable.h:126
 Configurable.h:127
 Configurable.h:128
 Configurable.h:129
 Configurable.h:130
 Configurable.h:131
 Configurable.h:132
 Configurable.h:133
 Configurable.h:134
 Configurable.h:135
 Configurable.h:136
 Configurable.h:137
 Configurable.h:138
 Configurable.h:139
 Configurable.h:140
 Configurable.h:141
 Configurable.h:142
 Configurable.h:143
 Configurable.h:144
 Configurable.h:145
 Configurable.h:146
 Configurable.h:147
 Configurable.h:148
 Configurable.h:149
 Configurable.h:150
 Configurable.h:151
 Configurable.h:152
 Configurable.h:153
 Configurable.h:154
 Configurable.h:155
 Configurable.h:156
 Configurable.h:157
 Configurable.h:158
 Configurable.h:159
 Configurable.h:160
 Configurable.h:161
 Configurable.h:162
 Configurable.h:163
 Configurable.h:164
 Configurable.h:165
 Configurable.h:166
 Configurable.h:167
 Configurable.h:168
 Configurable.h:169
 Configurable.h:170
 Configurable.h:171
 Configurable.h:172
 Configurable.h:173
 Configurable.h:174
 Configurable.h:175
 Configurable.h:176
 Configurable.h:177
 Configurable.h:178
 Configurable.h:179
 Configurable.h:180
 Configurable.h:181
 Configurable.h:182
 Configurable.h:183
 Configurable.h:184
 Configurable.h:185
 Configurable.h:186
 Configurable.h:187
 Configurable.h:188
 Configurable.h:189
 Configurable.h:190
 Configurable.h:191
 Configurable.h:192
 Configurable.h:193
 Configurable.h:194
 Configurable.h:195
 Configurable.h:196
 Configurable.h:197
 Configurable.h:198
 Configurable.h:199
 Configurable.h:200
 Configurable.h:201
 Configurable.h:202
 Configurable.h:203
 Configurable.h:204
 Configurable.h:205
 Configurable.h:206
 Configurable.h:207
 Configurable.h:208
 Configurable.h:209
 Configurable.h:210
 Configurable.h:211
 Configurable.h:212
 Configurable.h:213
 Configurable.h:214
 Configurable.h:215
 Configurable.h:216
 Configurable.h:217
 Configurable.h:218
 Configurable.h:219
 Configurable.h:220
 Configurable.h:221
 Configurable.h:222
 Configurable.h:223
 Configurable.h:224