Writing branches and trees

Hi all,

I am trying to create a tree and, using Geant4, store some data in it. In Geant4, I run multiple events and want to add the data I get to a branch of the tree that has a name that corresponds to the event number.

What I am doing right now is:
At the beginning of the main run, I create a tree :
tree = new TTree("Data", "Title");
At the beginning of an event, I create the branch I want:
G4String eventID = IntToStr( evt->GetEventID() ); G4String branchName = "Event" + eventID + "LayerData"; tree->Branch(branchName,en_dep,"en_dep[20]/F");
During the event I fill the en_dep array with the data I want to store, which is replaced during each event with new data.

At the end of the run (so after all the events have been completed and the branches created), I fill the tree so that the branches get put in there:
tree->Fill(); tree->Write(); //Which writes it to the file

But! This doesn’t work – each branch gets filled with the same data, that of the last event. Even though the branch names are all different and they each should have been assigned different data, they are all assigned the same data.

Does anyone know why?

Thanks in advance,
jason

I guess that all makes perfect sense after thinking about it overnight. All the data is getting entered at the same time and thus it of course will be the same for all the branches since they all rely on the same array. Now, though, I’m stuck trying to figure out how to get the data to enter once and only once for all of the branches (except the last). What is happening is, say I run 3 events, then the first branch gets data added to it for the first event, then the array get overwritten and a new branch is created, but the first array still relies on that same array, so when I call the tree->Fill() function the first branch will get data added to it as well as the second. This will continue on and I will get extra data all the way through the run. Does someone have a good way of fixing this?

Thanks,
Jason

[quote]). What is happening is, say I run 3 events, then the first branch gets data added to it for the first event, then the array get overwritten and a new branch is created,[/quote]Humm … What makes you case unusually hard is that you seem to want/need to stored each ‘event’ in a separate branch rather than the usual technique with is to enter each event in a separate ‘entry’ of the TTree (i.e. call tree->Fill() at the end of each event).

So the first question is why do you need this odd organization?

Cheers,
Philippe.

Ah, I’m pretty new to Geant4 at the moment and I don’t know much about what everyone usually does, so this is just me trying to find a way to get it to work. I’m sure the conventional way will work then, but I’m not sure what you mean by entering each event as a separate ‘entry’. I was hoping to get more than just the total energy deposited (I’m using a sensitive detector for a calorimeter) – it would be very nice to have the energy deposited in each of my 20 layers. So that was why I thought the branches were a good idea – I could store the array that contained the 20 values for each layer and the total energy in the same branch, and just have a branch for each event.

Still learning but it’s getting better and better every day! Thanks for all your help, Philippe.

Jason

Got it working.

For anyone else who has the same problem, I’ll post how I did it:

At the beginning of the run, create a tree:

tree = new TTree("Data", "Title");

At the end of each event, create the branch and fill only the branch (you can have multiple branches) (you fill it assuming that the data has already been compiled of course):

G4String eventID = IntToStr( evt->GetEventID() );

G4String branchName = "Event" + eventID + "LayerData";
tree->Branch(branchName,en_dep,"en_dep[20]/F");
tree->GetBranch(branchName)->Fill();

At the end of the run (so when all the events are done), run the SetEntries() function with no arguments (at least that’s the one that worked for me) and write to file:

tree->SetEntries(); tree->Write();

That was the fix, and I have all the data that I want. Hope that helps.

Jason

Hi Jason,

Indeed, your solution will work.

A completely different alternative would be:

tree = new TTree("Data", "Title");
Int_t eventid;
tree->Branch("eventid",&eventid);
tree->Branch("LayerData",en_dep,"en_dep[20]/F");
...
// Create other branches, each using their own separate variables.
...
for each event (id) do {
   eventid = evt->GetEventID();
   // set value in en_dep
   tree->Fill();
}
tree->Write();

Cheers,
Philipp.e

^ this approach worked best for me.