// @(#)root/tmva $Id$
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Eckhard von Toerne, Jan Therhaag

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : Reader                                                                *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Reader class to be used in the user application to interpret the trained  *
 *      MVAs in an analysis context                                               *
 *                                                                                *
 * Authors (alphabetical order):                                                  *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Peter Speckmayer <peter.speckmayer@cern.ch> - CERN, Switzerland           *
 *      Joerg Stelzer <Joerg.Stelzer@cern.ch>    - CERN, Switzerland              *
 *      Jan Therhaag       <Jan.Therhaag@cern.ch>     - U of Bonn, Germany        *
 *      Eckhard v. Toerne  <evt@uni-bonn.de>          - U of Bonn, Germany        *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *      Kai Voss        <Kai.Voss@cern.ch>       - U. of Victoria, Canada         *
 *                                                                                *
 * Copyright (c) 2005-2011:                                                       *
 *      CERN, Switzerland                                                         *
 *      U. of Victoria, Canada                                                    *
 *      MPI-K Heidelberg, Germany                                                 *
 *      U. of Bonn, Germany                                                       *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://ttmva.sourceforge.net/LICENSE)                                         *
 **********************************************************************************/

//_______________________________________________________________________
//
//  The Reader class serves to use the MVAs in a specific analysis context.
//  Within an event loop, a vector is filled that corresponds to the variables
//  that were used to train the MVA(s) during the training stage. This vector
//  is transfered to the Reader, who takes care of interpreting the weight
//  file of the MVA of choice, and to return the MVA's output. This is then
//  used by the user for further analysis.
//
//  ---------------------------------------------------------------------
//  Usage:
//
//    // ------ before starting the event loop (eg, in the initialisation step)
//
//    //
//    // create TMVA::Reader object
//    //
//    TMVA::Reader *reader = new TMVA::Reader();
//
//    // create a set of variables and declare them to the reader
//    // - the variable names must corresponds in name and type to
//    // those given in the weight file(s) that you use
//    Float_t var1, var2, var3, var4;
//    reader->AddVariable( "var1", &var1 );
//    reader->AddVariable( "var2", &var2 );
//    reader->AddVariable( "var3", &var3 );
//    reader->AddVariable( "var4", &var4 );
//
//    // book the MVA of your choice (prior training of these methods, ie,
//    // existence of the weight files is required)
//    reader->BookMVA( "Fisher method",  "weights/Fisher.weights.txt"   );
//    reader->BookMVA( "MLP method",     "weights/MLP.weights.txt" );
//    // ... etc
//
//    // ------- start your event loop
//
//    for (Long64_t ievt=0; ievt<myTree->GetEntries();ievt++) {
//
//      // fill vector with values of variables computed from those in the tree
//      var1 = myvar1;
//      var2 = myvar2;
//      var3 = myvar3;
//      var4 = myvar4;
//
//      // retrieve the corresponding MVA output
//      double mvaFi = reader->EvaluateMVA( "Fisher method" );
//      double mvaNN = reader->EvaluateMVA( "MLP method"    );
//
//      // do something with these ...., e.g., fill them into your ntuple
//
//    } // end of event loop
//
//    delete reader;
//  ---------------------------------------------------------------------
//
//  An example application of the Reader can be found in TMVA/macros/TMVApplication.C.
//_______________________________________________________________________

#include "TMVA/Reader.h"

#include "TTree.h"
#include "TLeaf.h"
#include "TString.h"
#include "TClass.h"
#include "TH1D.h"
#include "TKey.h"
#include "TVector.h"
#include "TXMLEngine.h"
#include "TMath.h"

#include <cstdlib>

#include <string>
#include <vector>
#include <fstream>

#include <iostream>
#ifndef ROOT_TMVA_Tools
#include "TMVA/Tools.h"
#endif
#include "TMVA/Config.h"
#include "TMVA/ClassifierFactory.h"
#include "TMVA/IMethod.h"
#include "TMVA/MethodCuts.h"
#include "TMVA/MethodCategory.h"
#include "TMVA/DataSetManager.h"

ClassImp(TMVA::Reader)

//_______________________________________________________________________
TMVA::Reader::Reader( const TString& theOption, Bool_t verbose )
   : Configurable( theOption ),
     fDataSetManager( NULL ), // DSMTEST
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fCalculateError(kFALSE),
     fMvaEventError( 0 ),
     fMvaEventErrorUpper( 0 ),
     fLogger ( 0 )
{
   // constructor
   fDataSetManager = new DataSetManager( fDataInputHandler ); 
   fDataSetManager->AddDataSetInfo(fDataSetInfo); 
   fLogger = new MsgLogger(this);
   SetConfigName( GetName() );
   DeclareOptions();
   ParseOptions();

   Init();
}

//_______________________________________________________________________
TMVA::Reader::Reader( std::vector<TString>& inputVars, const TString& theOption, Bool_t verbose )
   : Configurable( theOption ),
     fDataSetManager( NULL ), // DSMTEST
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fCalculateError(kFALSE),
     fMvaEventError( 0 ),
     fMvaEventErrorUpper( 0 ),   //zjh
     fLogger ( 0 )
{
   // constructor

   fDataSetManager = new DataSetManager( fDataInputHandler ); 
   fDataSetManager->AddDataSetInfo(fDataSetInfo); 
   fLogger = new MsgLogger(this);
   SetConfigName( GetName() );
   DeclareOptions();
   ParseOptions();

   // arguments: names of input variables (vector)
   //            verbose flag
   for (std::vector<TString>::iterator ivar = inputVars.begin(); ivar != inputVars.end(); ivar++) 
      DataInfo().AddVariable( *ivar );

   Init();
}

//_______________________________________________________________________
TMVA::Reader::Reader( std::vector<std::string>& inputVars, const TString& theOption, Bool_t verbose )
   : Configurable( theOption ),
     fDataSetManager( NULL ), // DSMTEST
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fCalculateError(kFALSE),
     fMvaEventError( 0 ),
     fMvaEventErrorUpper( 0 ),
     fLogger ( 0 )
{
   // constructor
   fDataSetManager = new DataSetManager( fDataInputHandler ); 
   fDataSetManager->AddDataSetInfo(fDataSetInfo); 
   fLogger = new MsgLogger(this);
   SetConfigName( GetName() );
   DeclareOptions();
   ParseOptions();

   // arguments: names of input variables (vector)
   //            verbose flag
   for (std::vector<std::string>::iterator ivar = inputVars.begin(); ivar != inputVars.end(); ivar++) 
      DataInfo().AddVariable( ivar->c_str() );

   Init();
}

