TH1F::Write(), I don't understand your philosophy

I read from root.cern.ch/root/html/TH1F.html, to write an TH1F to a file:

 TFile f("histos.root"); //maybe is better to use the option "RECREATE" or "NEW"
 TH1F histo(...)
 ...
 histo->Write();

how the Write method know where save data?? More: the contrary of Write is Read, not Get!!! Get is the contrary of Set.

I do two very simple programs:
-----------------write.cpp------------------

#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TH1F.h"
#include "TFile.h"
#include "TPaveLabel.h"

int main(int argc,char **argv)
{
    TApplication theApp("App", &argc, argv);

    TH1F histo("histo","my histogram",100,0,10);
    histo.Fill(3);
    histo.Fill(4);
    histo.Fill(4);
    TCanvas canvas("canvas","my canvas",0,0,800,600);
    histo.Draw();
    TFile f("file1.root","RECREATE");
    histo.Write();
    f.Close();
    theApp.Run();
    return 0;
}

-----------------read.cpp-------------------

#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TH1F.h"
#include "TFile.h"
#include "TPaveLabel.h"

int main(int argc,char **argv)
{
    TApplication theApp("App", &argc, argv);

    TFile f("file1.root");    
    TH1F *histo = (TH1F*)f.Get("histo");
//    f.Close();
    TCanvas canvas("canvas","my canvas",0,0,800,600);
    histo->Draw();


    theApp.Run();
    return 0;
}

Now… why if I close the file in read.cpp I get an error

 *** Break *** segmentation violation

what’s the problem? 1) open file 2) get data from file and store it in a container (TH1F) 3) close file, the data will be indipendent from the file! but not!

more: why I have to initalize dynamically an histo in read.cpp? Why in your documentation you use always the dynamic iniatilization?? If it is not necessary it is evil! And more: the cast (TH1F*) is deprecated, use static_cast<TH1F*> that is c++ standard instead. And more… why the cast is necessary? I don’t understand your philosophy here and in a lots of other things. I need to do a long data analysis of spectrum and I lost one day to learn how save histogram in ROOT format, it is not possibile!

The first thing that you should do is read at least the first chapters of the Users Guide (in particular the one about object ownership) and look at the most basic tutorials.

Rene

  1. What do you mean by dynamic initiallization? In C++ the term “dynamic initialization” means initialization of non-local object like this:

//global scope
int fun();

int n = fun();//n here has dynamic initialization according to ISO/IEC 14882, 3.6.2/1

Do you mean such initialization? Or you simply mean objects created in a dynamic memory? These are two completely different things.
I’m not sure about ROOT’s documentation, but IMHO: most of the samples are CINT macros, and after macro executed, you still can use objects if they were created in dynamic memory, not on a stack (BTW I’m not sure how CINT implements stack). And these samples are not C++ tutorials, they are ROOT specific.
Yes, dynamic allocation should be used ONLY if you cannot place object on a stack (or create object with static storage duration).
But if you read something from a file (you simply ask f.Get(“name”)), how can you create this object not in a dynamic memory? I can write object of type “MyType” with name “MyObject” into file “myfile.root”.
What if someone save object of type “HisType” with name “MyObject” into file “myfile.root”? TFile (or some ROOT’s machinery) will re-create this object for me (after f.Get(“MyObject”)), and I can check the type of this object and understand, that it’s wrong. But you cannot do such things without dynamic allocations.

Wrong statement. It’s not deprecated. It’s a part of standard C++. Just open ISO/IEC 14882 Annex D and read, what is deprecated in C++.
BTW:
TFile::Get returns TObject *,
TH1F inherited from TObject, so this two
casts:
(TH1F *) and static_cast<TH1F *> are equivalent here!!!
(read ISO/IEC 14882 5.4)

And if you have a compiled programm (not a macro) you’d better use dynamic_cast<TH1F *> - after dynamic_cast you can check, that object with name “MyObject” really has type you want “MyType”, not “HisType”.
(dynamic_cast useless with CINT - AFAIK it does not work correctly).

Well, to use TObject * as TH1F* you have to do cast, right?
To say the truth, I do not like many things in ROOT, but your problem is not real problem. Just listen to Rene - read ROOT’s tutorial.

[quote=“brun”]The first thing that you should do is read at least the first chapters of the Users Guide (in particular the one about object ownership) and look at the most basic tutorials.

Rene[/quote]

Ok, but I don’t understand why if I close the data file in the read program I get the error

This is one of the things I do not like :slight_smile:

ROOT’s manual (chapter 8 in my version of manual):

So, may be, hist->SetDirectory(0) can help you.

If I’m wrong, somebody will help us (I hope).