Problems understanding TTrees and TFiles

Hi,

I’m very new to ROOT, and I am having a huge amount of trouble trying to understand TTrees, TFiles, Events and their relationship to one another.

From the examples, I cannot see how you attach a TTree to a specific file. The examples show how to create a file, then how to create a tree, but the tree never references the file. I cannot work out how to get a particular tree to be stored in a certain file.

The code below is what I am trying to get working. I am reading in large amounts of text from a file, creating my event, and then want to store the event in a .ROOT file (the name of the file is dependant on certain attributes of the record I have read in from the text file).

So to summarise, I have already created my event (pEvent), and just want to store it in a tree in a certain file. The following throws an exeption no matter what I try.

// Create a ROOT File
TFile hfile(strRootFile,“RECREATE”,“Data”);

// Create a ROOT Tree
TTree tree(strRootTree,“A Root tree”);

TBranch *eventBranch = tree.GetBranch( strRootTree );
if( eventBranch == NULL )
{
eventBranch = tree.Branch( strRootClass, strRootClass, pEvent, 32000, 99);
}
tree.Fill();

Any help is very welcome.

All the best,

Tony.

if pEvent is a pointer to say MyEvent, you should pass the address of the pointer and not the value of the pointer, ie replace

TBranch *eventBranch = tree.GetBranch( strRootTree ); if( eventBranch == NULL ) { eventBranch = tree.Branch( strRootClass, strRootClass, pEvent, 32000, 99); } by

Rene

Many thanks, that seems to have got me going again.

All the best,

Tony.

Hi again,

Can you advise me a little more? I have a function below, I am not certain it is what I want it to do.

Basically I have an event (pEvent) and want to put it into a certain file on a certain branch. I have the file name and branch name, but I cannot figure out from the ROOT help/documentation how to make sure my event gets stored in the correct place.

I am totally lost at the moment.

All the best and thanks in advance for any assistance.

Tony.[code]void CROOTFileManager::Add(CMyEvent *pEvent)
{
//first get the filename needed, and then see if we have the file open.
//if open, append,
//if not open, create and add

CStdString strRootFile = pEvent->GetROOTFileAsString();
CStdString strRootTree = pEvent->GetROOTTreeAsString();
CStdString strRootClass = pEvent->GetROOTClassAsString();

TTree *tree = NULL;
TFile *hfile = NULL;
TBranch *eventBranch = NULL;

int nFile = m_FileNames.Find(strRootFile);

if ( nFile != -1 )
{
	//get the file pointer
	hfile = m_FilePtrs.GetAt(nFile);
	tree = m_TreePtrs.GetAt(nFile);
	eventBranch = m_BranchPtrs.GetAt(nFile);
}
else
{
	//first check to see if the file we want exists.
	hfile = new TFile(strRootFile,"UPDATE","Data");
	if ( hfile == NULL )
	{
		// Create a ROOT File
		hfile = new TFile(strRootFile,"RECREATE","Data");

		// Create a ROOT Tree
		tree = new TTree(strRootTree,strRootClass);
	}
	else
	{
		// Create a ROOT Tree
		tree = (TTree*)hfile->Get(strRootTree);

		if ( tree == NULL )
		{
			// Create a ROOT Tree
			tree = new TTree(strRootTree,"");
		}
	}

	eventBranch = tree->GetBranch( strRootClass );
	if( eventBranch == NULL )
	{
		eventBranch = tree->Branch( strRootClass, strRootClass, &pEvent, 32000, 99);
	}

	m_FileNames.Add(strRootFile);
	m_FilePtrs.Add(hfile);
	m_TreePtrs.Add(tree);
	m_BranchPtrs.Add(eventBranch);
}

tree->Fill();

}[/code]

When you pass the pointer to your object (&pEvent), the branch retains this address (as it is used by the branch to (potentially) pass information back to you).
However the address you pass to the branch is transient (as it is on the stack).
So you need to correct your code in the following way:[code]void CROOTFileManager::Add(CMyEvent *pEvent)
{
//first get the filename needed, and then see if we have the file open.
//if open, append,
//if not open, create and add

CStdString strRootFile = pEvent->GetROOTFileAsString();
CStdString strRootTree = pEvent->GetROOTTreeAsString();
CStdString strRootClass = pEvent->GetROOTClassAsString();

TTree *tree = NULL;
TFile *hfile = NULL;
TBranch *eventBranch = NULL;

int nFile = m_FileNames.Find(strRootFile);

if ( nFile != -1 )
{
//get the file pointer
hfile = m_FilePtrs.GetAt(nFile);
tree = m_TreePtrs.GetAt(nFile);
eventBranch = m_BranchPtrs.GetAt(nFile);
}
else
{
//first check to see if the file we want exists.
hfile = new TFile(strRootFile,“UPDATE”,“Data”);
if ( hfile == NULL )
{
// Create a ROOT File
hfile = new TFile(strRootFile,“RECREATE”,“Data”);

     // Create a ROOT Tree
     tree = new TTree(strRootTree,strRootClass);
  }
  else
  {
     // Create a ROOT Tree
     tree = (TTree*)hfile->Get(strRootTree);

     if ( tree == NULL )
     {
        // Create a ROOT Tree
        tree = new TTree(strRootTree,"");
     }
  }

  eventBranch = tree->GetBranch( strRootClass );
  if( eventBranch == NULL )
  {
     eventBranch = tree->Branch( strRootClass, strRootClass, &pEvent, 32000, 99);
  }

  m_FileNames.Add(strRootFile);
  m_FilePtrs.Add(hfile);
  m_TreePtrs.Add(tree);
  m_BranchPtrs.Add(eventBranch);

}

tree->SetBranchAddress(strRootClass, &pEvent); // Always set the address to the ‘current’ location[Code Added]

tree->Fill();

tree->ResetBranchAddresses(); // Forget stack addresses }

Cheers,
Philippe.