//_______________________________________________________________________
TMVA::Reader::Reader( const std::string& varNames, const TString& theOption, Bool_t verbose )
   : Configurable( theOption ),
     fDataSetManager( NULL ), // DSMTEST
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fCalculateError(kFALSE),
     fMvaEventError( 0 ),
     fMvaEventErrorUpper( 0 ),
     fLogger ( 0 )
{
   // constructor
   fDataSetManager = new DataSetManager( fDataInputHandler ); 
   fDataSetManager->AddDataSetInfo(fDataSetInfo); 
   fLogger = new MsgLogger(this);
   SetConfigName( GetName() );
   DeclareOptions();
   ParseOptions();

   // arguments: names of input variables given in form: "name1:name2:name3"
   //            verbose flag
   DecodeVarNames(varNames);
   Init();
}

//_______________________________________________________________________
TMVA::Reader::Reader( const TString& varNames, const TString& theOption, Bool_t verbose )
   : Configurable( theOption ),
     fDataSetManager( NULL ), // DSMTEST
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fCalculateError(kFALSE),
     fMvaEventError( 0 ),
     fMvaEventErrorUpper( 0 ),
     fLogger ( 0 )
{
   // constructor
   fDataSetManager = new DataSetManager( fDataInputHandler ); 
   fDataSetManager->AddDataSetInfo(fDataSetInfo); 
   fLogger = new MsgLogger(this);
   SetConfigName( GetName() );
   DeclareOptions();
   ParseOptions();

   // arguments: names of input variables given in form: "name1:name2:name3"
   //            verbose flag
   DecodeVarNames(varNames);
   Init();
}

//_______________________________________________________________________
void TMVA::Reader::DeclareOptions()
{
   // declaration of configuration options
   if (gTools().CheckForSilentOption( GetOptions() )) Log().InhibitOutput(); // make sure is silent if wanted to

   DeclareOptionRef( fVerbose,        "V",      "Verbose flag" );
   DeclareOptionRef( fColor,          "Color",  "Color flag (default True)" );
   DeclareOptionRef( fSilent,         "Silent", "Boolean silent flag (default False)" );
   DeclareOptionRef( fCalculateError, "Error",  "Calculates errors (default False)" );
}

//_______________________________________________________________________
TMVA::Reader::~Reader( void )
{
   // destructor

   delete fDataSetManager; // DSMTEST

   delete fLogger;
}

//_______________________________________________________________________
void TMVA::Reader::Init( void )
{
   // default initialisation (no member variables)
   // default initialisation (no member variables)
   if (Verbose()) fLogger->SetMinType( kVERBOSE );

   gConfig().SetUseColor( fColor );
   gConfig().SetSilent  ( fSilent );
}

//_______________________________________________________________________
void TMVA::Reader::AddVariable( const TString& expression, Float_t* datalink )
{
   // Add a float variable or expression to the reader
   DataInfo().AddVariable( expression, "", "", 0, 0, 'F', kFALSE ,(void*)datalink ); // <= should this be F or rather T?
}

//_______________________________________________________________________
void TMVA::Reader::AddVariable( const TString& expression, Int_t* datalink )
{
   Log() << kFATAL << "Reader::AddVariable( const TString& expression, Int_t* datalink ), this function is deprecated, please provide all variables to the reader as floats" << Endl;
   // Add an integer variable or expression to the reader
   Log() << kFATAL << "Reader::AddVariable( const TString& expression, Int_t* datalink ), this function is deprecated, please provide all variables to the reader as floats" << Endl;
   DataInfo().AddVariable(expression, "", "", 0, 0, 'I', kFALSE, (void*)datalink ); // <= should this be F or rather T?
}

//_______________________________________________________________________
void TMVA::Reader::AddSpectator( const TString& expression, Float_t* datalink )
{
   // Add a float spectator or expression to the reader
   DataInfo().AddSpectator( expression, "", "", 0, 0, 'F', kFALSE ,(void*)datalink );
}

//_______________________________________________________________________
void TMVA::Reader::AddSpectator( const TString& expression, Int_t* datalink )
{
   // Add an integer spectator or expression to the reader
   DataInfo().AddSpectator(expression, "", "", 0, 0, 'I', kFALSE, (void*)datalink );
}

//_______________________________________________________________________
TString TMVA::Reader::GetMethodTypeFromFile( const TString& filename ) 
{
   // read the method type from the file

   std::ifstream fin( filename );
   if (!fin.good()) { // file not found --> Error
      Log() << kFATAL << "<BookMVA> fatal error: "
            << "unable to open input weight file: " << filename << Endl;
   }

   TString fullMethodName("");
   if (filename.EndsWith(".xml")) {
      fin.close();
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,29,0)
      void* doc      = gTools().xmlengine().ParseFile(filename,gTools().xmlenginebuffersize());// the default buffer size in TXMLEngine::ParseFile is 100k. Starting with ROOT 5.29 one can set the buffer size, see: http://savannah.cern.ch/bugs/?78864. This might be necessary for large XML files
#else
      void* doc      = gTools().xmlengine().ParseFile(filename);
#endif
      void* rootnode = gTools().xmlengine().DocGetRootElement(doc); // node "MethodSetup"
      gTools().ReadAttr(rootnode, "Method", fullMethodName);
      gTools().xmlengine().FreeDoc(doc);
   } 
   else {
      char buf[512];
      fin.getline(buf,512);
      while (!TString(buf).BeginsWith("Method")) fin.getline(buf,512);
      fullMethodName = TString(buf);
      fin.close();
   }
   TString methodType = fullMethodName(0,fullMethodName.Index("::"));
   if (methodType.Contains(" ")) methodType = methodType(methodType.Last(' ')+1,methodType.Length());
   return methodType;
}

