I have a script which I compile and run which creates a few TGraphs (among other things) and saves them to a .root file. When I later open the .root file, the objects with the same names are TH2F, not TGraph. When I draw them they are drawn as scatter plots, rather than as usual graphs.
Here are some code fragments from my script, regarding how I do things:
TTree* C2 = (TTree*)gDirectory->Get("C2");
// Loop over just a single value of i...
C2->Draw("ampl_tv->fElements:Iteration$ >> gChan2",TString::Format("Entry$==%i",i));
gChan2 = (TGraph*)gDirectory->Get("gChan2");
gChan2->SetTitle(TString::Format("Channel 2 Entry %i",i));
In my script I don’t even #include TH2F.h, so I’m confused as to how they get turned into TH2Fs. Any ideas would be appreciated.
So there are contradictions in the documentation and in the behavior between compiled macros and interactive mode. If not contradictions, then some very confusing statements.
When I try the tree->Draw command from my script interactively, indeed it draws an unbinned thing with lots of points, as described in the second link you mention (search for the first instance of the string “TGraph”). Is this some kind of “unbinned TH2F” or a TGraph?
When the same command is present in my compiled macro, the object that is saved to the file is indeed a binned TH2F as described in the first link you mention.
More confusingly, both documentation sources say that the “prof” option can be used to draw a TProfile histogram “instead of a regular TH2F”.
Finally, while searching for “>>” in those links reveals some confusing documentation with hints of an explanation for the observed behavior, it doesn’t really indicate how I can save a TGraph drawn using TTree::Draw to a file. Is there no way to do this in a macro? I’d like to avoid having to extract and create arrays and then put them explicitly into a TGraph constructor…
Search for “Retrieving the result of Draw” in http://root.cern.ch/root/html/TTree.html#TTree:Draw@2
Actually, simply read the whole description of “TTree:Draw” from this link.
Compare the beginning of this description with the contents of the section called “Saving the result of Draw to an histogram”.
I’m doing that, but it’s coming up as a TH2F instead of a TGraph. This is the problem I’m having.
Are you saying that drawing with “x:y” creates a TGraph (which can then be retrieved via the name “Graph”) but that drawing with “x:y >> MyGraph” instead creates a TH2F in the object “MyGraph”, even if “MyGraph” was declared to be a TGraph beforehand?
If this is the case, then it needs to be much more explicitly stated in the docs. “>>” doesn’t imply TH2F, and it is counter-intuitive that it changes the type of object drawn.
I tried to do what you are doing in your macro using the simple tree produce by $ROOTSYS/tutorials/hsimple.C.
And I get:
root  TGraph *g
root  ntuple->Draw("px:py >> g")
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root  g->Draw()
Error: illegal pointer to class object g 0x0 1335 (tmpfile):1:
*** Interpreter error recovered ***
I wonder how your macro can work …
The original code may not work when interpreted but it will probably work when compiled (except that it will create a TH2F instead of a TGraph, of course). I think that the magic line which makes it work when compiled is:
gChan2 = (TGraph*)gDirectory->Get(“gChan2”);
The “gChan2” on the left side is a TGraph pointer (defined by the user several lines earlier), while the “gChan2” on the right side is a TH2F name (automatically created by the preceding “TTree:Draw” with “>>gChan2”). And in the middle, there’s the “TDirectory::Get” which returns a “TObject” pointer.
It is not obvious to me at all why it would create a TH2F instead of a TGraph. As I mentioned earlier, different parts of the documentation disagree.
Which parts of my situation determine if it makes a TGraph or a TH2F. Is it compiled vs CINT? Is it the usage of “>>”?
[quote]Which parts of my situation determine if it makes a TGraph or a TH2F. Is it compiled vs CINT? Is it the usage of “>>”?[/quote]The ‘>>’ part tell TTree::Draw to use an existing object with the given name.
Ah, so in my original example, declaring gChan2 as a pointer to a TGraph was not enough, because it didn’t have a name in ROOT.
Would it turn out as a TGraph if I actually called a TGraph constructor with the name “gChan2”, then used “>> gChan2” in the draw command?
P.S. Just to make it clear. My above statement translated into a bit more verbose form: I disagree
Yep, so do I … it should work but it does not
TTree::Draw will always create the TGraph (in the cases where it fills one).
As already mentioned … one can always retrieve that “magic graph” using:
TGraph *graph = ((TGraph *)(gPad->GetPrimitive(“Graph”))); // 2D case of Draw(“e1:e2”)
and then clone it (make a copy of it), rename it, …
(No need to use “>>” at all.)