#include <string>
#include <iostream>
#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"
#include "TMVA/Configurable.h"
#include "TMVA/Config.h"
using std::endl;
ClassImp(TMVA::Configurable)
#ifdef _WIN32
#pragma warning ( disable : 4355 )
#endif
TMVA::Configurable::Configurable( const TString& theOption)
: fOptions ( theOption ),
fLooseOptionCheckingEnabled ( kTRUE ),
fLastDeclaredOption ( 0 ),
fConfigName ( "Configurable" ),
fConfigDescription ( "No description" ),
fReferenceFile ( "None" ),
fLogger ( this )
{
fListOfOptions.SetOwner();
}
TMVA::Configurable::~Configurable()
{
}
void TMVA::Configurable::SplitOptions(const TString& theOpt, TList& loo) const
{
TString splitOpt(theOpt);
loo.SetOwner();
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 sp = optname(optname.First('[')+1,100);
sp.Remove(sp.First(']'));
std::stringstream str(sp.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()
<< " does not have 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();
if (gConfig().WriteOptionsReference()) WriteOptionsReferenceToFile();
}
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::WriteOptionsReferenceToFile()
{
TString dir = gConfig().GetIONames().fOptionsReferenceFileDir;
gSystem->MakeDirectory( dir );
fReferenceFile = dir + "/" + GetConfigName() + "_optionsRef.txt";
std::ofstream o( fReferenceFile );
if (!o.good()) {
fLogger << kFATAL << "<WriteOptionsToInfoFile> Unable to open output file: " << fReferenceFile << Endl;
}
TListIter optIt( &fListOfOptions );
o << "# List of options:" << endl;
o << "# Configurable: " << GetConfigName() << endl;
o << "# Description: " << GetConfigDescription() << endl;
while (OptionBase * opt = (OptionBase *) optIt()) {
opt->Print( o, 1 );
o << endl << "# ------------------------------------------------" << endl;
}
o.close();
fLogger << kINFO << "Wrote options reference file: \"" << fReferenceFile << "\"" << 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);
}
}
Last change: Sat Nov 1 10:21:32 2008
Last generated: 2008-11-01 10:21
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.