//_______________________________________________________________________
TMVA::IMethod* TMVA::Reader::BookMVA( const TString& methodTag, const TString& weightfile )
{
   // read method name from weight file

   // assert non-existence
   if (fMethodMap.find( methodTag ) != fMethodMap.end())
      Log() << kFATAL << "<BookMVA> method tag \"" << methodTag << "\" already exists!" << Endl;

   TString methodType(GetMethodTypeFromFile(weightfile));

   Log() << kINFO << "Booking \"" << methodTag << "\" of type \"" << methodType << "\" from " << weightfile << "." << Endl;

   MethodBase* method = dynamic_cast<MethodBase*>(this->BookMVA( Types::Instance().GetMethodType(methodType),
                                                                 weightfile ) );
   if( method && method->GetMethodType() == Types::kCategory ){
      MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
      if( !methCat )
         Log() << kFATAL << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
      methCat->fDataSetManager = fDataSetManager;
   }

   return fMethodMap[methodTag] = method;
}

//_______________________________________________________________________
TMVA::IMethod* TMVA::Reader::BookMVA( TMVA::Types::EMVA methodType, const TString& weightfile )
{
   // books MVA method from weightfile
   IMethod* im = ClassifierFactory::Instance().Create(std::string(Types::Instance().GetMethodName( methodType )),
                                                      DataInfo(), weightfile );

   MethodBase *method = (dynamic_cast<MethodBase*>(im));

   if (method==0) return im;

   if( method->GetMethodType() == Types::kCategory ){
      MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
      if( !methCat )
         Log() << kERROR << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
      methCat->fDataSetManager = fDataSetManager;
   }

   method->SetupMethod();

   // when reading older weight files, they could include options
   // that are not supported any longer
   method->DeclareCompatibilityOptions();

   // read weight file
   method->ReadStateFromFile();

   // check for unused options
   method->CheckSetup();

   Log() << kINFO << "Booked classifier \"" << method->GetMethodName()
         << "\" of type: \"" << method->GetMethodTypeName() << "\"" << Endl;

   return method;
}

//_______________________________________________________________________
TMVA::IMethod* TMVA::Reader::BookMVA( TMVA::Types::EMVA methodType, const char* xmlstr )
{

#if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)

   // books MVA method from weightfile
   IMethod* im = ClassifierFactory::Instance().Create(std::string(Types::Instance().GetMethodName( methodType )),
                                                      DataInfo(), "" );

   MethodBase *method = (dynamic_cast<MethodBase*>(im));

   if(!method) return 0;

   if( method->GetMethodType() == Types::kCategory ){ 
      MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method)); 
      if( !methCat ) 
         Log() << kFATAL << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl; 
      methCat->fDataSetManager = fDataSetManager; 
   }

   method->SetupMethod();

   // when reading older weight files, they could include options
   // that are not supported any longer
   method->DeclareCompatibilityOptions();

   // read weight file
   method->ReadStateFromXMLString( xmlstr );

   // check for unused options
   method->CheckSetup();

   Log() << kINFO << "Booked classifier \"" << method->GetMethodName()
         << "\" of type: \"" << method->GetMethodTypeName() << "\"" << Endl;

   return method;
#else
   Log() << kFATAL << "Method Reader::BookMVA(TMVA::Types::EMVA methodType = " << methodType 
         << ", const char* xmlstr = " << xmlstr 
         << " ) is not available for ROOT versions prior to 5.26/00." << Endl;
   return 0;
#endif
}

//_______________________________________________________________________
Double_t TMVA::Reader::EvaluateMVA( const std::vector<Float_t>& inputVec, const TString& methodTag, Double_t aux )
{
   // Evaluate a std::vector<float> of input data for a given method
   // The parameter aux is obligatory for the cuts method where it represents the efficiency cutoff

   // create a temporary event from the vector.
   IMethod* imeth = FindMVA( methodTag );
   MethodBase* meth = dynamic_cast<TMVA::MethodBase*>(imeth);
   if(meth==0) return 0;

//   Event* tmpEvent=new Event(inputVec, 2); // ToDo resolve magic 2 issue
   Event* tmpEvent=new Event(inputVec, DataInfo().GetNVariables()); // is this the solution?
   for (UInt_t i=0; i<inputVec.size(); i++){
     if (TMath::IsNaN(inputVec[i])) {
       Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
       delete tmpEvent;
       return -999;
     }
   }

   if (meth->GetMethodType() == TMVA::Types::kCuts) {
      TMVA::MethodCuts* mc = dynamic_cast<TMVA::MethodCuts*>(meth);
      if(mc)
         mc->SetTestSignalEfficiency( aux );
   }
   Double_t val = meth->GetMvaValue( tmpEvent, (fCalculateError?&fMvaEventError:0));
   delete tmpEvent;
   return val;
}

//_______________________________________________________________________
Double_t TMVA::Reader::EvaluateMVA( const std::vector<Double_t>& inputVec, const TString& methodTag, Double_t aux )
{
   // Evaluate a std::vector<double> of input data for a given method
   // The parameter aux is obligatory for the cuts method where it represents the efficiency cutoff

   // performs a copy to float values which are internally used by all methods
   if(fTmpEvalVec.size() != inputVec.size())
      fTmpEvalVec.resize(inputVec.size());

   for (UInt_t idx=0; idx!=inputVec.size(); idx++ )
      fTmpEvalVec[idx]=inputVec[idx];

   return EvaluateMVA( fTmpEvalVec, methodTag, aux );
}

//_______________________________________________________________________
Double_t TMVA::Reader::EvaluateMVA( const TString& methodTag, Double_t aux )
{
   // evaluates MVA for given set of input variables
   IMethod* method = 0;

   std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
   if (it == fMethodMap.end()) {
      Log() << kINFO << "<EvaluateMVA> unknown classifier in map; "
              << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
      for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
      Log() << "Check calling string" << kFATAL << Endl;
   }

   else method = it->second;

   MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);

   if(kl==0)
      Log() << kFATAL << methodTag << " is not a method" << Endl;

   // check for NaN in event data:  (note: in the factory, this check was done already at the creation of the datasets, hence
   // it is not again checked in each of these subsequet calls..
   const Event* ev = kl->GetEvent();
   for (UInt_t i=0; i<ev->GetNVariables(); i++){
     if (TMath::IsNaN(ev->GetValue(i))) {
       Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
       return -999;
     }
   }
   return this->EvaluateMVA( kl, aux );
}

