Writing Ntuple to a file

Hi,

I’ve read through the topics about writing an Ntuple to a file, but could not figure out the solution for my problem, so I post it now here.
I create some Ntuples, which are protected members of a class. A function of this class opens a datafile:
datafile = new TFile(…,“RECREATE”,…);
(TFile *datafile; is also member of the class)
then, later, the ntuples are created:
ntp[i] = new TNtuple(…);
beginevent[i] = new TNtuple(…);
again later, in another function, the Ntuples are filled.
After that, I want to write them to a file, and I do:
for(int i=0;i<4;i++)
{
ntp[i]->Write();
delete ntp[i];
beginevent[i]->Write();
delete beginevent[i];
}
datafile->Write();
I tried this many times, at the first time, the ntuples were created before the TFile, so the program wrote everything in the memory, and this was not the best solution. Although it worked properly, I could not process enough data due to memory limitations.
After that, I changed it, and put the TFile(…“RECREATE”…) in a routine which is called before the one which creates the Ntuples.
But then, not all (!!) Ntuples were written in the file, just a few. How could this be? Or what is the ‘official’ thing to do something like this?
The TFile exist, it is as huge as I would expect it, but it contains only two of my eight NTuples. And root said:
Error in TNtuple::Write: No file open
eight times.
First, it seemed, that it will run properly, the file was opened at the right time, started to increase it’s size, but at the end, something is wrong.
I even could not figure out, if datafile->Write() is needed or not.

Thanks a lot,
Mate Csanad

This is essential. It insures that the file directory is properly updated.

Now that you are creating the ntuple after opening the file, you can simplify you code:

datafile->Write(); // Will also write the ntuple meta data delete datafile; datafile =0; for(int i=0;i<4;i++) { ntp[i] = 0; // has been deleted 'delete datafile' beginevent[i] = 0; // has been deleted 'delete datafile' }

This is indicative of a real problem. Either the ntuple created before the file was open. Either the ‘ROOT’ directory was changed to a non file resident directory. Either the file was closed and delete before the write is being done.

Cheers,
Philippe.

Hi,

If I include

[code]
delete datafile;
datafile =0;
for(int i=0;i<4;i++)
{
ntp[i] = 0; // has been deleted 'delete datafile’
beginevent[i] = 0; // has been deleted ‘delete datafile’
}
[\code]
root exits without telling me anything.
But if I do, what you have recommended, just leave out the above part, it seems to be ok, just the funny thing is, that if I look at the root file with
.ls
I see the following:

[quote]
TFile** filename title
TFile* filename title
KEY: TNtuple ntp1;2 Particle ntuple
KEY: TNtuple ntp1;1 Particle ntuple
KEY: TNtuple ntp0;1 Particle ntuple
KEY: TNtuple beginevent0;1 Begin of event
KEY: TNtuple beginevent1;1 Begin of event
KEY: TNtuple ntp2;1 Particle ntuple
KEY: TNtuple beginevent2;1 Begin of event
KEY: TNtuple ntp3;1 Particle ntuple
KEY: TNtuple beginevent3;1 Begin of event
[\quote]
Why do I have one of the ntuples twice?
And why aren’t they in proper order?

But anyway, they contain the proper info, and that’s what I need, so…

Thanks,
Mate Csanad

Hi,

This is (of course) not normal. The most likely causes
are that you either (inadvertendly) delete the file twice
or you have a memory over-write problem (you could
detect this by using a tool named ‘valgrind’).
You could also run root in a debugger.

They are ‘cycles’ (see the User’s Guide for more details).
They appear each time the object is saved (i.e. either the
TTree has called TTree::AutoSave or you called Write).

Cheers,
Philippe