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

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : DataInputHandler                                                      *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Contains all the data information                                         *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Joerg Stelzer   <Joerg.Stelzer@cern.ch>  - CERN, Switzerland              *
 *      Peter Speckmayer <Peter.Speckmayer@cern.ch>  - CERN, Switzerland          *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *                                                                                *
 * Copyright (c) 2006:                                                            *
 *      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_DataInputHandler
#define ROOT_TMVA_DataInputHandler

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// DataInputHandler                                                     //
//                                                                      //
// Class that contains all the data information                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

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

#ifndef ROOT_TTree
#include "TTree.h"
#endif
#ifndef ROOT_TCut
#include "TCut.h"
#endif

#ifndef ROOT_TMVA_Types
#include "TMVA/Types.h"
#endif

namespace TMVA {

   class MsgLogger;
   
   class TreeInfo:public TObject {

   public:

      TreeInfo( TTree* tr, const TString& className, Double_t weight=1.0, Types::ETreeType tt = Types::kMaxTreeType, Bool_t own=kFALSE ) 
      : fTree(tr), fClassName(className), fWeight(weight), fTreeType(tt), fOwner(own) {}
      TreeInfo():fTree(0),fClassName(""),fWeight(1.0), fTreeType(Types::kMaxTreeType), fOwner(kFALSE) {}
      ~TreeInfo() { if (fOwner) delete fTree; }

      TTree*           GetTree()      const { return fTree; }
      Double_t         GetWeight()    const { return fWeight; }
      UInt_t           GetEntries()   const { if( !fTree ) return 0; else return fTree->GetEntries(); }
      Types::ETreeType GetTreeType()  const { return fTreeType; }
      const TString&   GetClassName() const { return fClassName; }

   private:

      TTree*           fTree;     // pointer to the tree
      TString          fClassName;// name of the class the tree belongs to
      Double_t         fWeight;   // weight for the tree
      Types::ETreeType fTreeType; // tree is for training/testing/both
      Bool_t           fOwner;    // true if created from file
   protected:
       ClassDef(TreeInfo,1);      
   };

   class DataInputHandler :public TObject {

   public:

      DataInputHandler();
      ~DataInputHandler();

      // setters
      void     AddSignalTree    ( TTree* tr, Double_t weight=1.0, Types::ETreeType tt = Types::kMaxTreeType );
      void     AddBackgroundTree( TTree* tr, Double_t weight=1.0, Types::ETreeType tt = Types::kMaxTreeType );
      void     AddSignalTree    ( const TString& tr, Double_t weight=1.0, Types::ETreeType tt = Types::kMaxTreeType );
      void     AddBackgroundTree( const TString& tr, Double_t weight=1.0, Types::ETreeType tt = Types::kMaxTreeType );
      void     AddInputTrees    ( TTree* inputTree, const TCut& SigCut, const TCut& BgCut);

      void     AddTree          ( TTree* tree, const TString& className, Double_t weight=1.0, 
                                  const TCut& cut = "", Types::ETreeType tt = Types::kMaxTreeType );
      void     AddTree          ( const TString& tr, const TString& className, Double_t weight=1.0, 
                                  const TCut& cut = "", Types::ETreeType tt = Types::kMaxTreeType );

      // accessors
      std::vector< TString >* GetClassList() const;

      UInt_t           GetEntries( const TString& name ) const { return GetEntries( fInputTrees[name] ); }
      UInt_t           GetNTrees ( const TString& name ) const { return fInputTrees[name].size(); }

      UInt_t           GetNSignalTrees()           const { return fInputTrees["Signal"].size(); }
      UInt_t           GetNBackgroundTrees()       const { return fInputTrees["Background"].size(); }
      UInt_t           GetSignalEntries()          const { return GetEntries(fInputTrees["Signal"]); }
      UInt_t           GetBackgroundEntries()      const { return GetEntries(fInputTrees["Background"]); }
      UInt_t           GetEntries()                const;
      const TreeInfo&  SignalTreeInfo(Int_t i)     const { return fInputTrees["Signal"][i]; }
      const TreeInfo&  BackgroundTreeInfo(Int_t i) const { return fInputTrees["Background"][i]; }

      std::vector<TreeInfo>::const_iterator begin( const TString& className ) const { return fInputTrees[className].begin(); }
      std::vector<TreeInfo>::const_iterator end( const TString& className )   const { return fInputTrees[className].end(); }
      std::vector<TreeInfo>::const_iterator Sbegin() const { return begin("Signal"); }
      std::vector<TreeInfo>::const_iterator Send()   const { return end  ("Signal"); }
      std::vector<TreeInfo>::const_iterator Bbegin() const { return begin("Background"); }
      std::vector<TreeInfo>::const_iterator Bend()   const { return end  ("Background"); }

      // reset the list of trees
      void     ClearSignalTreeList()     { ClearTreeList("Signal"); }
      void     ClearBackgroundTreeList() { ClearTreeList("Background"); }
      void     ClearTreeList( const TString& className );

   private:

      UInt_t GetEntries(const std::vector<TreeInfo>& tiV) const;

      TTree * ReadInputTree( const TString& dataFile );
      