//_______________________________________________________________________
Double_t TMVA::Reader::EvaluateMVA( MethodBase* method, Double_t aux )
{
   // evaluates the MVA

   // the aux value is only needed for MethodCuts: it sets the
   // required signal efficiency
   if (method->GetMethodType() == TMVA::Types::kCuts) {
      TMVA::MethodCuts* mc = dynamic_cast<TMVA::MethodCuts*>(method);
      if(mc)
         mc->SetTestSignalEfficiency( aux );
   }

   return method->GetMvaValue( (fCalculateError?&fMvaEventError:0),
                               (fCalculateError?&fMvaEventErrorUpper:0) );
}

//_______________________________________________________________________
const std::vector< Float_t >& TMVA::Reader::EvaluateRegression( const TString& methodTag, Double_t aux )
{
   // evaluates MVA for given set of input variables
   IMethod* method = 0;

   std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
   if (it == fMethodMap.end()) {
      Log() << kINFO << "<EvaluateMVA> unknown method in map; "
              << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
      for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
      Log() << "Check calling string" << kFATAL << Endl;
   }
   else method = it->second;

   MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);

   if(kl==0)
      Log() << kFATAL << methodTag << " is not a method" << Endl;
   // check for NaN in event data:  (note: in the factory, this check was done already at the creation of the datasets, hence
   // it is not again checked in each of these subsequet calls..
   const Event* ev = kl->GetEvent();
   for (UInt_t i=0; i<ev->GetNVariables(); i++){
     if (TMath::IsNaN(ev->GetValue(i))) {
       Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
     }
   }

   return this->EvaluateRegression( kl, aux );
}

//_______________________________________________________________________
const std::vector< Float_t >& TMVA::Reader::EvaluateRegression( MethodBase* method, Double_t /*aux*/ )
{
   // evaluates the regression MVA
   // check for NaN in event data:  (note: in the factory, this check was done already at the creation of the datasets, hence
   // it is not again checked in each of these subsequet calls..
   const Event* ev = method->GetEvent();
   for (UInt_t i=0; i<ev->GetNVariables(); i++){
     if (TMath::IsNaN(ev->GetValue(i))) {
       Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
     }
   }
   return method->GetRegressionValues();
}


//_______________________________________________________________________
Float_t TMVA::Reader::EvaluateRegression( UInt_t tgtNumber, const TString& methodTag, Double_t aux )
{ 
   // evaluates the regression MVA
   try {
      return EvaluateRegression(methodTag, aux).at(tgtNumber); 
   }
   catch (std::out_of_range e) {
      Log() << kWARNING << "Regression could not be evaluated for target-number " << tgtNumber << Endl;
      return 0;
   }
}



//_______________________________________________________________________
const std::vector< Float_t >& TMVA::Reader::EvaluateMulticlass( const TString& methodTag, Double_t aux )
{
   // evaluates MVA for given set of input variables
   IMethod* method = 0;

   std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
   if (it == fMethodMap.end()) {
      Log() << kINFO << "<EvaluateMVA> unknown method in map; "
              << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
      for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
      Log() << "Check calling string" << kFATAL << Endl;
   }
   else method = it->second;

   MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);

   if(kl==0)
      Log() << kFATAL << methodTag << " is not a method" << Endl;
   // check for NaN in event data:  (note: in the factory, this check was done already at the creation of the datasets, hence
   // it is not again checked in each of these subsequet calls..

   const Event* ev = kl->GetEvent();
   for (UInt_t i=0; i<ev->GetNVariables(); i++){
     if (TMath::IsNaN(ev->GetValue(i))) {
       Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
     }
   }

   return this->EvaluateMulticlass( kl, aux );
}

//_______________________________________________________________________
const std::vector< Float_t >& TMVA::Reader::EvaluateMulticlass( MethodBase* method, Double_t /*aux*/ )
{
   // evaluates the multiclass MVA
   // check for NaN in event data:  (note: in the factory, this check was done already at the creation of the datasets, hence
   // it is not again checked in each of these subsequet calls..
   const Event* ev = method->GetEvent();
   for (UInt_t i=0; i<ev->GetNVariables(); i++){
     if (TMath::IsNaN(ev->GetValue(i))) {
       Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
     }
   }
   return method->GetMulticlassValues();
}


//_______________________________________________________________________
Float_t TMVA::Reader::EvaluateMulticlass( UInt_t clsNumber, const TString& methodTag, Double_t aux )
{ 
   // evaluates the multiclass MVA
   try {
      return EvaluateMulticlass(methodTag, aux).at(clsNumber); 
   }
   catch (std::out_of_range e) {
      Log() << kWARNING << "Multiclass could not be evaluated for class-number " << clsNumber << Endl;
      return 0;
   }
}


//_______________________________________________________________________
TMVA::IMethod* TMVA::Reader::FindMVA( const TString& methodTag )
{
   // return pointer to method with tag "methodTag"
   std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
   if (it != fMethodMap.end()) return it->second;
   Log() << kERROR << "Method " << methodTag << " not found!" << Endl;
   return 0;
}

//_______________________________________________________________________
TMVA::MethodCuts* TMVA::Reader::FindCutsMVA( const TString& methodTag )
{
   // special function for Cuts to avoid dynamic_casts in ROOT macros,
   // which are not properly handled by CINT
   return dynamic_cast<MethodCuts*>(FindMVA(methodTag));
}

//_______________________________________________________________________
Double_t TMVA::Reader::GetProba( const TString& methodTag,  Double_t ap_sig, Double_t mvaVal )
{
   // evaluates probability of MVA for given set of input variables
   IMethod* method = 0;
   std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
   if (it == fMethodMap.end()) {
      for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << "M" << it->first << Endl;
      Log() << kFATAL << "<EvaluateMVA> unknown classifier in map: " << method << "; "
              << "you looked for " << methodTag<< " while the available methods are : " << Endl;
   }
   else method = it->second;

   MethodBase* kl = dynamic_cast<MethodBase*>(method);
   if(kl==0) return -1;
   // check for NaN in event data:  (note: in the factory, this check was done already at the creation of the datasets, hence
   // it is not again checked in each of these subsequet calls..
   const Event* ev = kl->GetEvent();
   for (UInt_t i=0; i<ev->GetNVariables(); i++){
     if (TMath::IsNaN(ev->GetValue(i))) {
       Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
       return -999;
     }
   }

   if (mvaVal == -9999999) mvaVal = kl->GetMvaValue();

   return kl->GetProba( mvaVal, ap_sig );
}

