TCanvas::Print() won't print PNG/GIF/JPG files within a loop

Hi all,

This is driving me nuts. I have a rootfile where some TCanvas are stored. I want to loop on them and print them as PNG files. So I tried a few variations from this example, without any success : ROOT will (successfully) loop on the canvas, but won’t print them as PNG files, it will just loop without a word. It’s even worse with GIF files (segfault) or JPG files (print them as PS). I tried on three different computers with three different versions of ROOT (5.28/00 on SL4.7, 5.30/06 on Fedora 16, 5.32/04 on SL5.8), without any success. However, it works well if I create PS/PDF/EPS or even SVG files, or if I create a single canvas which I print in PNG/GIF/JPG. It won’t work only in the loop.

What am I doing wrong ? Here is one version of the code (variations on using an ostringstream or not or using a buffer TCanvas or not give identical results) :

TFile *_file0 = TFile::Open("file.root");
TIter next(_file0->GetListOfKeys());
TKey *k;
while ((k=(TKey*)next()))
{
      TCanvas *c = (TCanvas*)(k->ReadObj());
      ostringstream a("");
      a << c->GetName() << ".png";
      c->Print(a.str().c_str(),"png");
}

Content of the file :

$ root file.root 
root [0] 
Attaching file file.root as _file0...
root [1] _file0->ls()
TFile**		file.root	
 TFile*		file.root	
  KEY: TCanvas	c1;1	Canvas 1
  KEY: TCanvas	cl1;1	Line 1
  KEY: TCanvas	cl2;1	Line 2
  KEY: TCanvas	cl3;1	Line 3
  KEY: TCanvas	cl4;1	Line 4
  …

Before “Print”, try to add:
c->Draw(); c->Modified(); c->Update();
After “Print”, try to add:
delete c;

Thanks, I should have thought about that, it works by adding “c->Draw();”. Also, if the PNG files already exist, it will aknowledge for successful creation of the PNG files without actually creating them (I mean, without the “c->Draw()” — that is, with the version as in the first post).

I guess this is to be reported as a bug, then.

No bug here … just do:

void loopdir() {
   TFile *f1 = new TFile("hsimple.root");
   TIter next(f1->GetListOfKeys());
   TKey *key;
   TCanvas c1;
   Int_t i=0;
   while ((key = (TKey*)next())) {
      TClass *cl = gROOT->GetClass(key->GetClassName());
      if (!cl->InheritsFrom("TH1")) continue;
      TH1 *h = (TH1*)key->ReadObj();
      h->Draw();
      c1.Print(Form("hsimple%d.png",i++));
   }
}

Actually the bug would be that “if the PNG files already exist, it will aknowledge for successful creation of the PNG files without actually creating [nor modifying] them”.

If the files already exist they are overwritten:

imaccouet:roottest couet$ ls -l *hsimple*.png
-rw-r--r--  1 couet  staff  11113 Jul  4 10:39 hsimple0.png
-rw-r--r--  1 couet  staff  32025 Jul  4 10:39 hsimple1.png
-rw-r--r--  1 couet  staff  12069 Jul  4 10:39 hsimple2.png
imaccouet:roottest couet$ root -n
root [0] .x loopdir.C
Info in <TCanvas::Print>: png file hsimple0.png has been created
Info in <TCanvas::Print>: png file hsimple1.png has been created
Info in <TCanvas::Print>: png file hsimple2.png has been created
root [1] .q
imaccouet:roottest couet$ ls -l *hsimple*.png
-rw-r--r--  1 couet  staff  11113 Jul  4 10:41 hsimple0.png
-rw-r--r--  1 couet  staff  32025 Jul  4 10:41 hsimple1.png
-rw-r--r--  1 couet  staff  12069 Jul  4 10:41 hsimple2.png
imaccouet:roottest couet$ 

… look at the dates…

Ok, first of all I apologize, actually the script of the first post seems to work with ROOT 5.32/04 on SL5.8, contrarily to what I have stated. It also works with 5.34/00 on Debian Wheezy. The point is that in both case ROOT doesn’t acknowledge for the creation of files as I was expecting — so with my first experience with previous versions I didn’t even check files were there. Both versions correctly update the files though, so I guess the bug of not updating existing files while incorrectingly acknowledging for their creation has been fixed between 5.30/06 and 5.32/04.

The fact that ROOT does not acknowledge for the first creation of the PNG files is still a (minor) bug, though — but maybe it has been fixed since 5.34/00.

$ ls
file.root  uu.C
$ root uu.C
root [0] 
Processing uu.C...
root [1] .q
$ ls
c1.png    cl11.png  cl1.png  cl3.png  cl5.png  cl7.png  cl9.png    uu.C
cl10.png  cl12.png  cl2.png  cl4.png  cl6.png  cl8.png  file.root
$ root uu.C
root [0] 
Processing uu.C...
Info in <TCanvas::Print>: png file c1.png has been created
Info in <TCanvas::Print>: png file cl1.png has been created
Info in <TCanvas::Print>: png file cl2.png has been created
Info in <TCanvas::Print>: png file cl3.png has been created
Info in <TCanvas::Print>: png file cl4.png has been created
Info in <TCanvas::Print>: png file cl5.png has been created
Info in <TCanvas::Print>: png file cl6.png has been created
Info in <TCanvas::Print>: png file cl7.png has been created
Info in <TCanvas::Print>: png file cl8.png has been created
Info in <TCanvas::Print>: png file cl9.png has been created
Info in <TCanvas::Print>: png file cl10.png has been created
Info in <TCanvas::Print>: png file cl11.png has been created
Info in <TCanvas::Print>: png file cl12.png has been created
root [1] .q

now fixed, thanks