// TSingleEntryTree.cxx
// Author: Axel Naumann <mailto:axel@fnal.gov> 10/02/2001
//@(#) 04/04/2002 AN

#include "TSingleEntryTree.h" 
#include "TEventSample.h" 
#include <iostream>

R__EXTERN TTree *gTree; // declare the gTree variable

//_________________________________________________________________________________________________________________________
//
// Wrapper class for an n-tuple tree.
// This class in constructed giving a tree with an event selected by seed::TEventSample.
// You can read data out of the n-tuple using the GetValue methods.

ClassImp(seed::TSingleEntryTree)


 Double_t seed::TSingleEntryTree::GetValue(const Char_t *strBranch,
                                        const Char_t *cLeaf,
                                        const Int_t iIndex)
{
// Get value of leaf in branch, given an index of the leaf
// 
// Parameters
// strBranch: branch name to access
// cLeaf:  leaf name to access
// iIndex:  index of the leaf to read

      TBranch *pB = fPTree->GetBranch(strBranch);
      if (!pB) {
         std::
             cout <<
             "ERROR in TSingleEntryTree::GetValue(const Char_t*, const Char_t*, const Int_t): Branch ""
             << strBranch << "" not found!" << std::endl;
	 TEventSample::AddError(); 
         return -999.;
      };
      TLeaf *pL = pB->GetLeaf(cLeaf);
      if (!pL) {
         std::
             cout <<
             "ERROR in TSingleEntryTree::GetValue(const Char_t*, const Char_t*, const Int_t): Leaf ""
             << cLeaf << "" in Branch "" << strBranch << "" not found!"
             << std::endl;
	 TEventSample::AddError(); 
         return -998.;
      };
      if (iIndex < pL->GetLen()){
         if (fIDebug>3)
            std::cout<<"TSingleEntryTree::GetValue(""<<strBranch<<"", ""
               <<cLeaf<<"", "<<iIndex<<") read "<<pL->GetValue(iIndex)<<std::endl;
         return pL->GetValue(iIndex);
      }
      else
         std::
             cout <<
             "ERROR in TSingleEntryTree::GetValue(const Char_t*, const Char_t*, const Int_t): Index Leaf "
             << cLeaf << "[" << iIndex << "] out of bounds (max index is "
             << pL->GetLen() - 1 << ")!" << std::endl;
      TEventSample::AddError(); 
      return -998.;
};


 Double_t seed::TSingleEntryTree::GetValue(const Char_t *cLeaf,
                                        const Int_t iIndex)
{
// Get value of the leaf "cLeaf" in branch as set by SetBranch. 
// * If no Index is given...
//  * if leaf has only one entry, this entry will be returned
//  * else the entry with index set by SetIndex is returned
// * else 
//  * if leaf has only one entry, this entry will be returned
//  * the entry with index given as parameter is returned. 

   if (fPCurrentBranch == 0) {
      std::
          cout <<
          "ERROR in TSingleEntryTree::GetValue(const Char_t*, Int_t): Can't access leaf '"
          << cLeaf << "'. No branch set (or prior SetBranch failed)!" <<
          std::endl;
      TEventSample::AddError(); 
      return -999.;
   };
   TLeaf *pLeaf = fPCurrentBranch->GetLeaf(cLeaf);
   if (!pLeaf) {
      std::
          cout <<
          "ERROR in TSingleEntryTree::GetValue(const Char_t*, Int_t): Leaf ""
          << cLeaf << "" not found!" << std::endl;
      TEventSample::AddError(); 
      return -998.;
   };
   Int_t iLeafCount = pLeaf->GetLen();
   if (iLeafCount != 1) {
      if (iIndex == -1) {
         if (fICurrentIndex < iLeafCount){
            if (fIDebug>3)
               std::cout<<"TSingleEntryTree::GetValue(""
                  <<cLeaf<<"", "<<iIndex<<") with current index set to "
                  <<fICurrentIndex<<" read "<<pLeaf->GetValue(fICurrentIndex)<<std::endl;
            return pLeaf->GetValue(fICurrentIndex);
         }
         else {
            std::
                cout <<
                "ERROR in TSingleEntryTree::GetValue(const Char_t*, Int_t): Index "
                << cLeaf << "[" << fICurrentIndex <<
                "] out of bounds (max index is " << iLeafCount -
                1 << ")!" << std::endl;
	    TEventSample::AddError(); 
            return -997.;
         };
      } else if (iIndex < iLeafCount){
            if (fIDebug>3)
               std::cout<<"TSingleEntryTree::GetValue(""
                  <<cLeaf<<"", "<<iIndex<<") read "<<pLeaf->GetValue(iIndex)<<std::endl;
         return pLeaf->GetValue(iIndex);
      }
      else {
         std::
             cout <<
             "ERROR in TSingleEntryTree::GetValue(const Char_t*, Int_t): Index "
             << cLeaf << "[" << iIndex << "] out of bounds (max index is "
             << iLeafCount - 1 << ")!" << std::endl;
	 TEventSample::AddError(); 
         return -996.;
      };
   } else {
      if (fIDebug>3)
         std::cout<<"TSingleEntryTree::GetValue(""
            <<cLeaf<<"", "<<iIndex<<") read "<<pLeaf->GetValue(0)<<std::endl;
      return pLeaf->GetValue(0);
   }
};