      mutable std::map< TString, std::vector<TreeInfo> > fInputTrees;        // list of input trees per class (classname is given as first parameter in the map)
      std::map< std::string, Bool_t   >                  fExplicitTrainTest; // if set to true the user has specified training and testing data explicitly
      mutable MsgLogger*                                 fLogger;            //! message logger
      MsgLogger& Log() const { return *fLogger; }
   protected:
       ClassDef(DataInputHandler,1);
   };
}

#endif
 DataInputHandler.h:1
 DataInputHandler.h:2
 DataInputHandler.h:3
 DataInputHandler.h:4
 DataInputHandler.h:5
 DataInputHandler.h:6
 DataInputHandler.h:7
 DataInputHandler.h:8
 DataInputHandler.h:9
 DataInputHandler.h:10
 DataInputHandler.h:11
 DataInputHandler.h:12
 DataInputHandler.h:13
 DataInputHandler.h:14
 DataInputHandler.h:15
 DataInputHandler.h:16
 DataInputHandler.h:17
 DataInputHandler.h:18
 DataInputHandler.h:19
 DataInputHandler.h:20
 DataInputHandler.h:21
 DataInputHandler.h:22
 DataInputHandler.h:23
 DataInputHandler.h:24
 DataInputHandler.h:25
 DataInputHandler.h:26
 DataInputHandler.h:27
 DataInputHandler.h:28
 DataInputHandler.h:29
 DataInputHandler.h:30
 DataInputHandler.h:31
 DataInputHandler.h:32
 DataInputHandler.h:33
 DataInputHandler.h:34
 DataInputHandler.h:35
 DataInputHandler.h:36
 DataInputHandler.h:37
 DataInputHandler.h:38
 DataInputHandler.h:39
 DataInputHandler.h:40
 DataInputHandler.h:41
 DataInputHandler.h:42
 DataInputHandler.h:43
 DataInputHandler.h:44
 DataInputHandler.h:45
 DataInputHandler.h:46
 DataInputHandler.h:47
 DataInputHandler.h:48
 DataInputHandler.h:49
 DataInputHandler.h:50
 DataInputHandler.h:51
 DataInputHandler.h:52
 DataInputHandler.h:53
 DataInputHandler.h:54
 DataInputHandler.h:55
 DataInputHandler.h:56
 DataInputHandler.h:57
 DataInputHandler.h:58
 DataInputHandler.h:59
 DataInputHandler.h:60
 DataInputHandler.h:61
 DataInputHandler.h:62
 DataInputHandler.h:63
 DataInputHandler.h:64
 DataInputHandler.h:65
 DataInputHandler.h:66
 DataInputHandler.h:67
 DataInputHandler.h:68
 DataInputHandler.h:69
 DataInputHandler.h:70
 DataInputHandler.h:71
 DataInputHandler.h:72
 DataInputHandler.h:73
 DataInputHandler.h:74
 DataInputHandler.h:75
 DataInputHandler.h:76
 DataInputHandler.h:77
 DataInputHandler.h:78
 DataInputHandler.h:79
 DataInputHandler.h:80
 DataInputHandler.h:81
 DataInputHandler.h:82
 DataInputHandler.h:83
 DataInputHandler.h:84
 DataInputHandler.h:85
 DataInputHandler.h:86
 DataInputHandler.h:87
 DataInputHandler.h:88
 DataInputHandler.h:89
 DataInputHandler.h:90
 DataInputHandler.h:91
 DataInputHandler.h:92
 DataInputHandler.h:93
 DataInputHandler.h:94
 DataInputHandler.h:95
 DataInputHandler.h:96
 DataInputHandler.h:97
 DataInputHandler.h:98
 DataInputHandler.h:99
 DataInputHandler.h:100
 DataInputHandler.h:101
 DataInputHandler.h:102
 DataInputHandler.h:103
 DataInputHandler.h:104
 DataInputHandler.h:105
 DataInputHandler.h:106
 DataInputHandler.h:107
 DataInputHandler.h:108
 DataInputHandler.h:109
 DataInputHandler.h:110
 DataInputHandler.h:111
 DataInputHandler.h:112
 DataInputHandler.h:113
 DataInputHandler.h:114
 DataInputHandler.h:115
 DataInputHandler.h:116
 DataInputHandler.h:117
 DataInputHandler.h:118
 DataInputHandler.h:119
 DataInputHandler.h:120
 DataInputHandler.h:121
 DataInputHandler.h:122
 DataInputHandler.h:123
 DataInputHandler.h:124
 DataInputHandler.h:125
 DataInputHandler.h:126
 DataInputHandler.h:127
 DataInputHandler.h:128
 DataInputHandler.h:129
 DataInputHandler.h:130
 DataInputHandler.h:131
 DataInputHandler.h:132
 DataInputHandler.h:133
 DataInputHandler.h:134
 DataInputHandler.h:135
 DataInputHandler.h:136
 DataInputHandler.h:137
 DataInputHandler.h:138
 DataInputHandler.h:139
 DataInputHandler.h:140
 DataInputHandler.h:141
 DataInputHandler.h:142
 DataInputHandler.h:143
 DataInputHandler.h:144
 DataInputHandler.h:145