#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.