/** GetValue for bools */
 Bool_t seed::TSingleEntryTree::GetValueBool(const Char_t *strBranch, const Char_t *cLeaf,
					    const Int_t iIndex) {
// GetValue for bools. See seed::TSingleEntryTree::GetValue for details
    return (Bool_t) GetValue(strBranch, cLeaf, iIndex);
}

 Bool_t seed::TSingleEntryTree::GetValueBool(const Char_t *cLeaf, const Int_t iIndex){
// GetValue for bools. See seed::TSingleEntryTree::GetValue for details
    return (Bool_t) GetValue(cLeaf, iIndex);
}

/** GetValue for ints */
 Int_t seed::TSingleEntryTree::GetValueInt(const Char_t *strBranch, const Char_t *cLeaf,
					  const Int_t iIndex){

// GetValue for ints. See seed::TSingleEntryTree::GetValue for details
    return (Int_t) GetValue(strBranch, cLeaf, iIndex);
}

 Int_t seed::TSingleEntryTree::GetValueInt(const Char_t *cLeaf, const Int_t iIndex){
// GetValue for ints. See seed::TSingleEntryTree::GetValue for details
    return (Int_t) GetValue(cLeaf, iIndex);
}




/** GetValue for arrays of doubles */ 
 Double_t* seed::TSingleEntryTree::GetValueArr(const Char_t *strBranch, const Char_t *cLeaf){
// Get pointer to values of leaf in branch
// 
// Parameters
// strBranch: branch name to access
// cLeaf:  leaf name to access
//
// REMEMBER: Arrays are NOT very object oriented...

      TBranch *pB = fPTree->GetBranch(strBranch);
      if (!pB) {
         std::
             cout <<
             "ERROR in TSingleEntryTree::GetValueArr(const TString&, const Char_t*): Branch ""
             << strBranch << "" not found!" << std::endl;
	 TEventSample::AddError(); 
         return NULL;
      };
      TLeaf *pL = pB->GetLeaf(cLeaf);
      if (!pL) {
         std::
             cout <<
             "ERROR in TSingleEntryTree::GetValueArr(const TString&, const Char_t*): Leaf ""
             << cLeaf << "" in Branch "" << strBranch << "" not found!"
             << std::endl;
	 TEventSample::AddError(); 
         return NULL;
      };
      return (Double_t*) pL->GetValuePointer();
}

 Double_t* seed::TSingleEntryTree::GetValueArr(const Char_t *cLeaf){
// Get pointer to values of the leaf "cLeaf" in branch as set by SetBranch. 
//
// REMEMBER: Arrays are NOT very object oriented...

   if (fPCurrentBranch == 0) {
      std::
          cout <<
          "ERROR in TSingleEntryTree::GetValueArr(const Char_t*): Can't access leaf '"
          << cLeaf << "'. No branch set (or prior SetBranch failed)!" <<
          std::endl;
      TEventSample::AddError(); 
      return NULL;
   };
   TLeaf *pLeaf = fPCurrentBranch->GetLeaf(cLeaf);
   if (!pLeaf) {
      std::
          cout <<
          "ERROR in TSingleEntryTree::GetValueArr(const Char_t*): Leaf ""
          << cLeaf << "" not found!" << std::endl;
      TEventSample::AddError(); 
      return NULL;
   };
   return (Double_t*)pLeaf->GetValuePointer();
}


