/*
  Base Class for all classes that would like to habe option parsing enabled
*/
//End_Html
#include <string>
#include <fstream>
#include <stdlib.h>
#include "TROOT.h"
#include "TSystem.h"
#include "TObjString.h"
#include "TQObject.h"
#include "TSpline.h"
#include "TMatrix.h"
#include "TMath.h"
#include "TFile.h"
#include "TKey.h" 
#ifndef ROOT_TMVA_Configurable
#include "TMVA/Configurable.h"
#endif
ClassImp(TMVA::Configurable)
TMVA::Configurable::Configurable( const TString & theOption)  
   : fOptions                    ( theOption ),
     fLooseOptionCheckingEnabled ( kTRUE ),
     fLastDeclaredOption         ( 0 ),
     fLogger                     ( this )
{
   
}
TMVA::Configurable::~Configurable()
{
   
}
void TMVA::Configurable::SplitOptions(const TString& theOpt, TList& loo) const
{
   
   TString splitOpt(theOpt);
   while (splitOpt.Length()>0) {
      if ( ! splitOpt.Contains(':') ) {
         loo.Add(new TObjString(splitOpt));
         splitOpt = "";
      } 
      else {
         TString toSave = splitOpt(0,splitOpt.First(':'));
         loo.Add(new TObjString(toSave.Data()));
         splitOpt = splitOpt(splitOpt.First(':')+1,splitOpt.Length());
      }
   }
}
void TMVA::Configurable::ResetSetFlag() {
   
   
   TListIter decOptIt(&fListOfOptions); 
   while (OptionBase* decOpt = (OptionBase*) decOptIt()) { 
      decOpt->fIsSet = kFALSE;
   }
}
void TMVA::Configurable::ParseOptions( Bool_t verbose ) 
{
   
   if (verbose) {
      fLogger << kINFO << "Parsing option string: " << Endl;
      TString optionsWithoutTilde(fOptions);
      optionsWithoutTilde.ReplaceAll(TString("~"),TString(""));
      fLogger << kINFO << "\"" << optionsWithoutTilde << "\"" << Endl;
   }
   
   TList loo; 
   
   fOptions = fOptions.Strip(TString::kLeading, ':');
   
   
   SplitOptions(fOptions, loo);
   fOptions = "";
   
   std::map<TString, std::vector<std::pair<Int_t, TString> > > arrayTypeOptions;
   TListIter decOptIt(&fListOfOptions); 
   TListIter setOptIt(&loo);   
   while (TObjString * os = (TObjString*) setOptIt()) { 
      TString s = os->GetString();
      
      
      
      
      
      
      
      Bool_t preserveTilde = s.BeginsWith('~');
      s = s.Strip(TString::kLeading, '~');
      Bool_t paramParsed = kFALSE;
      if (s.Contains('=')) { 
         TString optname = s(0,s.First('=')); optname.ToLower(); 
         TString optval = s(s.First('=')+1,s.Length());
         Int_t idx = -1;
         
         if (optname.Contains('[')) {
            TString s = optname(optname.First('[')+1,100);
            s.Remove(s.First(']'));
            std::stringstream str(s.Data());
            str >> idx;                              
            optname.Remove(optname.First('['));      
         }
         OptionBase * decOpt = (OptionBase *)fListOfOptions.FindObject(optname);
         TListIter optIt(&fListOfOptions);
         if (decOpt!=0) {
            if (decOpt->IsSet())
               fLogger << kWARNING << "Value for option " << decOpt->GetName() 
                       << " was previously set to " << decOpt->GetValue() << Endl;
            if (!decOpt->HasPreDefinedVal() || (decOpt->HasPreDefinedVal() && decOpt->IsPreDefinedVal(optval)) ) {
               if (decOpt->IsArrayOpt()) {
                  
                  if (idx==-1) {
                     decOpt->SetValue(optval);
                  } 
                  else {
                     
                     if (!decOpt->SetValue(optval, idx))
                        fLogger << kFATAL << "Index " << idx << " too large for option " << decOpt->TheName()
                                << ", allowed range is [0," << decOpt->GetArraySize()-1 << "]" << Endl;
                  }
               } 
               else {
                  if (idx!=-1) 
                     fLogger << kFATAL << "Option " << decOpt->TheName()
                             << " is not an array, but you specified an index" << Endl;
                  decOpt->SetValue(optval);
               }
               paramParsed = kTRUE;
            }
            else fLogger << kFATAL << "Option " << decOpt->TheName() 
                         << " has no predefined value " << optval << Endl;               
         }
      }
      
      
      Bool_t preserveNotSign = kFALSE;
      if (!paramParsed) {
         Bool_t hasNotSign = kFALSE;
         if (s.BeginsWith("!")) { s.Remove(0,1); preserveNotSign = hasNotSign = kTRUE; }
         TString optname(s); optname.ToLower();
         OptionBase* decOpt = 0;
         Bool_t optionExists = kFALSE;
         TListIter optIt(&fListOfOptions);
         while ( (decOpt = (OptionBase*)optIt()) !=0) {
            TString predOptName(decOpt->GetName());
            predOptName.ToLower();
            if (predOptName == optname) optionExists = kTRUE;
            if (dynamic_cast<Option<bool>*>(decOpt)==0) continue; 
            if (predOptName == optname) break;
         }
        
         if (decOpt != 0) {
            decOpt->SetValue( hasNotSign ? "0" : "1" );
            paramParsed = kTRUE;
         } else {
            if (optionExists && hasNotSign) {
               fLogger << kFATAL << "Negating a non-boolean variable " << optname
                       << ", please check the opions for method " << GetName() << Endl;
            }
         }
      }
      if (!paramParsed && LooseOptionCheckingEnabled()) {
         
         
         decOptIt.Reset();
         while (OptionBase* decOpt = (OptionBase*) decOptIt()) {
            if (decOpt->HasPreDefinedVal() && decOpt->IsPreDefinedVal(s) ) {
               paramParsed = decOpt->SetValue(s);
               break;
            }
         }
      }
   
      if(fOptions!="") fOptions += ":";
      if(paramParsed || preserveTilde) fOptions += '~';
      if(paramParsed || preserveNotSign) fOptions += '!';
      fOptions += s;
   }
   if (verbose) PrintOptions();
}
void TMVA::Configurable::CheckForUnusedOptions() const 
{
   
   TString theOpt(fOptions);
   theOpt = theOpt.Strip(TString::kLeading, ':');
   
   
   TList loo; 
   SplitOptions(theOpt, loo);
   TListIter setOptIt(&loo);   
   TString unusedOptions("");
   while (TObjString * os = (TObjString*) setOptIt()) { 
      TString s = os->GetString();
      if( !s.BeginsWith('~') ) {
         if(unusedOptions!="") unusedOptions += ':';
         unusedOptions += s;
      }
   }
   if(unusedOptions!="")
      fLogger << kFATAL
              << "The following options were specified, but could not be interpreted: \'"
              << unusedOptions << "\', please check!" << Endl;
}
void TMVA::Configurable::PrintOptions() const 
{
   
   fLogger << kINFO << "The following options are set:" << Endl;
   TListIter optIt( & fListOfOptions );
   fLogger << kINFO << "- By User:" << Endl;
   Bool_t found = kFALSE;
   while (OptionBase* opt = (OptionBase *) optIt()) {
      if (opt->IsSet()) { fLogger << kINFO << "    "; opt->Print(fLogger); fLogger << Endl; found = kTRUE; }
   }
   if (!found) fLogger << kINFO << "    <none>" << Endl;
   optIt.Reset();
   fLogger << kINFO << "- Default:" << Endl;
   found = kFALSE;
   while (OptionBase* opt = (OptionBase *) optIt()) {
      if (!opt->IsSet()) { fLogger << kINFO << "    "; opt->Print(fLogger); fLogger << Endl; found = kTRUE; }
   }
   if (!found) fLogger << kINFO << "    <none>" << Endl;
}
void TMVA::Configurable::WriteOptionsToStream( ostream& o, const TString& prefix ) const 
{
   
   TListIter optIt( &fListOfOptions );
   o << prefix << "# Set by User:" << endl;
   while (OptionBase * opt = (OptionBase *) optIt()) 
      if (opt->IsSet()) { o << prefix; opt->Print(o); o << endl; }
   optIt.Reset();
   o << prefix << "# Default:" << endl;
   while (OptionBase * opt = (OptionBase *) optIt()) 
      if (!opt->IsSet()) { o << prefix; opt->Print(o); o << endl; }
   o << prefix << "##" << endl;
}
void TMVA::Configurable::ReadOptionsFromStream(istream& istr)
{
   
   
   
   
   ResetSetFlag();
   fOptions = "";
   char buf[512];
   istr.getline(buf,512);
   TString stropt, strval;
   while (istr.good() && !istr.eof() && !(buf[0]=='#' && buf[1]=='#')) { 
      char *p = buf;
      while (*p==' ' || *p=='\t') p++; 
      if (*p=='#' || *p=='\0') {
         istr.getline(buf,512); 
         continue; 
      }
      std::stringstream sstr(buf);
      sstr >> stropt >> strval;
      stropt.ReplaceAll(':','=');
      strval.ReplaceAll("\"","");
      if (fOptions.Length()!=0) fOptions += ":";
      fOptions += stropt;
      fOptions += strval;
      istr.getline(buf,512); 
   }
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.