Hi experts,
I can’t delete a specific cycle from a specific directory in a TFile.
Here’s a dummy code (and attached is the running script) with other
issues described below:
{
TFile f("test.root", "RECREATE");
TH1F h("h","",10,0,10);
h.Fill(3);
f.mkdir("testDirA");
f.cd("testDirA");
h.Write();
h.Write();
f.mkdir("testDirB");
f.cd("testDirB");
h.Write();
h.Write();
f.Close();
}
{
TFile f("test.root", "UPDATE");
f.cd("testDirA");
f.ls();// shows h;1 and h;2 in the testDirA directory
f.Delete("h;1");
f.ls();// Q1: ls() still (?) shows h;1 in the testDirA directory
f.Close();
f.Open("test.root", "READ");
f.ls();// Q2: ls() no directories shown (?)
f.Close();
}
{
TFile f("test.root", "READ");
f.cd("testDirA");
f.ls();// Q3: shows h;1 and h;2 in the testDirA directory
f.Close();
}
Questions
Q1. Immediately after deleting an ls() of the file still shows the
histogram supposedly deleted. TFile::Delete is mediated by a buffer?
Q2. After closing and reopening the file the ls() changes and no
directory is shown. This is rather awkward since TBrowsing the file at
this stage (in a separate or the same session) shows that all
directories are still in the file.
Q3. The histogram testDirA/h;1 was actually never deleted from the
file. How can this Histogram be deleted?
Thanks in advance,
Hernan.
testDelete.C (1.24 KB)
[quote]Q2. After closing and reopening the file the ls() changes and no
directory is shown.[/quote] humm … f.Open("test.root", "READ");
Does NOT affect the object ‘j’ because TFile::Open is a static function that allocates and return a new object. i.e. TFile *f2 TFile::Open("test.root", "READ");
f2->ls();
f2->Close();
will work better.
Cheers,
Philippe.
[quote]Q1. Immediately after deleting an ls() of the file still shows the
histogram supposedly deleted. TFile::Delete is mediated by a buffer?[/quote]This means that the object has not been removed from the file (and hence explain Q3). This is because the TFile is also the top level directory and the call;f.Delete("h;1");
request “h1;1” to be removed from the top level directory … which of course can not happen since it is not there. Instead use:gDirectory->Delete("h1;1");
where gDirectory point to the directory reached by f.cd(…);
Cheers,
Philippe.
Thanks for the reply Philippe.
Some things still confuse me.
TFile f("test.root", "UPDATE");
f.cd("testDirA");
f.pwd();
shows the top level, but pwd calls TDirectory::GetPath which should show full path. This (odd?) behavior may be related to the next doubt:
[quote]
request “h1;1” to be removed from the top level directory … which of course can not happen since it is not there.[/quote]
So doing
should remove the desired object, which doesn’t. I tried simple variations like
TFile f("test.root", "UPDATE");
f.Delete("testDirA/h;1");
f.Delete("/testDirA/h;1");
and
TFile f("test.root", "UPDATE");
f.cd("testDirA");
f.Delete("testDirA/h;1");
f.Delete("/testDirA/h;1");
Seems like TFile::Delete() applies always on top directory. Shouldn’t it be possible to delete a nested directory by TFile::Delete using the Delete() argument? Mean delete from gDirectory by default or from (the expected behavior of) TFile::pwd()?
Thanks again.
[quote]but pwd calls TDirectory::GetPath which should show full path.[/quote]It is intended to show the full path of the object it is called upon. The ‘only’ trace/marker of the current directory is the value of gDirectory. If you want/need an operation to be done on the current directory call it on gDirectory (gDirectory->pwd(), gDirectory->Delete(…)).
[quote]f.Delete(“testDirA/h;1”);
should remove the desired object[/quote]Humm … no. Which part of the documentation claimed it should?
Delete intentional only look for a cycle name in the object/directory it is called on. So calling it on f (f being a TFile*) can only delete objects in the top level directory.
[quote]Seems like TFile::Delete() applies always on top directory.[/quote]By definition, yes (since a TFile object is always the top level directory).
[quote]Shouldn’t it be possible to delete a nested directory by TFile::Delete using the Delete() argument?
[/quote]It is not supported, you need to first get to the correct subdirectory.
[quote]Mean delete from gDirectory by default instead from (the expected behavior of) TFile::pwd()?[/quote]This is not desirable as it conflicts with the idea/concept of object orientation.
To achieve what you want use either:TFile f("test.root", "UPDATE");
f.cd("testDirA");
gDirectory->Delete("h;1");
orTFile f("test.root", "UPDATE");
TDirectory *testDir = f.GetDirectory("testDirA");
testDir->Delete("h;1");
Cheers,
Philippe.
Thanks again Philippe. Your answers cleared me up.
Bests,
Hernan.