/** GetValue for arrays of bools */
 Bool_t* seed::TSingleEntryTree::GetValueBoolArr(const Char_t *strBranch, const Char_t *cLeaf){
// Get pointer to values of leaf in branch
// 
// Parameters
// strBranch: branch name to access
// cLeaf:  leaf name to access
//
// REMEMBER: Arrays are NOT very object oriented...

    return (Bool_t*) GetValueArr(strBranch, cLeaf);
}

 Bool_t* seed::TSingleEntryTree::GetValueBoolArr(const Char_t *cLeaf){
// Get pointer to values of the leaf "cLeaf" in branch as set by SetBranch. 
//
// REMEMBER: Arrays are NOT very object oriented...
    return (Bool_t*) GetValueArr(cLeaf);
}

/** GetValue for arrays of ints */
 Int_t* seed::TSingleEntryTree::GetValueIntArr(const Char_t *strBranch, const Char_t *cLeaf){
// Get pointer to values of leaf in branch
// 
// Parameters
// strBranch: branch name to access
// cLeaf:  leaf name to access
//
// REMEMBER: Arrays are NOT very object oriented...

    return (Int_t*) GetValueArr(strBranch, cLeaf);
}

 Int_t* seed::TSingleEntryTree::GetValueIntArr(const Char_t *cLeaf){
// Get pointer to values of the leaf "cLeaf" in branch as set by SetBranch. 
//
// REMEMBER: Arrays are NOT very object oriented...

    return (Int_t*) GetValueArr(cLeaf);
}

 Bool_t seed::TSingleEntryTree::TransferGeneric(
   const char* cTypeName, void* pTarget,  
   const Char_t* cLeafName,const Char_t* cBranchName, Int_t iSize) {
// internal method.
// adds pTarget to the map of targets for ntuple data updates
// and checks that the size of the array the TSingleEntryTree will be
// writing to is big enough for the number of values (using iSize)
// Used by the Transfer methods.

  TLeaf* pL = GetNtupleLeaf(cLeafName, cBranchName); 
  TLeaf* pLC= NULL;
 
  if(pL) {

    // Check array size
    Int_t iCountVal;
    Int_t iMaxVals=1; // the number of values in the tree
    if(iSize>0) {

      // GetLeafCounter requires gTree to point to current tree
      //gTree=fPTree; // this doesn't work for leaves on friend trees
      gTree = pL->GetBranch()->GetTree();

      pLC = pL->GetLeafCounter(iCountVal);
      // here are the cases:
      // leaf; -> pLC==NULL, iCountVal==1;
      // leaf[12]; -> pLC==NULL, iCountVal==12;
      // leaf[otherleaf]; -> pLC==&otherleaf; iCountVal==1
      // leaf[12][otherleaf]; -> pLC==&otherleaf; iCountVal==12

      if(iCountVal<0) { 
	std::cerr<<"ERROR TSingleEntryTree::TransferGeneric: Error in GetLeafCounter, maybe it couldn't find this leaf. "<<iCountVal<<"  "<<pLC<<std::endl; 
	std::cerr<<"      Disabling array size check- your data will likely be ok."<<std::endl;
	TEventSample::AddError();
	
	iSize=-1; // disable check
      }
    }

    if(iSize>=0) {
      if (pLC || iCountVal>1 ) {
	if (pLC) iMaxVals *= (Int_t) pLC->GetMaximum();
	else if (iCountVal>1) iMaxVals*=iCountVal;
      };
    
      if(iMaxVals>iSize) {
	std::cout<<"ERROR in TSingleEntryTree::TransferGeneric: " 
		 <<"The leaf "<<cLeafName
		 <<" in branch " << (cBranchName?cBranchName:(fPCurrentBranch?fPCurrentBranch->GetName():"UNKNOWN")) 
		 <<" contains "<<iMaxVals
		 <<" values. There only is room to store "<<iSize
		 <<" values in the array in the seed."<<std::endl;
	TEventSample::AddError();
	return kFALSE;
      }
    }
    
    fDataMap[pL].push_back(pTarget); 
    if (strcmp(pL->GetTypeName(),cTypeName)) { 
      std::cout<< "WARNING in TSingleEntryTree::TransferGeneric: " 
	       << "The leaf " << cLeafName 
	       << " in branch " << (cBranchName?cBranchName:(fPCurrentBranch?fPCurrentBranch->GetName():"UNKNOWN")) 
	       << " does not contain " << cTypeName <<"'s! " 
	       << "Most probably this will result in currupt data being read out!" 
	       << std::endl; 
        TEventSample::AddWarning();  
    } 
    if (fIDebug>2) {
      std::cout<< "A new target for leaf " << pL->GetName();
      TBranch* pB = pL->GetBranch();
      if (pB) std::cout << " in branch " << pB->GetName();
      std::cout << " has been registered."<<std::endl;
    };
    return kTRUE; 

  } // if(pL)
  else { 
    std::cout<<"WARNING in TSingleEntryTree::TransferGeneric: " 
	     << "The leaf " << cLeafName 
	     << " in branch " << (cBranchName?cBranchName:fPCurrentBranch->GetName()) 
	     << " does not exist! "<<std::endl; 
    TEventSample::AddWarning(); 
    return kFALSE; 
  } 

}

 Bool_t seed::TSingleEntryTree::TransferGenericArr(
   const char* cTypeName, void** pTarget,   
   const Char_t* cLeafName,const Char_t* cBranchName, Int_t iSize) {
// internal method. 
// adds pTarget to the map of targets for ntuple data updates 
// and checks that the size of the array the TSingleEntryTree will be
// writing to is big enough for the number of values (using iSize)
//
// Used by the Transfer methods. 
 
  TLeaf* pL = GetNtupleLeaf(cLeafName, cBranchName); 
  TLeaf* pLC= NULL;

  // Check array size
  Int_t iCountVal;
  Int_t iMaxVals; // the number of values in the tree
  if(iSize>=0) {

    // gTree must point to the current tree for GetLeafCounter
    //gTree=fPTree; // this doesn't work for leaves on friend trees
    gTree = pL->GetBranch()->GetTree();

    pLC = pL->GetLeafCounter(iCountVal);
    // here are the cases:
    // leaf; -> pLC==NULL, iCountVal==1;
    // leaf[12]; -> pLC==NULL, iCountVal==12;
    // leaf[otherleaf]; -> pLC==&otherleaf; iCountVal==1
    // leaf[12][otherleaf]; -> pLC==&otherleaf; iCountVal==12

    if(iCountVal<0) { 
      std::cerr<<"ERROR TSingleEntryTree::TransferGeneric: Error in GetLeafCounter. "<<iCountVal<<"  "<<pLC<<std::endl; 
      std::cerr<<"      Disabling array size check- your data will likely be ok."<<std::endl;
      TEventSample::AddError();
      // in root 3.03 this happens if you're checking a leaf that's on a friend
      // tree.

      iSize=-1; // disable check
    }
  }

  if(iSize>=0) {
    if (pLC || iCountVal>1 ) {
      if (pLC) iMaxVals = (Int_t) GetNtupleLeaf(pLC->GetName())->GetValue();
      else if (iCountVal>1) iMaxVals=iCountVal;
    }
    else iMaxVals = 1;

    if(iMaxVals>iSize) {
      std::cout<<"ERROR in TSingleEntryTree::TransferGeneric: " 
	       <<"The leaf "<<cLeafName
	       <<" in branch " << (cBranchName?cBranchName:(fPCurrentBranch?fPCurrentBranch->GetName():"UNKNOWN")) 
	       <<" contains "<<iMaxVals
	       <<" values. There only is room to store "<<iSize
	       <<" values in the array in the seed."<<std::endl;
      TEventSample::AddError();
      return kFALSE;
    }
  }
  
  if (pL) fDataMapArr[pTarget]=pL; 
  else { 
    std::cout<<"WARNING in TSingleEntryTree::TransferGenericArr: " 
	     << "The leaf " << cLeafName 
	     << " in branch " << (cBranchName?cBranchName:(fPCurrentBranch?fPCurrentBranch->GetName():"UNKNOWN")) 
	     << " does not exist! "<<std::endl; 
    TEventSample::AddWarning();  
    return kFALSE; 
  } 
  if (pL && strcmp(pL->GetTypeName(),cTypeName)) { 
    std::cout<< "WARNING in TSingleEntryTree::TransferGenericArr: " 
	     << "The leaf " << cLeafName 
	     << " in branch " << (cBranchName?cBranchName:(fPCurrentBranch?fPCurrentBranch->GetName():"UNKNOWN")) 
	     << " does not contain " << cTypeName << "'s! " 
	     << "Most probably this will result in currupt data being read out!" 
	     << std::endl; 
    TEventSample::AddWarning();  
  } 
  if (fIDebug>2) {
      std::cout<< "A new target array for leaf " << pL->GetName();
      TBranch* pB = pL->GetBranch();
      if (pB) std::cout << " in branch " << pB->GetName();
      std::cout << " has been registered."<<std::endl;
  };
  return kTRUE; 
}
 

 Bool_t seed::TSingleEntryTree::Transfer(Double_t &pVal, const Char_t* cLeafName, 
				      const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's value.
// and checks that the size of the array the TSingleEntryTree will be
// writing to is big enough for the number of values (using iSize)
//
// Used for members of classes deriving from TSeedABC.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGeneric("Double_t", &pVal, cLeafName, cBranchName, iSize);
}

 Bool_t seed::TSingleEntryTree::Transfer(Float_t &pVal, const Char_t* cLeafName, 
				      const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's value.
// Used for members of classes deriving from TSeedABC.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGeneric("Float_t", &pVal, cLeafName, cBranchName, iSize); 
}

 Bool_t seed::TSingleEntryTree::Transfer(Int_t &pVal, const Char_t* cLeafName, 
					 const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's value.
// Used for members of classes deriving from TSeedABC.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGeneric("Int_t", &pVal, cLeafName, cBranchName, iSize); 
}

 Bool_t seed::TSingleEntryTree::Transfer(Bool_t &pVal, const Char_t* cLeafName, 
					  const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's value.
// Used for members of classes deriving from TSeedABC.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGeneric("Bool_t", &pVal, cLeafName, cBranchName, iSize); 
}

 Bool_t seed::TSingleEntryTree::Transfer(Double_t* &pVal, const Char_t* cLeafName, 
				      const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep the array pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's values.
// Used for members of classes deriving from TSeedABC and leaves holding a
// one dimensional array for each entry/event.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGenericArr("Double_t", (void**)&pVal, cLeafName, cBranchName, iSize);
}

 Bool_t seed::TSingleEntryTree::Transfer(Float_t* &pVal, const Char_t* cLeafName, 
				      const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep the array pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's values.
// Used for members of classes deriving from TSeedABC and leaves holding an
// one dimensional array for each entry/event.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGenericArr("Float_t", (void**)&pVal, cLeafName, cBranchName, iSize);
}

 Bool_t seed::TSingleEntryTree::Transfer(Int_t* &pVal, const Char_t* cLeafName, 
					 const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep the array pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's values.
// Used for members of classes deriving from TSeedABC and leaves holding an
// one dimensional array for each entry/event.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGenericArr("Int_t", (void**)&pVal, cLeafName, cBranchName, iSize);  
}

 Bool_t seed::TSingleEntryTree::Transfer(Bool_t* &pVal, const Char_t* cLeafName, 
					  const Char_t* cBranchName, Int_t iSize){
// Tells the TSingleEntryTree to keep the array pVal updated with ntuple data,
// i.e. if a new tree entry is selected it will update pVal with
// this entry's values.
// Used for members of classes deriving from TSeedABC and leaves holding an
// one dimensional array for each entry/event.
//
// Parameters
//   pVal:         variable where ntuple data should be transferred to
//   cLeafName:    name of a leaf. This leaf's data will be transferred to pVal
//   cBranchName:  name of a branch. Can be NULL (or not given) in which case
//                 the currently selected branch (via SetBranch) is assumed
//   iSize:        the size of the array pVal to allow checking of the array
//                 boundary

  return TransferGenericArr("Bool_t", (void**)&pVal, cLeafName, cBranchName, iSize);  
}

 TLeaf* seed::TSingleEntryTree::GetNtupleLeaf(const Char_t* cLeafName, const Char_t* cBranchName){
// internal method
// returns the leaf named cLeafName in branch cBranchName or if cBranchName==NULL in the 
// branch currently selected by SetBranch

    TBranch* pB;
    if (cBranchName) {
	AddBranchRead(cBranchName);
	pB = fPTree->GetBranch(cBranchName);
	if (!pB) {
	    std::cout<<"ERROR in TSingleEntryTree::GetNtupleLeaf: "
		     <<"There is no branch called '"<<cBranchName<<"'."<< std::endl;
	    TEventSample::AddError(); 
	    return NULL;
	};
    } else {
	if (!fPCurrentBranch) {
	    std::cout<<"ERROR in TSingleEntryTree::GetNtupleLeaf: "
		     <<"No branch selected. "
		     <<"Maybe a prior TSingleEntryTree::SetBranch failed. "
		     <<"If not, call TSingleEntryTree::SetBranch first or provide " 
		     <<"the branch name as argument." << std::endl;
	    TEventSample::AddError(); 
	    return NULL;
	};
	pB = fPCurrentBranch;
    }

    TLeaf* pL = pB->GetLeaf(cLeafName);
    if (!pL) {
	std::cout<<"ERROR in TSeedABC::StoresNtupleData(const Char_t*, const Char_t*, Double_t *): "
		 <<"Current TSingleEntryTree (=ntuple)'s branch ";
	if (cBranchName) std::cout<<"'"<<cBranchName<<"' ";
	std::cout<<"does not have a leaf called '"<<cLeafName<<"'."<< std::endl;
        TEventSample::AddError(); 
	return NULL;
    };

    return pL;
}

 Int_t seed::TSingleEntryTree::SetEntry(Int_t iEntry) {
// selects a new entry in the tree and updates all transfer requests

    fIEntry = iEntry;
    Int_t iRet = fPTree->GetEntry(fIEntry);

    // PB: also GetEntry on each of the friend trees
    TList* PListFriends = fPTree->GetListOfFriends();
    if(PListFriends) {
	
	TIter nextf(PListFriends);
	TFriendElement *fe;
	while ((fe = (TFriendElement*)nextf())) {
	    TTree *t = fe->GetTree();
	    if (t) t->GetEntry(fIEntry);
	}
    }
    // end PB

    TransferEvent();
    return iRet;
};

 void seed::TSingleEntryTree::UpdateTransfers(){
// internal method.
// transfers data from ntuple to entries in transfer maps

    std::map<TLeaf*, std::list <void*> >::iterator iDLeaf;
    for (iDLeaf=fDataMap.begin(); iDLeaf!=fDataMap.end(); iDLeaf++) {
	std::list<void*> lD = (*iDLeaf).second;
	TLeaf* pL = (*iDLeaf).first;
	if (pL && lD.size()>0)
	    pL->SetAddress(*(lD.begin()));
	if (fIDebug>2){
	    std::cout << "Added " << lD.size() << " transfer request for leaf " << pL->GetName();
	    TBranch* pB = pL->GetBranch();
	    if (pB) std::cout << " in branch " << pB->GetName();
	    std::cout << "." <<std::endl;
	};
    };

    std::map<void**, TLeaf*>::iterator iDALeaf;
    for (iDALeaf=fDataMapArr.begin(); iDALeaf!=fDataMapArr.end(); iDALeaf++) {
	void** pD = (*iDALeaf).first;
	TLeaf* pL = (*iDALeaf).second;
	if (pD && pL) {
	    (*pD)=pL->GetValuePointer();
	    if (fIDebug>3){
		std::cout << "Updated array transfer request for leaf " << pL->GetName();
		TBranch* pB = pL->GetBranch();
		if (pB) std::cout << " in branch " << pB->GetName();
		std::cout << "."<<std::endl;
	    };
	};
    };
}

 void seed::TSingleEntryTree::TransferEvent(){
// internal method.
// Updates the leaf data of the current event that was requested by 
// Transfer calls.
 
    std::map<TLeaf*, std::list <void*> >::iterator iDLeaf; 
    for (iDLeaf=fDataMap.begin(); iDLeaf!=fDataMap.end(); iDLeaf++) { 
        std::list<void*> lD = (*iDLeaf).second; 
        TLeaf* pL = (*iDLeaf).first; 
        if (pL && lD.size()>1) { 
	  Int_t iSize=pL->GetLen()*pL->GetLenType();
	  std::list<void*>::iterator iTarget=lD.begin();
	  for (iTarget++; iTarget!=lD.end(); iTarget++) 
	    memcpy(*iTarget,pL->GetValuePointer(), iSize); 
	} 
	if (fIDebug>3){ 
	  std::cout << "Updated " << lD.size() << " transfer request for leaf " << pL->GetName(); 
	  TBranch* pB = pL->GetBranch(); 
	  if (pB) std::cout << " in branch " << pB->GetName(); 
	  std::cout << "." <<std::endl; 
	}; 
    }; 
}

 void seed::TSingleEntryTree::ResetTransfers(){
// internal method.
// clears the transfer maps 
    fDataMap.clear();
    fDataMapArr.clear();
}

 void seed::TSingleEntryTree::NotifyInitSeed(){ 
// Called after an activated seed's Init method has been called.
// Here, TSingleEntryTree checks whether the seed has requested data 
// from a certain branch, if not, all input branches will be enabled.

  if (!fSeedRequestedBranch) 
    fBranchesRead="*"; 
  fSeedRequestedBranch=kFALSE; 
} 

 void seed::TSingleEntryTree::NotifyInitSeedBegin(){
// Initializes branch check as described in 
// seed::TSingleEntryTree::NotifyInitSeed.

  fSeedRequestedBranch=kFALSE;
}

 void seed::TSingleEntryTree::NotifyInitSeedEnd(){
// called after all activated seeds' Init methods have been called.

}


ROOT page - Class index - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.