#include "TClonesArray.h"
#include "TSeed.h"
#include "TSeedList.h"
#include "TEventSample.h"

#include <iostream>

//_________________________________________________________________________________________________________________________
//
//      This is the base class for the user defined Seeds. 
// To fill data from an n-tuple into a seed::TEventSample, 
// seed::TEventSample::Create calls the method FillSeedData 
// for all activated seeds for each event and lets them read 
// data from the n-tuple and store it in a class, which is
// then written into seed::TEventSample's tree. 
// 
// To create a seed you have to derive your class from 
// seed::TSeed, stating which kind of object your seed 
// should handle (the data class):
//
//    TMySeed: public TSeed< TMyDataClass > {
//
// This class needs to define where the data will be stored
// at in the output tree (i.e. the branch name) - usually
// you should use the name of your seed here, to make it 
// clear how that data was generated.
//
// This branch name (called the seed's "name") is given in 
// constructor, which has to be declared by you, as well as
// the virtual default destructor:
//
//     public:
//       TMySeed(seed::TEventSample pES=NULL): TSeed("TMySeed",pES){};
//       virtual ~TMySeed() {};
// 
// The next two methods are needed for the data fransfer
// from the ntuple to the objects handled by your seed 
// (here, objects of type TMyDataClass):
//
//       void Init(seed::TSingleEntryTree& tree);
//       Bool_t FillSeedData(seed::TSingleEntryTree & tree,
//                           const Int_t iEventNo);
//
// Now, add the data members to store the data you need 
// from the ntuple:
//
//     private:
//       Int_t fnumObj; // number of objects in a given event
//       Float_t* fPosX; // fPosX[n] gets the (n+1)-th object's fPosX for a given event
//       Float_t* fPosY;
//       Float_t* fPosZ;
//    };
//
// To register your seed with seed::TSeedList (which makes
// it "available" to seed::TEventSample) you need to 
// create a global, static object of this type, which will
// not be referenced directly, so you can put it into an
// unnamed namespace:
//
//    namespace { static TMySeed globalstaticMySeed; }
//
// In your seed's Init method you set up the transfer from
// the ntuple, accessible via a seed::TSingleEntryTree
// (see seed::TSingleEntryTree::Transfer for how to set
// this up). In your seed's FillSeedData method you create
// new objects with NewEntry() (in this case of it creates
// an object of type TMyDataObject) and initialize it 
// using your seed's members (here one would create 
// fnumObj objects and initialize them with 
//   fPosX[0], fPosY[0], fPosZ[0]
//   fPosX[1], fPosY[1], fPosZ[1] ...
//
// For more details see the seed documentation.
//

ClassImp(seed::TSeedABC)

