// @(#)root/treeplayer:$Id$
// Author: Axel Naumann, 2011-09-28

/*************************************************************************
 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al.        *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TTreeReaderValue.h"

#include "TTreeReader.h"
#include "TBranchClones.h"
#include "TBranchElement.h"
#include "TBranchRef.h"
#include "TBranchSTL.h"
#include "TBranchProxyDirector.h"
#include "TLeaf.h"
#include "TTreeProxyGenerator.h"
#include "TTreeReaderValue.h"
#include "TRegexp.h"
#include "TStreamerInfo.h"
#include "TStreamerElement.h"
#include "TNtuple.h"
#include <vector>

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// TTreeReaderValue                                                        //
//                                                                            //
// Extracts data from a TTree.                                                //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

ClassImp(TTreeReaderValueBase)

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::TTreeReaderValueBase(TTreeReader* reader /*= 0*/,
                                                 const char* branchname /*= 0*/,
                                                 TDictionary* dict /*= 0*/):
   fBranchName(branchname),
   fTreeReader(reader),
   fDict(dict),
   fProxy(NULL),
   fLeaf(NULL),
   fTreeLastOffset(-1),
   fSetupStatus(kSetupNotSetup),
   fReadStatus(kReadNothingYet)
{
   // Construct a tree value reader and register it with the reader object.
   if (fTreeReader) fTreeReader->RegisterValueReader(this);
}

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::~TTreeReaderValueBase()
{
   // Unregister from tree reader, cleanup.
   if (fTreeReader) fTreeReader->DeregisterValueReader(this);
}

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::EReadStatus
ROOT::TTreeReaderValueBase::ProxyRead() {
   // Try to read the value from the TBranchProxy, returns
   // the status of the read.

   if (!fProxy) return kReadNothingYet;
   if (fProxy->Read()) {
      fReadStatus = kReadSuccess;
   } else {
      fReadStatus = kReadError;
   }
   return fReadStatus;
}

//______________________________________________________________________________
TLeaf* ROOT::TTreeReaderValueBase::GetLeaf() { 
   // If we are reading a leaf, return the corresponding TLeaf.

   if (fLeafName.Length() > 0){

      Long64_t newChainOffset = fTreeReader->GetTree()->GetChainOffset();

      if (newChainOffset != fTreeLastOffset){
         fTreeLastOffset = newChainOffset;

         TTree *myTree = fTreeReader->GetTree();

         if (!myTree) {
            fReadStatus = kReadError;
            Error("GetLeaf()", "Unable to get the tree from the TTreeReader");
            return 0;
         }

         TBranch *myBranch = myTree->GetBranch(fBranchName);

         if (!myBranch) {
            fReadStatus = kReadError;
            Error("GetLeaf()", "Unable to get the branch from the tree");
            return 0;
         }

         fLeaf = myBranch->GetLeaf(fLeafName);
         if (!fLeaf) {
            Error("GetLeaf()", "Failed to get the leaf from the branch");
         }
      }
      return fLeaf;
   }
   else {
      Error("GetLeaf()", "We are not reading a leaf");
      return 0;
   }
}

//______________________________________________________________________________
void* ROOT::TTreeReaderValueBase::GetAddress() {
   // Returns the memory address of the object being read.

   if (ProxyRead() != kReadSuccess) return 0;

   if (fLeafName.Length() > 0){
      if (GetLeaf()){
         return fLeaf->GetValuePointer();
      }
      else {
         fReadStatus = kReadError;
         Error("GetAddress()", "Unable to get the leaf");
         return 0;
      }
   }
   if (!fStaticClassOffsets.empty()){ // Follow all the pointers
      Byte_t *address = (Byte_t*)fProxy->GetWhere();

      for (unsigned int i = 0; i < fStaticClassOffsets.size() - 1; ++i){
         address = *(Byte_t**)(address + fStaticClassOffsets[i]);
      }

      return address + fStaticClassOffsets.back();
   }
   return fProxy ? (Byte_t*)fProxy->GetWhere() : 0;
}

