ROOT logo
// @(#)root/tmva $Id: Reader.cxx 31458 2009-11-30 13:58:20Z stelzer $
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss

/**********************************************************************************
 * 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              *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *      Kai Voss        <Kai.Voss@cern.ch>       - U. of Victoria, Canada         *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         *
 *      U. of Victoria, Canada                                                    *
 *      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://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 <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"

ClassImp(TMVA::Reader)

//_______________________________________________________________________
TMVA::Reader::Reader( const TString& theOption, Bool_t verbose )
   : Configurable( theOption ),
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fMvaEventError( -1 ),
     fLogger ( 0 )
{
   // constructor

   fLogger = new MsgLogger(this);

   DataSetManager::CreateInstance(fDataInputHandler);
   DataSetManager::Instance().AddDataSetInfo(fDataSetInfo);

   SetConfigName( GetName() );
   DeclareOptions();
   ParseOptions();

   Init();
}

//_______________________________________________________________________
TMVA::Reader::Reader( std::vector<TString>& inputVars, const TString& theOption, Bool_t verbose )
   : Configurable( theOption ),
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fMvaEventError( -1 ),
     fLogger ( 0 )
{
   // constructor
   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 ),
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fMvaEventError( -1 ),
     fLogger ( 0 )
{
   // constructor
   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 ),
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fMvaEventError( -1 ),
     fLogger ( 0 )
{
   // constructor
   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 ),
     fDataSetInfo(),
     fVerbose( verbose ),
     fSilent ( kFALSE ),
     fColor  ( kFALSE ),
     fMvaEventError( -1 ),
     fLogger ( 0 )
{
   // constructor
   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)" );   
}

//_______________________________________________________________________
TMVA::Reader::~Reader( void )
{
   // destructor
   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 )
{
   // Add an integer variable or expression to the reader
   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

   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();
      void* doc      = gTools().xmlengine().ParseFile(filename); 
      void* rootnode = gTools().xmlengine().DocGetRootElement(doc); // node "MethodSetup"
      gTools().ReadAttr(rootnode, "Method", fullMethodName);
   } 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 ) );

   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));

   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;
}

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

   return EvaluateMVA( methodTag, aux );
}

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

   return EvaluateMVA( 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;

   return this->EvaluateMVA( dynamic_cast<TMVA::MethodBase*>(method), 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)
      dynamic_cast<TMVA::MethodCuts*>(method)->SetTestSignalEfficiency( aux );

   return method->GetMvaValue( &fMvaEventError ); // attributed MVA response and error
}

//_______________________________________________________________________
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;
   return this->EvaluateRegression( dynamic_cast<TMVA::MethodBase*>(method), aux );
}

//_______________________________________________________________________
const std::vector< Float_t >& TMVA::Reader::EvaluateRegression( MethodBase* method, Double_t /*aux*/ )
{
   // evaluates the regression MVA
   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;
   }
}

//_______________________________________________________________________
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 (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 (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