//_______________________________________________________________________
Double_t TMVA::Reader::GetRarity( const TString& methodTag, Double_t mvaVal )
{
   // evaluates the MVA's rarity
   IMethod* method = 0;
   std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
   if (it == fMethodMap.end()) {
      for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << "M" << it->first << Endl;
      Log() << kFATAL << "<EvaluateMVA> unknown classifier in map: \"" << method << "\"; "
              << "you looked for \"" << methodTag<< "\" while the available methods are : " << Endl;
   }
   else method = it->second;

   MethodBase* kl = dynamic_cast<MethodBase*>(method);
   if(kl==0) return -1;
   // check for NaN in event data:  (note: in the factory, this check was done already at the creation of the datasets, hence
   // it is not again checked in each of these subsequet calls..
   const Event* ev = kl->GetEvent();
   for (UInt_t i=0; i<ev->GetNVariables(); i++){
     if (TMath::IsNaN(ev->GetValue(i))) {
       Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
       return -999;
     }
   }

   if (mvaVal == -9999999) mvaVal = kl->GetMvaValue();

   return kl->GetRarity( mvaVal );
}

// ---------------------------------------------------------------------------------------
// ----- methods related to the decoding of the input variable names ---------------------
// ---------------------------------------------------------------------------------------

//_______________________________________________________________________
void TMVA::Reader::DecodeVarNames( const std::string& varNames )
{
   // decodes "name1:name2:..." form
   size_t ipos = 0, f = 0;
   while (f != varNames.length()) {
      f = varNames.find( ':', ipos );
      if (f > varNames.length()) f = varNames.length();
      std::string subs = varNames.substr( ipos, f-ipos ); ipos = f+1;
      DataInfo().AddVariable( subs.c_str() );
   }
}