seed::TSeedABC::TSeedABC(const Char_t* cName, seed::TEventSample * pES):
    fPCA(NULL), fSET(NULL), fBEnabled(kFALSE), 
    fINumObjCreatedTotal(0), fINumObjCreatedEvent(0), 
    fCallStack(NULL), fName(cName)
{
// create a seed::TSeedABC for reading data from a seed::TEventSample

    if (pES) {
	fPCA=pES->GetCAPtrAddr(cName);
	if (!fPCA) {
	    std::cout 
		<< "ERROR in TSeedABC::TSeedABC(const Char_t*, seed::TEventSample): "
		<< "Either the seed " << cName << " is not enabled or it tries to access its data "
		<< "but there is no data for it in the current file (the branch does not exist)!"
		<< std::endl;
	    TEventSample::AddError();
	}
    }
    else TSeedList::GetInstance()->Add(this);
}

 TBranch* seed::TSeedABC::CreateBranch(TClonesArray ** ppCA, TTree * pTree)
{
// creates a branch in the given tree, and sets the branch's address to 
// the address of the clones array.

    return pTree->Branch(GetName(), "TClonesArray", ppCA, 10000, 99);
}

 Bool_t seed::TSeedABC::Init(seed::TSingleEntryTree& tree){
// This method is called to update the mapping from ntuple data
// to TSeedABC derived classes. It should be overloaded by classes
// deriving from TSeedABC, making use of methods like
// TSingleEntryTree::TransferDouble etc.

    return kTRUE;
}

 void seed::TSeedABC::SetFillOwner(TSingleEntryTree * tree, TClonesArray * const * pCA){
// called before filling to signal "ownership" for this seed 

    if (tree && tree->GetDebug()>1)
	std::cout << "Seed " << GetName() 
		  << " initialized to fill." << std::endl;
    if (pCA && *pCA) (*pCA)->Delete(); // reset array entries from previous event
    fPCA = pCA;
    fSET = tree;
}


 Bool_t seed::TSeedABC::PreFillSeedData(
    std::list< seed::TSeedABC* >& callStack,
    Int_t iEventNo) 
{
// called before TSeedABC::FillSeedData is called. Cleanup from the previous
// n-tuple entry and initialization for this entry

    if (fPCA && *fPCA) (*fPCA)->Delete(); // reset array entries from previous event

    fINumObjCreatedEvent = 0;
    fCallStack = &callStack;

    if (fSET && fSET->GetDebug()>2)
       std::cout<<GetName()<<"'s FillSeedData called."<<std::endl;
    Bool_t bRet = FillSeedData(*fSET, iEventNo);
    return bRet;
};
	 

 seed::TSeedABC* seed::TSeedABC::GetSeedData(const char* strLabel) {
// Called from within FillSeedData, this method returns a pointer to the 
// TSeedABC derived class holding the data of the seed with name 
// strLabel for the current n-tuple entry. With this method cross references
// between seeds are possible. One can e.g. reference the data of a
// seed declared with 
//    TSeedA: public TSeed< TDataClassA >
// from within TSeedB::FillSeedData:
//
//    TSeed< TDataClassA > * pSeedA = GetSeedData("TSeedA");
//
// and access its objects via 
//    TDataClassA a = (*pSeedDataA)[0];
//
// This method always fills the seed data in the order necessary to
// satisfy all dependencies (i.e. if SeedA needs SeedB, SeedB will be 
// filled first). If a circular dependency is encountered, the program
// exits with an error message showing the path of the circular dependency.

    if (!fSET) {
	std::cout<< "ERROR in TSeedABC::GetSeedData: "
		 << "No TSingleENtryTree is set, presumably"
		 << "This method was not called within FillSeedData! "
		 << "Use TEventSample::GetSeed outside of FillSeedData."
		 << std::endl;
	TEventSample::AddError();
	return NULL;
    };

    if (fSET->GetDebug()>2)
	std::cout << "Seed " << GetName() <<" requested data from "
		  <<" seed " << strLabel <<". "<<std::endl;

    // store current branch, index
    TBranch* pB=fSET->GetCurrentBranch();
    Int_t iIdx=fSET->GetCurrentIndex();

    TSeedABC* pSeed = TSeedList::GetInstance()->SeedRequestsSeedData( *fCallStack, strLabel );

    // set last branch, index
    if (pB) fSET->SetBranch(pB->GetName());
    fSET->SetIndex(iIdx);

    return pSeed;
}

 Long_t seed::TSeedABC::Size() const
{
// returns the number of available objects of this seed::TSeedDataABC's seed in the currently
// selected event.

   if (fPCA && *fPCA)
      return (*fPCA)->GetEntriesFast();
   else {
      std::cout << "WARNING in seed::TSeedABC::Size(): " 
		<< "TClonesArray no set for seed " <<GetName()
		<< "! Did you pass a TEventSample* to the constructor? "
		<< "If you did please consult prior error messages."
		<< std::endl;
      TEventSample::AddWarning(); 
      return -1;
   };
}

 Bool_t seed::TSeedABC::FillSeedData(seed::TSingleEntryTree & tree,
				    const Int_t iEventNo) 
{
// Produces output, filling ntuple data into objects (the
// data classes) requested by TSeed::NewEntry. See the class
// documentation of TSeedABC for details.
//
// Has to be overloaded by deriving classes to produce output.
//
// Parameters
//   tree:     A seed::TSingleEntryTree allowing to access the ntuple 
//             entry currently being transformed. If principle access 
//             to this object is not needed for FillSeedData, as the
//             data access (transfer to members, see 
//             seed::TSingleEntryTree::Transfer) should be setup in 
//             Init.
//   iEventNo: Number of the current entry, always starting at 0 even 
//             if seed::TEventSample::SetFirstEntry has been called
//             

    std::cout << "ERROR in seed::TSeedABC::FillSeedData: "
	      << "This method has to be overloaded in order "
	      << "to allow your seed to process data. "
	      << "Seed " << GetName() <<" will not create "
	      << "any output." <<std::endl;
    TEventSample::AddError(); 
    Enable(kFALSE);
    return kFALSE;
}

 void seed::TSeedABC::Enable(Bool_t bEnable) {
// Enables a seed for data transfer / reading
    if(!(fBEnabled == bEnable))
	std::cout << "Seed " << GetName() << (bEnable?" enabled.":" disabled.") << std::endl;
    fBEnabled = bEnable;
};


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.