//______________________________________________________________________________
void ROOT::TTreeReaderValueBase::CreateProxy() {
   // Create the proxy object for our branch.
   if (fProxy) {
      return;
   }
   if (!fTreeReader) {
      Error("CreateProxy()", "TTreeReader object not set / available for branch %s!",
            fBranchName.Data());
      return;
   }
   if (!fDict) {
      TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
      const char* brDataType = "{UNDETERMINED}";
      if (br) {
         TDictionary* brDictUnused = 0;
         brDataType = GetBranchDataType(br, brDictUnused);
      }
      Error("CreateProxy()", "The template argument type T of %s accessing branch %s (which contains data of type %s) is not known to ROOT. You will need to create a dictionary for it.",
            GetDerivedTypeName(), fBranchName.Data(), brDataType);
      return;
   }

   // Search for the branchname, determine what it contains, and wire the
   // TBranchProxy representing it to us so we can access its data.

   ROOT::TNamedBranchProxy* namedProxy
      = (ROOT::TNamedBranchProxy*)fTreeReader->FindObject(fBranchName);
   if (namedProxy && namedProxy->GetDict() == fDict) {
      fProxy = namedProxy->GetProxy();
      return;
   }

   TBranch* branch = fTreeReader->GetTree()->GetBranch(fBranchName);
   TLeaf *myLeaf = NULL;
   TDictionary* branchActualType = 0;

   if (!branch) {
      if (fBranchName.Contains(".")){
         TRegexp leafNameExpression ("\\.[a-zA-Z0-9_]+$");
         TString leafName (fBranchName(leafNameExpression));
         TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
         branch = fTreeReader->GetTree()->GetBranch(branchName);
         if (!branch){
            std::vector<TString> nameStack;
            nameStack.push_back(TString()); //Trust me
            nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
            leafName = branchName(leafNameExpression);
            branchName = branchName(0, branchName.Length() - leafName.Length());
            
            branch = fTreeReader->GetTree()->GetBranch(branchName);
            if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName + ".");
            if (leafName.Length()) nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
            
            while (!branch && branchName.Contains(".")){
               leafName = branchName(leafNameExpression);
               branchName = branchName(0, fBranchName.Length() - leafName.Length());
               branch = fTreeReader->GetTree()->GetBranch(branchName);
               if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName + ".");
               nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
            }

            if (branch && branch->IsA() == TBranchElement::Class()){
               TBranchElement *myBranchElement = (TBranchElement*)branch;

               TString traversingBranch = nameStack.back();
               nameStack.pop_back();

               bool found = true;

               TDataType *finalDataType = 0;

               std::vector<Long64_t> offsets;
               Long64_t offset = 0;
               TClass *elementClass = 0;

               TObjArray *myObjArray = myBranchElement->GetInfo()->GetElements();
               Int_t     *myOffsets  = myBranchElement->GetInfo()->GetOffsets();

               while (nameStack.size() && found){
                  found = false;

                  for (int i = 0; i < myObjArray->GetEntries(); ++i){

                     TStreamerElement *tempStreamerElement = (TStreamerElement*)myObjArray->At(i);

                     if (!strcmp(tempStreamerElement->GetName(), traversingBranch.Data())){
                        offset += myOffsets[i];

                        traversingBranch = nameStack.back();
                        nameStack.pop_back();

                        elementClass = tempStreamerElement->GetClass();
                        if (elementClass){
                           TVirtualStreamerInfo *tempStreamerInfo = elementClass->GetStreamerInfo(0);
                           myObjArray = tempStreamerInfo->GetElements();
                           myOffsets = tempStreamerInfo->GetOffsets();
                        }
                        else {
                           finalDataType = TDataType::GetDataType((EDataType)tempStreamerElement->GetType());
                           if (!finalDataType) {
                              TDictionary* seType = TDictionary::GetDictionary(tempStreamerElement->GetTypeName());
                              if (seType && seType->IsA() == TDataType::Class()) {
                                 finalDataType = TDataType::GetDataType((EDataType)((TDataType*)seType)->GetType());
                              }
                           }
                        }

                        if (tempStreamerElement->IsaPointer()){
                           offsets.push_back(offset);
                           offset = 0;
                        }

                        found = true;
                        break;
                     }
                  }
               }

               offsets.push_back(offset);

               if (found){
                  fStaticClassOffsets = offsets;

                  if (fDict != finalDataType && fDict != elementClass){
                     Error("CreateProxy", "Wrong data type %s", finalDataType ? finalDataType->GetName() : elementClass ? elementClass->GetName() : "UNKNOWN");
                     fProxy = 0;
                     return;
                  }
               }
            }

            
            if (!fStaticClassOffsets.size()) {
               Error("CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
               fProxy = 0;
               return;
            }
         }
         else {
            myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
            if (!myLeaf){
               Error("CreateProxy()", "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
               fProxy = 0;
               return;
            }
            else {
               TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
               if (tempDict && tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
                  //fLeafOffset = myLeaf->GetOffset() / 4;
                  branchActualType = fDict;
                  fLeaf = myLeaf;
                  fBranchName = branchName;
                  fLeafName = leafName(1, leafName.Length());
               }
               else {
                  Error("CreateProxy()", "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
               }
            }
         }
      }
      else {
         Error("CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
         fProxy = 0;
         return;
      }
   }

   if (!myLeaf && !fStaticClassOffsets.size()){
      const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);

      if (!branchActualType) {
         Error("CreateProxy()", "The branch %s contains data of type %s, which does not have a dictionary.",
               fBranchName.Data(), branchActualTypeName ? branchActualTypeName : "{UNDETERMINED TYPE}");
         fProxy = 0;
         return;
      }

      if (fDict != branchActualType) {
         Error("CreateProxy()", "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
               fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
         return;
      }
   }
   

   // Update named proxy's dictionary
   if (namedProxy && !namedProxy->GetDict()) {
      namedProxy->SetDict(fDict);
      fProxy = namedProxy->GetProxy();
      return;
   }

   // Search for the branchname, determine what it contains, and wire the
   // TBranchProxy representing it to us so we can access its data.
   // A proxy for branch must not have been created before (i.e. check
   // fProxies before calling this function!)

   TString membername;

   bool isTopLevel = branch->GetMother() == branch;
   if (!isTopLevel) {
      membername = strrchr(branch->GetName(), '.');
      if (membername.IsNull()) {
         membername = branch->GetName();
      }
   }
   namedProxy = new ROOT::TNamedBranchProxy(fTreeReader->fDirector, branch, membername);
   fTreeReader->GetProxies()->Add(namedProxy);
   fProxy = namedProxy->GetProxy();
}

//______________________________________________________________________________
const char* ROOT::TTreeReaderValueBase::GetBranchDataType(TBranch* branch,
                                           TDictionary* &dict) const
{
   // Retrieve the type of data stored by branch; put its dictionary into
   // dict, return its type name. If no dictionary is available, at least
   // its type name should be returned.

   dict = 0;
   if (branch->IsA() == TBranchElement::Class()) {
      TBranchElement* brElement = (TBranchElement*)branch;
      if (brElement->GetType() == TBranchElement::kSTLNode || 
            brElement->GetType() == TBranchElement::kLeafNode || 
            brElement->GetType() == TBranchElement::kObjectNode) {

         TStreamerInfo *streamerInfo = brElement->GetInfo();
         Int_t id = brElement->GetID();

         if (id >= 0){
            TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
            if (element->IsA() == TStreamerSTL::Class()){
               TStreamerSTL *myStl = (TStreamerSTL*)element;
               dict = myStl->GetClass();
               return 0;
            }
         }

         if (brElement->GetTypeName()) dict = TDictionary::GetDictionary(brElement->GetTypeName());
         if (dict && dict->IsA() == TDataType::Class()){
            dict = TDictionary::GetDictionary(((TDataType*)dict)->GetTypeName());
            if (dict != fDict){
               dict = TClass::GetClass(brElement->GetTypeName());
            }
            if (dict != fDict){
               dict = brElement->GetCurrentClass();
            }
         }
         else if (!dict) {
            dict = brElement->GetCurrentClass();
         }

         return brElement->GetTypeName();
      } else if (brElement->GetType() == TBranchElement::kClonesNode) {
         dict = TClonesArray::Class();
         return "TClonesArray";
      } else if (brElement->GetType() == 31
                 || brElement->GetType() == 41) {
         // it's a member, extract from GetClass()'s streamer info
         Error("GetBranchDataType()", "Must use TTreeReaderValueArray to access a member of an object that is stored in a collection.");
      }
      else {
         Error("GetBranchDataType()", "Unknown type and class combination: %i, %s", brElement->GetType(), brElement->GetClassName());
      }
      return 0;
   } else if (branch->IsA() == TBranch::Class()
              || branch->IsA() == TBranchObject::Class()
              || branch->IsA() == TBranchSTL::Class()) {
      if (branch->GetTree()->IsA() == TNtuple::Class()){
         dict = TDataType::GetDataType(kFloat_t);
         return dict->GetName();
      }
      const char* dataTypeName = branch->GetClassName();
      if ((!dataTypeName || !dataTypeName[0])
          && branch->IsA() == TBranch::Class()) {
         TLeaf *myLeaf = branch->GetLeaf(branch->GetName());
         if (myLeaf){
            TDictionary *myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
            if (myDataType && myDataType->IsA() == TDataType::Class()){
               dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
               return myLeaf->GetTypeName();
            }
         }


         // leaflist. Can't represent.
         Error("GetBranchDataType()", "The branch %s was created using a leaf list and cannot be represented as a C++ type. Please access one of its siblings using a TTreeReaderValueArray:", branch->GetName());
         TIter iLeaves(branch->GetListOfLeaves());
         TLeaf* leaf = 0;
         while ((leaf = (TLeaf*) iLeaves())) {
            Error("GetBranchDataType()", "   %s.%s", branch->GetName(), leaf->GetName());
         }
         return 0;
      }
      if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
      return dataTypeName;
   } else if (branch->IsA() == TBranchClones::Class()) {
      dict = TClonesArray::Class();
      return "TClonesArray";
   } else if (branch->IsA() == TBranchRef::Class()) {
      // Can't represent.
      Error("GetBranchDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
      return 0;
   } else {
      Error("GetBranchDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
      return 0;
   }

   return 0;
}

 TTreeReaderValue.cxx:1
 TTreeReaderValue.cxx:2
 TTreeReaderValue.cxx:3
 TTreeReaderValue.cxx:4
 TTreeReaderValue.cxx:5
 TTreeReaderValue.cxx:6
 TTreeReaderValue.cxx:7
 TTreeReaderValue.cxx:8
 TTreeReaderValue.cxx:9
 TTreeReaderValue.cxx:10
 TTreeReaderValue.cxx:11
 TTreeReaderValue.cxx:12
 TTreeReaderValue.cxx:13
 TTreeReaderValue.cxx:14
 TTreeReaderValue.cxx:15
 TTreeReaderValue.cxx:16
 TTreeReaderValue.cxx:17
 TTreeReaderValue.cxx:18
 TTreeReaderValue.cxx:19
 TTreeReaderValue.cxx:20
 TTreeReaderValue.cxx:21
 TTreeReaderValue.cxx:22
 TTreeReaderValue.cxx:23
 TTreeReaderValue.cxx:24
 TTreeReaderValue.cxx:25
 TTreeReaderValue.cxx:26
 TTreeReaderValue.cxx:27
 TTreeReaderValue.cxx:28
 TTreeReaderValue.cxx:29
 TTreeReaderValue.cxx:30
 TTreeReaderValue.cxx:31
 TTreeReaderValue.cxx:32
 TTreeReaderValue.cxx:33
 TTreeReaderValue.cxx:34
 TTreeReaderValue.cxx:35
 TTreeReaderValue.cxx:36
 TTreeReaderValue.cxx:37
 TTreeReaderValue.cxx:38
 TTreeReaderValue.cxx:39
 TTreeReaderValue.cxx:40
 TTreeReaderValue.cxx:41
 TTreeReaderValue.cxx:42
 TTreeReaderValue.cxx:43
 TTreeReaderValue.cxx:44
 TTreeReaderValue.cxx:45
 TTreeReaderValue.cxx:46
 TTreeReaderValue.cxx:47
 TTreeReaderValue.cxx:48
 TTreeReaderValue.cxx:49
 TTreeReaderValue.cxx:50
 TTreeReaderValue.cxx:51
 TTreeReaderValue.cxx:52
 TTreeReaderValue.cxx:53
 TTreeReaderValue.cxx:54
 TTreeReaderValue.cxx:55
 TTreeReaderValue.cxx:56
 TTreeReaderValue.cxx:57
 TTreeReaderValue.cxx:58
 TTreeReaderValue.cxx:59
 TTreeReaderValue.cxx:60
 TTreeReaderValue.cxx:61
 TTreeReaderValue.cxx:62
 TTreeReaderValue.cxx:63
 TTreeReaderValue.cxx:64
 TTreeReaderValue.cxx:65
 TTreeReaderValue.cxx:66
 TTreeReaderValue.cxx:67
 TTreeReaderValue.cxx:68
 TTreeReaderValue.cxx:69
 TTreeReaderValue.cxx:70
 TTreeReaderValue.cxx:71
 TTreeReaderValue.cxx:72
 TTreeReaderValue.cxx:73
 TTreeReaderValue.cxx:74
 TTreeReaderValue.cxx:75
 TTreeReaderValue.cxx:76
 TTreeReaderValue.cxx:77
 TTreeReaderValue.cxx:78
 TTreeReaderValue.cxx:79
 TTreeReaderValue.cxx:80
 TTreeReaderValue.cxx:81
 TTreeReaderValue.cxx:82
 TTreeReaderValue.cxx:83
 TTreeReaderValue.cxx:84
 TTreeReaderValue.cxx:85
 TTreeReaderValue.cxx:86
 TTreeReaderValue.cxx:87
 TTreeReaderValue.cxx:88
 TTreeReaderValue.cxx:89
 TTreeReaderValue.cxx:90
 TTreeReaderValue.cxx:91
 TTreeReaderValue.cxx:92
 TTreeReaderValue.cxx:93
 TTreeReaderValue.cxx:94
 TTreeReaderValue.cxx:95
 TTreeReaderValue.cxx:96
 TTreeReaderValue.cxx:97
 TTreeReaderValue.cxx:98
 TTreeReaderValue.cxx:99
 TTreeReaderValue.cxx:100
 TTreeReaderValue.cxx:101
 TTreeReaderValue.cxx:102
 TTreeReaderValue.cxx:103
 TTreeReaderValue.cxx:104
 TTreeReaderValue.cxx:105
 TTreeReaderValue.cxx:106
 TTreeReaderValue.cxx:107
 TTreeReaderValue.cxx:108
 TTreeReaderValue.cxx:109
 TTreeReaderValue.cxx:110
 TTreeReaderValue.cxx:111
 TTreeReaderValue.cxx:112
 TTreeReaderValue.cxx:113
 TTreeReaderValue.cxx:114
 TTreeReaderValue.cxx:115
 TTreeReaderValue.cxx:116
 TTreeReaderValue.cxx:117
 TTreeReaderValue.cxx:118
 TTreeReaderValue.cxx:119
 TTreeReaderValue.cxx:120
 TTreeReaderValue.cxx:121
 TTreeReaderValue.cxx:122
 TTreeReaderValue.cxx:123
 TTreeReaderValue.cxx:124
 TTreeReaderValue.cxx:125
 TTreeReaderValue.cxx:126
 TTreeReaderValue.cxx:127
 TTreeReaderValue.cxx:128
 TTreeReaderValue.cxx:129
 TTreeReaderValue.cxx:130
 TTreeReaderValue.cxx:131
 TTreeReaderValue.cxx:132
 TTreeReaderValue.cxx:133
 TTreeReaderValue.cxx:134
 TTreeReaderValue.cxx:135
 TTreeReaderValue.cxx:136
 TTreeReaderValue.cxx:137
 TTreeReaderValue.cxx:138
 TTreeReaderValue.cxx:139
 TTreeReaderValue.cxx:140
 TTreeReaderValue.cxx:141
 TTreeReaderValue.cxx:142
 TTreeReaderValue.cxx:143
 TTreeReaderValue.cxx:144
 TTreeReaderValue.cxx:145
 TTreeReaderValue.cxx:146
 TTreeReaderValue.cxx:147
 TTreeReaderValue.cxx:148
 TTreeReaderValue.cxx:149
 TTreeReaderValue.cxx:150
 TTreeReaderValue.cxx:151
 TTreeReaderValue.cxx:152
 TTreeReaderValue.cxx:153
 TTreeReaderValue.cxx:154
 TTreeReaderValue.cxx:155
 TTreeReaderValue.cxx:156
 TTreeReaderValue.cxx:157
 TTreeReaderValue.cxx:158
 TTreeReaderValue.cxx:159
 TTreeReaderValue.cxx:160
 TTreeReaderValue.cxx:161
 TTreeReaderValue.cxx:162
 TTreeReaderValue.cxx:163
 TTreeReaderValue.cxx:164
 TTreeReaderValue.cxx:165
 TTreeReaderValue.cxx:166
 TTreeReaderValue.cxx:167
 TTreeReaderValue.cxx:168
 TTreeReaderValue.cxx:169
 TTreeReaderValue.cxx:170
 TTreeReaderValue.cxx:171
 TTreeReaderValue.cxx:172
 TTreeReaderValue.cxx:173
 TTreeReaderValue.cxx:174
 TTreeReaderValue.cxx:175
 TTreeReaderValue.cxx:176
 TTreeReaderValue.cxx:177
 TTreeReaderValue.cxx:178
 TTreeReaderValue.cxx:179
 TTreeReaderValue.cxx:180
 TTreeReaderValue.cxx:181
 TTreeReaderValue.cxx:182
 TTreeReaderValue.cxx:183
 TTreeReaderValue.cxx:184
 TTreeReaderValue.cxx:185
 TTreeReaderValue.cxx:186
 TTreeReaderValue.cxx:187
 TTreeReaderValue.cxx:188
 TTreeReaderValue.cxx:189
 TTreeReaderValue.cxx:190
 TTreeReaderValue.cxx:191
 TTreeReaderValue.cxx:192
 TTreeReaderValue.cxx:193
 TTreeReaderValue.cxx:194
 TTreeReaderValue.cxx:195
 TTreeReaderValue.cxx:196
 TTreeReaderValue.cxx:197
 TTreeReaderValue.cxx:198
 TTreeReaderValue.cxx:199
 TTreeReaderValue.cxx:200
 TTreeReaderValue.cxx:201
 TTreeReaderValue.cxx:202
 TTreeReaderValue.cxx:203
 TTreeReaderValue.cxx:204
 TTreeReaderValue.cxx:205
 TTreeReaderValue.cxx:206
 TTreeReaderValue.cxx:207
 TTreeReaderValue.cxx:208
 TTreeReaderValue.cxx:209
 TTreeReaderValue.cxx:210
 TTreeReaderValue.cxx:211
 TTreeReaderValue.cxx:212
 TTreeReaderValue.cxx:213
 TTreeReaderValue.cxx:214
 TTreeReaderValue.cxx:215
 TTreeReaderValue.cxx:216
 TTreeReaderValue.cxx:217
 TTreeReaderValue.cxx:218
 TTreeReaderValue.cxx:219
 TTreeReaderValue.cxx:220
 TTreeReaderValue.cxx:221
 TTreeReaderValue.cxx:222
 TTreeReaderValue.cxx:223
 TTreeReaderValue.cxx:224
 TTreeReaderValue.cxx:225
 TTreeReaderValue.cxx:226
 TTreeReaderValue.cxx:227
 TTreeReaderValue.cxx:228
 TTreeReaderValue.cxx:229
 TTreeReaderValue.cxx:230
 TTreeReaderValue.cxx:231
 TTreeReaderValue.cxx:232
 TTreeReaderValue.cxx:233
 TTreeReaderValue.cxx:234
 TTreeReaderValue.cxx:235
 TTreeReaderValue.cxx:236
 TTreeReaderValue.cxx:237
 TTreeReaderValue.cxx:238
 TTreeReaderValue.cxx:239
 TTreeReaderValue.cxx:240
 TTreeReaderValue.cxx:241
 TTreeReaderValue.cxx:242
 TTreeReaderValue.cxx:243
 TTreeReaderValue.cxx:244
 TTreeReaderValue.cxx:245
 TTreeReaderValue.cxx:246
 TTreeReaderValue.cxx:247
 TTreeReaderValue.cxx:248
 TTreeReaderValue.cxx:249
 TTreeReaderValue.cxx:250
 TTreeReaderValue.cxx:251
 TTreeReaderValue.cxx:252
 TTreeReaderValue.cxx:253
 TTreeReaderValue.cxx:254
 TTreeReaderValue.cxx:255
 TTreeReaderValue.cxx:256
 TTreeReaderValue.cxx:257
 TTreeReaderValue.cxx:258
 TTreeReaderValue.cxx:259
 TTreeReaderValue.cxx:260
 TTreeReaderValue.cxx:261
 TTreeReaderValue.cxx:262
 TTreeReaderValue.cxx:263
 TTreeReaderValue.cxx:264
 TTreeReaderValue.cxx:265
 TTreeReaderValue.cxx:266
 TTreeReaderValue.cxx:267
 TTreeReaderValue.cxx:268
 TTreeReaderValue.cxx:269
 TTreeReaderValue.cxx:270
 TTreeReaderValue.cxx:271
 TTreeReaderValue.cxx:272
 TTreeReaderValue.cxx:273
 TTreeReaderValue.cxx:274
 TTreeReaderValue.cxx:275
 TTreeReaderValue.cxx:276
 TTreeReaderValue.cxx:277
 TTreeReaderValue.cxx:278
 TTreeReaderValue.cxx:279
 TTreeReaderValue.cxx:280
 TTreeReaderValue.cxx:281
 TTreeReaderValue.cxx:282
 TTreeReaderValue.cxx:283
 TTreeReaderValue.cxx:284
 TTreeReaderValue.cxx:285
 TTreeReaderValue.cxx:286
 TTreeReaderValue.cxx:287
 TTreeReaderValue.cxx:288
 TTreeReaderValue.cxx:289
 TTreeReaderValue.cxx:290
 TTreeReaderValue.cxx:291
 TTreeReaderValue.cxx:292
 TTreeReaderValue.cxx:293
 TTreeReaderValue.cxx:294
 TTreeReaderValue.cxx:295
 TTreeReaderValue.cxx:296
 TTreeReaderValue.cxx:297
 TTreeReaderValue.cxx:298
 TTreeReaderValue.cxx:299
 TTreeReaderValue.cxx:300
 TTreeReaderValue.cxx:301
 TTreeReaderValue.cxx:302
 TTreeReaderValue.cxx:303
 TTreeReaderValue.cxx:304
 TTreeReaderValue.cxx:305
 TTreeReaderValue.cxx:306
 TTreeReaderValue.cxx:307
 TTreeReaderValue.cxx:308
 TTreeReaderValue.cxx:309
 TTreeReaderValue.cxx:310
 TTreeReaderValue.cxx:311
 TTreeReaderValue.cxx:312
 TTreeReaderValue.cxx:313
 TTreeReaderValue.cxx:314
 TTreeReaderValue.cxx:315
 TTreeReaderValue.cxx:316
 TTreeReaderValue.cxx:317
 TTreeReaderValue.cxx:318
 TTreeReaderValue.cxx:319
 TTreeReaderValue.cxx:320
 TTreeReaderValue.cxx:321
 TTreeReaderValue.cxx:322
 TTreeReaderValue.cxx:323
 TTreeReaderValue.cxx:324
 TTreeReaderValue.cxx:325
 TTreeReaderValue.cxx:326
 TTreeReaderValue.cxx:327
 TTreeReaderValue.cxx:328
 TTreeReaderValue.cxx:329
 TTreeReaderValue.cxx:330
 TTreeReaderValue.cxx:331
 TTreeReaderValue.cxx:332
 TTreeReaderValue.cxx:333
 TTreeReaderValue.cxx:334
 TTreeReaderValue.cxx:335
 TTreeReaderValue.cxx:336
 TTreeReaderValue.cxx:337
 TTreeReaderValue.cxx:338
 TTreeReaderValue.cxx:339
 TTreeReaderValue.cxx:340
 TTreeReaderValue.cxx:341
 TTreeReaderValue.cxx:342
 TTreeReaderValue.cxx:343
 TTreeReaderValue.cxx:344
 TTreeReaderValue.cxx:345
 TTreeReaderValue.cxx:346
 TTreeReaderValue.cxx:347
 TTreeReaderValue.cxx:348
 TTreeReaderValue.cxx:349
 TTreeReaderValue.cxx:350
 TTreeReaderValue.cxx:351
 TTreeReaderValue.cxx:352
 TTreeReaderValue.cxx:353
 TTreeReaderValue.cxx:354
 TTreeReaderValue.cxx:355
 TTreeReaderValue.cxx:356
 TTreeReaderValue.cxx:357
 TTreeReaderValue.cxx:358
 TTreeReaderValue.cxx:359
 TTreeReaderValue.cxx:360
 TTreeReaderValue.cxx:361
 TTreeReaderValue.cxx:362
 TTreeReaderValue.cxx:363
 TTreeReaderValue.cxx:364
 TTreeReaderValue.cxx:365
 TTreeReaderValue.cxx:366
 TTreeReaderValue.cxx:367
 TTreeReaderValue.cxx:368
 TTreeReaderValue.cxx:369
 TTreeReaderValue.cxx:370
 TTreeReaderValue.cxx:371
 TTreeReaderValue.cxx:372
 TTreeReaderValue.cxx:373
 TTreeReaderValue.cxx:374
 TTreeReaderValue.cxx:375
 TTreeReaderValue.cxx:376
 TTreeReaderValue.cxx:377
 TTreeReaderValue.cxx:378
 TTreeReaderValue.cxx:379
 TTreeReaderValue.cxx:380
 TTreeReaderValue.cxx:381
 TTreeReaderValue.cxx:382
 TTreeReaderValue.cxx:383
 TTreeReaderValue.cxx:384
 TTreeReaderValue.cxx:385
 TTreeReaderValue.cxx:386
 TTreeReaderValue.cxx:387
 TTreeReaderValue.cxx:388
 TTreeReaderValue.cxx:389
 TTreeReaderValue.cxx:390
 TTreeReaderValue.cxx:391
 TTreeReaderValue.cxx:392
 TTreeReaderValue.cxx:393
 TTreeReaderValue.cxx:394
 TTreeReaderValue.cxx:395
 TTreeReaderValue.cxx:396
 TTreeReaderValue.cxx:397
 TTreeReaderValue.cxx:398
 TTreeReaderValue.cxx:399
 TTreeReaderValue.cxx:400
 TTreeReaderValue.cxx:401
 TTreeReaderValue.cxx:402
 TTreeReaderValue.cxx:403
 TTreeReaderValue.cxx:404
 TTreeReaderValue.cxx:405
 TTreeReaderValue.cxx:406
 TTreeReaderValue.cxx:407
 TTreeReaderValue.cxx:408
 TTreeReaderValue.cxx:409
 TTreeReaderValue.cxx:410
 TTreeReaderValue.cxx:411
 TTreeReaderValue.cxx:412
 TTreeReaderValue.cxx:413
 TTreeReaderValue.cxx:414
 TTreeReaderValue.cxx:415
 TTreeReaderValue.cxx:416
 TTreeReaderValue.cxx:417
 TTreeReaderValue.cxx:418
 TTreeReaderValue.cxx:419
 TTreeReaderValue.cxx:420
 TTreeReaderValue.cxx:421
 TTreeReaderValue.cxx:422
 TTreeReaderValue.cxx:423
 TTreeReaderValue.cxx:424
 TTreeReaderValue.cxx:425
 TTreeReaderValue.cxx:426
 TTreeReaderValue.cxx:427
 TTreeReaderValue.cxx:428
 TTreeReaderValue.cxx:429
 TTreeReaderValue.cxx:430
 TTreeReaderValue.cxx:431
 TTreeReaderValue.cxx:432
 TTreeReaderValue.cxx:433
 TTreeReaderValue.cxx:434
 TTreeReaderValue.cxx:435
 TTreeReaderValue.cxx:436
 TTreeReaderValue.cxx:437
 TTreeReaderValue.cxx:438
 TTreeReaderValue.cxx:439
 TTreeReaderValue.cxx:440
 TTreeReaderValue.cxx:441
 TTreeReaderValue.cxx:442
 TTreeReaderValue.cxx:443
 TTreeReaderValue.cxx:444
 TTreeReaderValue.cxx:445
 TTreeReaderValue.cxx:446
 TTreeReaderValue.cxx:447
 TTreeReaderValue.cxx:448
 TTreeReaderValue.cxx:449
 TTreeReaderValue.cxx:450
 TTreeReaderValue.cxx:451
 TTreeReaderValue.cxx:452
 TTreeReaderValue.cxx:453
 TTreeReaderValue.cxx:454
 TTreeReaderValue.cxx:455
 TTreeReaderValue.cxx:456
 TTreeReaderValue.cxx:457
 TTreeReaderValue.cxx:458
 TTreeReaderValue.cxx:459
 TTreeReaderValue.cxx:460
 TTreeReaderValue.cxx:461
 TTreeReaderValue.cxx:462
 TTreeReaderValue.cxx:463
 TTreeReaderValue.cxx:464
 TTreeReaderValue.cxx:465