//_______________________________________________________________________
void TMVA::Reader::DecodeVarNames( const TString& varNames )
{
   // decodes "name1:name2:..." form

   TString format;
   Int_t   n = varNames.Length();
   TString format_obj;

   for (int i=0; i< n+1 ; i++) {
      format.Append(varNames(i));
      if (varNames(i) == ':' || i == n) {
         format.Chop();
         format_obj = format;
         format_obj.ReplaceAll("@","");
         DataInfo().AddVariable( format_obj );
         format.Resize(0);
      }
   }
}
 Reader.cxx:1
 Reader.cxx:2
 Reader.cxx:3
 Reader.cxx:4
 Reader.cxx:5
 Reader.cxx:6
 Reader.cxx:7
 Reader.cxx:8
 Reader.cxx:9
 Reader.cxx:10
 Reader.cxx:11
 Reader.cxx:12
 Reader.cxx:13
 Reader.cxx:14
 Reader.cxx:15
 Reader.cxx:16
 Reader.cxx:17
 Reader.cxx:18
 Reader.cxx:19
 Reader.cxx:20
 Reader.cxx:21
 Reader.cxx:22
 Reader.cxx:23
 Reader.cxx:24
 Reader.cxx:25
 Reader.cxx:26
 Reader.cxx:27
 Reader.cxx:28
 Reader.cxx:29
 Reader.cxx:30
 Reader.cxx:31
 Reader.cxx:32
 Reader.cxx:33
 Reader.cxx:34
 Reader.cxx:35
 Reader.cxx:36
 Reader.cxx:37
 Reader.cxx:38
 Reader.cxx:39
 Reader.cxx:40
 Reader.cxx:41
 Reader.cxx:42
 Reader.cxx:43
 Reader.cxx:44
 Reader.cxx:45
 Reader.cxx:46
 Reader.cxx:47
 Reader.cxx:48
 Reader.cxx:49
 Reader.cxx:50
 Reader.cxx:51
 Reader.cxx:52
 Reader.cxx:53
 Reader.cxx:54
 Reader.cxx:55
 Reader.cxx:56
 Reader.cxx:57
 Reader.cxx:58
 Reader.cxx:59
 Reader.cxx:60
 Reader.cxx:61
 Reader.cxx:62
 Reader.cxx:63
 Reader.cxx:64
 Reader.cxx:65
 Reader.cxx:66
 Reader.cxx:67
 Reader.cxx:68
 Reader.cxx:69
 Reader.cxx:70
 Reader.cxx:71
 Reader.cxx:72
 Reader.cxx:73
 Reader.cxx:74
 Reader.cxx:75
 Reader.cxx:76
 Reader.cxx:77
 Reader.cxx:78
 Reader.cxx:79
 Reader.cxx:80
 Reader.cxx:81
 Reader.cxx:82
 Reader.cxx:83
 Reader.cxx:84
 Reader.cxx:85
 Reader.cxx:86
 Reader.cxx:87
 Reader.cxx:88
 Reader.cxx:89
 Reader.cxx:90
 Reader.cxx:91
 Reader.cxx:92
 Reader.cxx:93
 Reader.cxx:94
 Reader.cxx:95
 Reader.cxx:96
 Reader.cxx:97
 Reader.cxx:98
 Reader.cxx:99
 Reader.cxx:100
 Reader.cxx:101
 Reader.cxx:102
 Reader.cxx:103
 Reader.cxx:104
 Reader.cxx:105
 Reader.cxx:106
 Reader.cxx:107
 Reader.cxx:108
 Reader.cxx:109
 Reader.cxx:110
 Reader.cxx:111
 Reader.cxx:112
 Reader.cxx:113
 Reader.cxx:114
 Reader.cxx:115
 Reader.cxx:116
 Reader.cxx:117
 Reader.cxx:118
 Reader.cxx:119
 Reader.cxx:120
 Reader.cxx:121
 Reader.cxx:122
 Reader.cxx:123
 Reader.cxx:124
 Reader.cxx:125
 Reader.cxx:126
 Reader.cxx:127
 Reader.cxx:128
 Reader.cxx:129
 Reader.cxx:130
 Reader.cxx:131
 Reader.cxx:132
 Reader.cxx:133
 Reader.cxx:134
 Reader.cxx:135
 Reader.cxx:136
 Reader.cxx:137
 Reader.cxx:138
 Reader.cxx:139
 Reader.cxx:140
 Reader.cxx:141
 Reader.cxx:142
 Reader.cxx:143
 Reader.cxx:144
 Reader.cxx:145
 Reader.cxx:146
 Reader.cxx:147
 Reader.cxx:148
 Reader.cxx:149
 Reader.cxx:150
 Reader.cxx:151
 Reader.cxx:152
 Reader.cxx:153
 Reader.cxx:154
 Reader.cxx:155
 Reader.cxx:156
 Reader.cxx:157
 Reader.cxx:158
 Reader.cxx:159
 Reader.cxx:160
 Reader.cxx:161
 Reader.cxx:162
 Reader.cxx:163
 Reader.cxx:164
 Reader.cxx:165
 Reader.cxx:166
 Reader.cxx:167
 Reader.cxx:168
 Reader.cxx:169
 Reader.cxx:170
 Reader.cxx:171
 Reader.cxx:172
 Reader.cxx:173
 Reader.cxx:174
 Reader.cxx:175
 Reader.cxx:176
 Reader.cxx:177
 Reader.cxx:178
 Reader.cxx:179
 Reader.cxx:180
 Reader.cxx:181
 Reader.cxx:182
 Reader.cxx:183
 Reader.cxx:184
 Reader.cxx:185
 Reader.cxx:186
 Reader.cxx:187
 Reader.cxx:188
 Reader.cxx:189
 Reader.cxx:190
 Reader.cxx:191
 Reader.cxx:192
 Reader.cxx:193
 Reader.cxx:194
 Reader.cxx:195
 Reader.cxx:196
 Reader.cxx:197
 Reader.cxx:198
 Reader.cxx:199
 Reader.cxx:200
 Reader.cxx:201
 Reader.cxx:202
 Reader.cxx:203
 Reader.cxx:204
 Reader.cxx:205
 Reader.cxx:206
 Reader.cxx:207
 Reader.cxx:208
 Reader.cxx:209
 Reader.cxx:210
 Reader.cxx:211
 Reader.cxx:212
 Reader.cxx:213
 Reader.cxx:214
 Reader.cxx:215
 Reader.cxx:216
 Reader.cxx:217
 Reader.cxx:218
 Reader.cxx:219
 Reader.cxx:220
 Reader.cxx:221
 Reader.cxx:222
 Reader.cxx:223
 Reader.cxx:224
 Reader.cxx:225
 Reader.cxx:226
 Reader.cxx:227
 Reader.cxx:228
 Reader.cxx:229
 Reader.cxx:230
 Reader.cxx:231
 Reader.cxx:232
 Reader.cxx:233
 Reader.cxx:234
 Reader.cxx:235
 Reader.cxx:236
 Reader.cxx:237
 Reader.cxx:238
 Reader.cxx:239
 Reader.cxx:240
 Reader.cxx:241
 Reader.cxx:242
 Reader.cxx:243
 Reader.cxx:244
 Reader.cxx:245
 Reader.cxx:246
 Reader.cxx:247
 Reader.cxx:248
 Reader.cxx:249
 Reader.cxx:250
 Reader.cxx:251
 Reader.cxx:252
 Reader.cxx:253
 Reader.cxx:254
 Reader.cxx:255
 Reader.cxx:256
 Reader.cxx:257
 Reader.cxx:258
 Reader.cxx:259
 Reader.cxx:260
 Reader.cxx:261
 Reader.cxx:262
 Reader.cxx:263
 Reader.cxx:264
 Reader.cxx:265
 Reader.cxx:266
 Reader.cxx:267
 Reader.cxx:268
 Reader.cxx:269
 Reader.cxx:270
 Reader.cxx:271
 Reader.cxx:272
 Reader.cxx:273
 Reader.cxx:274
 Reader.cxx:275
 Reader.cxx:276
 Reader.cxx:277
 Reader.cxx:278
 Reader.cxx:279
 Reader.cxx:280
 Reader.cxx:281
 Reader.cxx:282
 Reader.cxx:283
 Reader.cxx:284
 Reader.cxx:285
 Reader.cxx:286
 Reader.cxx:287
 Reader.cxx:288
 Reader.cxx:289
 Reader.cxx:290
 Reader.cxx:291
 Reader.cxx:292
 Reader.cxx:293
 Reader.cxx:294
 Reader.cxx:295
 Reader.cxx:296
 Reader.cxx:297
 Reader.cxx:298
 Reader.cxx:299
 Reader.cxx:300
 Reader.cxx:301
 Reader.cxx:302
 Reader.cxx:303
 Reader.cxx:304
 Reader.cxx:305
 Reader.cxx:306
 Reader.cxx:307
 Reader.cxx:308
 Reader.cxx:309
 Reader.cxx:310
 Reader.cxx:311
 Reader.cxx:312
 Reader.cxx:313
 Reader.cxx:314
 Reader.cxx:315
 Reader.cxx:316
 Reader.cxx:317
 Reader.cxx:318
 Reader.cxx:319
 Reader.cxx:320
 Reader.cxx:321
 Reader.cxx:322
 Reader.cxx:323
 Reader.cxx:324
 Reader.cxx:325
 Reader.cxx:326
 Reader.cxx:327
 Reader.cxx:328
 Reader.cxx:329
 Reader.cxx:330
 Reader.cxx:331
 Reader.cxx:332
 Reader.cxx:333
 Reader.cxx:334
 Reader.cxx:335
 Reader.cxx:336
 Reader.cxx:337
 Reader.cxx:338
 Reader.cxx:339
 Reader.cxx:340
 Reader.cxx:341
 Reader.cxx:342
 Reader.cxx:343
 Reader.cxx:344
 Reader.cxx:345
 Reader.cxx:346
 Reader.cxx:347
 Reader.cxx:348
 Reader.cxx:349
 Reader.cxx:350
 Reader.cxx:351
 Reader.cxx:352
 Reader.cxx:353
 Reader.cxx:354
 Reader.cxx:355
 Reader.cxx:356
 Reader.cxx:357
 Reader.cxx:358
 Reader.cxx:359
 Reader.cxx:360
 Reader.cxx:361
 Reader.cxx:362
 Reader.cxx:363
 Reader.cxx:364
 Reader.cxx:365
 Reader.cxx:366
 Reader.cxx:367
 Reader.cxx:368
 Reader.cxx:369
 Reader.cxx:370
 Reader.cxx:371
 Reader.cxx:372
 Reader.cxx:373
 Reader.cxx:374
 Reader.cxx:375
 Reader.cxx:376
 Reader.cxx:377
 Reader.cxx:378
 Reader.cxx:379
 Reader.cxx:380
 Reader.cxx:381
 Reader.cxx:382
 Reader.cxx:383
 Reader.cxx:384
 Reader.cxx:385
 Reader.cxx:386
 Reader.cxx:387
 Reader.cxx:388
 Reader.cxx:389
 Reader.cxx:390
 Reader.cxx:391
 Reader.cxx:392
 Reader.cxx:393
 Reader.cxx:394
 Reader.cxx:395
 Reader.cxx:396
 Reader.cxx:397
 Reader.cxx:398
 Reader.cxx:399
 Reader.cxx:400
 Reader.cxx:401
 Reader.cxx:402
 Reader.cxx:403
 Reader.cxx:404
 Reader.cxx:405
 Reader.cxx:406
 Reader.cxx:407
 Reader.cxx:408
 Reader.cxx:409
 Reader.cxx:410
 Reader.cxx:411
 Reader.cxx:412
 Reader.cxx:413
 Reader.cxx:414
 Reader.cxx:415
 Reader.cxx:416
 Reader.cxx:417
 Reader.cxx:418
 Reader.cxx:419
 Reader.cxx:420
 Reader.cxx:421
 Reader.cxx:422
 Reader.cxx:423
 Reader.cxx:424
 Reader.cxx:425
 Reader.cxx:426
 Reader.cxx:427
 Reader.cxx:428
 Reader.cxx:429
 Reader.cxx:430
 Reader.cxx:431
 Reader.cxx:432
 Reader.cxx:433
 Reader.cxx:434
 Reader.cxx:435
 Reader.cxx:436
 Reader.cxx:437
 Reader.cxx:438
 Reader.cxx:439
 Reader.cxx:440
 Reader.cxx:441
 Reader.cxx:442
 Reader.cxx:443
 Reader.cxx:444
 Reader.cxx:445
 Reader.cxx:446
 Reader.cxx:447
 Reader.cxx:448
 Reader.cxx:449
 Reader.cxx:450
 Reader.cxx:451
 Reader.cxx:452
 Reader.cxx:453
 Reader.cxx:454
 Reader.cxx:455
 Reader.cxx:456
 Reader.cxx:457
 Reader.cxx:458
 Reader.cxx:459
 Reader.cxx:460
 Reader.cxx:461
 Reader.cxx:462
 Reader.cxx:463
 Reader.cxx:464
 Reader.cxx:465
 Reader.cxx:466
 Reader.cxx:467
 Reader.cxx:468
 Reader.cxx:469
 Reader.cxx:470
 Reader.cxx:471
 Reader.cxx:472
 Reader.cxx:473
 Reader.cxx:474
 Reader.cxx:475
 Reader.cxx:476
 Reader.cxx:477
 Reader.cxx:478
 Reader.cxx:479
 Reader.cxx:480
 Reader.cxx:481
 Reader.cxx:482
 Reader.cxx:483
 Reader.cxx:484
 Reader.cxx:485
 Reader.cxx:486
 Reader.cxx:487
 Reader.cxx:488
 Reader.cxx:489
 Reader.cxx:490
 Reader.cxx:491
 Reader.cxx:492
 Reader.cxx:493
 Reader.cxx:494
 Reader.cxx:495
 Reader.cxx:496
 Reader.cxx:497
 Reader.cxx:498
 Reader.cxx:499
 Reader.cxx:500
 Reader.cxx:501
 Reader.cxx:502
 Reader.cxx:503
 Reader.cxx:504
 Reader.cxx:505
 Reader.cxx:506
 Reader.cxx:507
 Reader.cxx:508
 Reader.cxx:509
 Reader.cxx:510
 Reader.cxx:511
 Reader.cxx:512
 Reader.cxx:513
 Reader.cxx:514
 Reader.cxx:515
 Reader.cxx:516
 Reader.cxx:517
 Reader.cxx:518
 Reader.cxx:519
 Reader.cxx:520
 Reader.cxx:521
 Reader.cxx:522
 Reader.cxx:523
 Reader.cxx:524
 Reader.cxx:525
 Reader.cxx:526
 Reader.cxx:527
 Reader.cxx:528
 Reader.cxx:529
 Reader.cxx:530
 Reader.cxx:531
 Reader.cxx:532
 Reader.cxx:533
 Reader.cxx:534
 Reader.cxx:535
 Reader.cxx:536
 Reader.cxx:537
 Reader.cxx:538
 Reader.cxx:539
 Reader.cxx:540
 Reader.cxx:541
 Reader.cxx:542
 Reader.cxx:543
 Reader.cxx:544
 Reader.cxx:545
 Reader.cxx:546
 Reader.cxx:547
 Reader.cxx:548
 Reader.cxx:549
 Reader.cxx:550
 Reader.cxx:551
 Reader.cxx:552
 Reader.cxx:553
 Reader.cxx:554
 Reader.cxx:555
 Reader.cxx:556
 Reader.cxx:557
 Reader.cxx:558
 Reader.cxx:559
 Reader.cxx:560
 Reader.cxx:561
 Reader.cxx:562
 Reader.cxx:563
 Reader.cxx:564
 Reader.cxx:565
 Reader.cxx:566
 Reader.cxx:567
 Reader.cxx:568
 Reader.cxx:569
 Reader.cxx:570
 Reader.cxx:571
 Reader.cxx:572
 Reader.cxx:573
 Reader.cxx:574
 Reader.cxx:575
 Reader.cxx:576
 Reader.cxx:577
 Reader.cxx:578
 Reader.cxx:579
 Reader.cxx:580
 Reader.cxx:581
 Reader.cxx:582
 Reader.cxx:583
 Reader.cxx:584
 Reader.cxx:585
 Reader.cxx:586
 Reader.cxx:587
 Reader.cxx:588
 Reader.cxx:589
 Reader.cxx:590
 Reader.cxx:591
 Reader.cxx:592
 Reader.cxx:593
 Reader.cxx:594
 Reader.cxx:595
 Reader.cxx:596
 Reader.cxx:597
 Reader.cxx:598
 Reader.cxx:599
 Reader.cxx:600
 Reader.cxx:601
 Reader.cxx:602
 Reader.cxx:603
 Reader.cxx:604
 Reader.cxx:605
 Reader.cxx:606
 Reader.cxx:607
 Reader.cxx:608
 Reader.cxx:609
 Reader.cxx:610
 Reader.cxx:611
 Reader.cxx:612
 Reader.cxx:613
 Reader.cxx:614
 Reader.cxx:615
 Reader.cxx:616
 Reader.cxx:617
 Reader.cxx:618
 Reader.cxx:619
 Reader.cxx:620
 Reader.cxx:621
 Reader.cxx:622
 Reader.cxx:623
 Reader.cxx:624
 Reader.cxx:625
 Reader.cxx:626
 Reader.cxx:627
 Reader.cxx:628
 Reader.cxx:629
 Reader.cxx:630
 Reader.cxx:631
 Reader.cxx:632
 Reader.cxx:633
 Reader.cxx:634
 Reader.cxx:635
 Reader.cxx:636
 Reader.cxx:637
 Reader.cxx:638
 Reader.cxx:639
 Reader.cxx:640
 Reader.cxx:641
 Reader.cxx:642
 Reader.cxx:643
 Reader.cxx:644
 Reader.cxx:645
 Reader.cxx:646
 Reader.cxx:647
 Reader.cxx:648
 Reader.cxx:649
 Reader.cxx:650
 Reader.cxx:651
 Reader.cxx:652
 Reader.cxx:653
 Reader.cxx:654
 Reader.cxx:655
 Reader.cxx:656
 Reader.cxx:657
 Reader.cxx:658
 Reader.cxx:659
 Reader.cxx:660
 Reader.cxx:661
 Reader.cxx:662
 Reader.cxx:663
 Reader.cxx:664
 Reader.cxx:665
 Reader.cxx:666
 Reader.cxx:667
 Reader.cxx:668
 Reader.cxx:669
 Reader.cxx:670
 Reader.cxx:671
 Reader.cxx:672
 Reader.cxx:673
 Reader.cxx:674
 Reader.cxx:675
 Reader.cxx:676
 Reader.cxx:677
 Reader.cxx:678
 Reader.cxx:679
 Reader.cxx:680
 Reader.cxx:681
 Reader.cxx:682
 Reader.cxx:683
 Reader.cxx:684
 Reader.cxx:685
 Reader.cxx:686
 Reader.cxx:687
 Reader.cxx:688
 Reader.cxx:689
 Reader.cxx:690
 Reader.cxx:691
 Reader.cxx:692
 Reader.cxx:693
 Reader.cxx:694
 Reader.cxx:695
 Reader.cxx:696
 Reader.cxx:697
 Reader.cxx:698
 Reader.cxx:699
 Reader.cxx:700
 Reader.cxx:701
 Reader.cxx:702
 Reader.cxx:703
 Reader.cxx:704
 Reader.cxx:705
 Reader.cxx:706
 Reader.cxx:707
 Reader.cxx:708
 Reader.cxx:709
 Reader.cxx:710
 Reader.cxx:711
 Reader.cxx:712
 Reader.cxx:713
 Reader.cxx:714
 Reader.cxx:715
 Reader.cxx:716
 Reader.cxx:717
 Reader.cxx:718
 Reader.cxx:719
 Reader.cxx:720
 Reader.cxx:721
 Reader.cxx:722
 Reader.cxx:723
 Reader.cxx:724
 Reader.cxx:725
 Reader.cxx:726
 Reader.cxx:727
 Reader.cxx:728
 Reader.cxx:729
 Reader.cxx:730
 Reader.cxx:731
 Reader.cxx:732
 Reader.cxx:733
 Reader.cxx:734
 Reader.cxx:735
 Reader.cxx:736
 Reader.cxx:737
 Reader.cxx:738
 Reader.cxx:739
 Reader.cxx:740
 Reader.cxx:741
 Reader.cxx:742
 Reader.cxx:743
 Reader.cxx:744
 Reader.cxx:745
 Reader.cxx:746
 Reader.cxx:747
 Reader.cxx:748
 Reader.cxx:749
 Reader.cxx:750
 Reader.cxx:751
 Reader.cxx:752
 Reader.cxx:753
 Reader.cxx:754
 Reader.cxx:755
 Reader.cxx:756
 Reader.cxx:757
 Reader.cxx:758
 Reader.cxx:759
 Reader.cxx:760
 Reader.cxx:761
 Reader.cxx:762
 Reader.cxx:763
 Reader.cxx:764
 Reader.cxx:765
 Reader.cxx:766
 Reader.cxx:767
 Reader.cxx:768
 Reader.cxx:769
 Reader.cxx:770
 Reader.cxx:771
 Reader.cxx:772
 Reader.cxx:773
 Reader.cxx:774
 Reader.cxx:775
 Reader.cxx:776
 Reader.cxx:777
 Reader.cxx:778
 Reader.cxx:779
 Reader.cxx:780
 Reader.cxx:781
 Reader.cxx:782
 Reader.cxx:783
 Reader.cxx:784
 Reader.cxx:785
 Reader.cxx:786
 Reader.cxx:787
 Reader.cxx:788
 Reader.cxx:789
 Reader.cxx:790
 Reader.cxx:791
 Reader.cxx:792
 Reader.cxx:793
 Reader.cxx:794
 Reader.cxx:795
 Reader.cxx:796
 Reader.cxx:797
 Reader.cxx:798
 Reader.cxx:799