Get histogram and close file

Hi,

I need to open file, get histogram to memory and close file.
What is wrong with the below code?
I would expect that Get() copy object to memory so the file following Close() changes nothing.
Instead if one opens file as a pointer using new TFile() and does not close it the same code works fine.

Best regards,
Valeri

void t()
{
  TFile f("mean.root");
  f.ls();
  TH2F *h2 = (TH2F*)(f.Get("h2"));
  //TH2F *sg = (TH2F*)(((TH2F*)(f.Get("h2")))->Clone("sg"));
  f.Close();
  h2->Draw();
  //sg->Draw();
}

Note that use of commented lines does not solve the problem

The output is:

$ root  t.C
  *******************************************
  *                                         *
  *        W E L C O M E  to  R O O T       *
  *                                         *
  *   Version   5.34/25   12 January 2015   *
  *                                         *
  *  You are welcome to visit our Web site  *
  *          http://root.cern.ch            *
  *                                         *
  *******************************************

ROOT 5.34/25 (v5-34-25@v5-34-25, Jan 12 2015, 15:29:06 on linuxx8664gcc)

root [0]
Processing t.C...
TFile**         mean.root
 TFile*         mean.root
  KEY: TH2F     h2;1    h2
  KEY: TH2F     hmean;1 hmean

 *** Break *** segmentation violation
 Generating stack trace...
root [0] TFile f("hsimple.root");
root [1] TH2F *h2 = (TH2F*)f.Get("hpxpy");
root [2] h2->SetDirectory(0); // to decouple it from the open file directory
root [3] f.Close()
root [4] h2->Draw()
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
1 Like

Thank you, Oliver!

I had to say that the necessity of this

h2->SetDirectory(0);

is not intuitive at all

Moreother in
root.cern.ch/root/html534/TDire … ryFile:Get
is written:
"examples:
foo : get object named foo in memory"
so one would expect that it is already detached from the file.

Especially strange that when I create completely new object with Clone() function this object is still depends somehow from the file directory even if the file is not writable.

Well, just the comment.

Best regards,
Valeri

I agree it might be more intuitive. May be you can encapsulate the Get and SetDirectory in one macro so you do not need to type two lines each time you want to do that.

when you do

TFile f("mean.root"); at the end of the function, the object f is automatically deleted, and also all objects associated to this file.
By calling SetDirectory(0) you dissociate the histogram from the file, and then it is your responsibility to manage it (eg avoiding a memory leak)

Rene

Thank you, Rene,

I’m mistaken or 2 or 3 major root versions ago the behavior was different and the objects like histograms were kept in memory after the file closing?

I see the point about memory leak, but to do for each object SetDirectory(0) brr… I’m sure that you already got an infinity of similar questions.

Best regards,
Valeri

if you do not want to call SetDirectory(0) for each histogram, you can call the static function

TH1::AddDirectory(kFALSE); before reading your objects. For more details, see the chapter about Objects ownership in the Users Guide.

Rene

1 Like

Probably for simple situations defied as:

“I want to get an object from file into memory and do not like to care about neither files nor directories”

it could be useful to have a special function like this one

TObject *GetObjectFromFile(“myfile.root:/mydir/myobject”);

which opens file, get object, attach it to the directory from where it was called, close file.

Probably this could be a function of TDirectory so one can call it from

gDirectory->…

or just a global function

Best regards,
Valeri

Hi Valeri,

The TDirectory / TFile association exists only for a few types, and can only be removed for a subset of those. See the users guide, chapter “Object Ownership”.

This has mostly historical reasons; it’s impossible to change this now fundamentally or we break everyones’ code :frowning:

Cheers, Axel.

Is it possible to move an arbitrary TObject to any TDirectory? I would like to be able to retain TGraph in memory after closing the file from which it was retreived.

Hi @quantiser,
this thread is 4 years old! Please open a new one with your question :smile:

Cheers,
Enrico

TGraph will always stay in memory (it does not depend on TDirectory).