Spherical harmonics

I think is that case you cumulate in a existing histogram. And the graphs are lost. so there is no other way. Unless we do like a:b:c with COL option where the graphs are attached to the histogram. Remember I told you that the case a:b and a:b:c with col behaved differently regarding the graphs storage.

yes …

no. the histogram can be used to define the range and still you want to have the points at the exact position.

The default is the scatter plot with graphs. We cannot change that.

No idea how easy/difficult it is to implement … may be post a Jira request with some running test case to keep track.

The fourth pad in the upper row of my “w2a.C” macro uses a simple:
TH2F *hba = new TH2F(“hba”, “b:a>>hba”, xnbins, hxmin, xmax, ynbins, hymin, ymax);
nt->Draw(“b:a>>hba”, “”, “”);
No “COL” is involved. =P~
So, I want to get the same result WITHOUT creating the “hba” first (i.e. without the first line “TH2F *hba = new TH2F(…);”). :mrgreen:
That’s what I tried in the third pad in the upper row:
nt->Draw(“b:a>>auto_hba”, “”, “”); // note: TTree::Draw creates “auto_hba”

If you insist on having the TGraph / TPolyMarker3D created, then please do it in BOTH cases, i.e. regardless whether the histogram existed or not, fill the histogram and draw the TGraph / TPolyMarker3D (so that my third and fourth pads in the upper row will look exactly the same).

I am not saying that all is fine. And I agree to revise it. All your requests are quite confusing right now. They go in all directions. We cannot decide that quickly what is good and what is not. At a first approximation we can agree to improve the in following way:

  1. we cannot get rid of the exact scatter plot Drawing (ie graphs).
  2. the histogram filling should (may be) be more coherent. Sometimes the histogram filling is done sometimes not. I think it will be better to always fill. But this has to to be checked: for instance filling the histogram in the case of a:b:c with COL will not be a good idea. Because if one plot the resulting histogram with any graphics option the graphs stored in the list of functions will be plotted on top of it. Using the option HIST to not draw the list of functions can be a workaround, but do we really want that ?
  3. the way graphs are handled is not the same between a a:b plot and a a:b:c one with COL. In the later one the graphs are kept in the histogram (in the list of functions) in the first one the are simply drawn in the pad after the empty histogram. I guess it will be better to keep them in the list of functions too. (to be checked also)

BUT: all this should be checked carefully to avoid disasters …

I’m afraid I’m even more confused than you … try the attached “w2b.C” macro …

With ROOT 5 I get: [code]TH2F hold histogram exists in advance -> 0x2bc33b0
gPad -> 0x2bc33b0 -> TH1.Print Name = hold, Entries= 20, Total sum= 20
gROOT -> 0x2bc33b0 -> TH1.Print Name = hold, Entries= 20, Total sum= 20

TH2F hnew histogram DOES NOT exist in advance
gPad -> 0x2d096b0 -> TH1.Print Name = hnew, Entries= 0, Total sum= 0
gROOT -> 0x2c61c90 -> TH1.Print Name = hnew, Entries= 20, Total sum= 20[/code] So, in case “hold” existed, ROOT 5 (re)uses it in both, the “gPad” and the “gROOT”.
However, in case “hnew” did not exist, ROOT 5 creates TWO different histograms with the same name “hnew”. One histogram in “gPad” and this “hnew” histogram is NOT filled, and another one in “gROOT” and this “hnew” histogram is filled.

With ROOT 6 I get: [code]TH2F hold histogram exists in advance -> 0x3779ed0
gPad -> 0x3779ed0 -> TH1.Print Name = hold, Entries= 20, Total sum= 20
gROOT -> 0x3779ed0 -> TH1.Print Name = hold, Entries= 20, Total sum= 20

TH2F hnew histogram DOES NOT exist in advance
gPad -> 0 -> hnew
gROOT -> 0x31eab70 -> TH1.Print Name = hnew, Entries= 0, Total sum= 0
gPad -> 0x31ecd10 -> TH1.Print Name = hnew_copy, Entries= 0, Total sum= 0
gROOT -> 0x31ecd10 -> TH1.Print Name = hnew_copy, Entries= 0, Total sum= 0[/code] Again, in case “hold” existed, ROOT 6 (re)uses it in both, the “gPad” and the “gROOT”.
However, in case “hnew” did not exist, ROOT 6 creates TWO different histograms with two different names. The “gROOT” sees both, “hnew” and “hnew_copy”, while “gPad” sees only “hnew_copy”. Neither of these two new histograms is filled.

I vote for the following modifications.

  1. In case “hold” existed and had appropriate dimensions and binning, ROOT simply resets and fills it if “>>hold[(…)]” or continues filling without resetting (appends data) if “>>+hold[(…)]”.
  2. in case “hold” existed but it did not have appropriate dimensions and/or binning, it is replaced with an appropriate new “hold” histogram and then everything goes as in point 1. above.
  3. In case “hnew” did not exist, ROOT creates it and registers in the “gPad” (current pad) and “gDirectory” (current directory). This newly created “hnew” histogram should be filled (for both, “>>hnew[(…)]” and “>>+hnew[(…)]”).
  4. What concerns graphic output (i.e. what’s drawn in the canvas) -> both above cases (i.e. point 1. and 3.) should behave in EXACTLY the same way. So, either in BOTH above cases the newly filled histogram is drawn, or in BOTH above cases an additionally created TGraph / TPolyMarker3D is drawn (so that every pad will have its own TGraph / TPolyMarker3D, too).
  5. The above rules should work for all dimensions and any graphics options.

BTW. in one of your previous posts you write that “… the histogram can be used to define the range …”. I believe that the whole purpose of the “>>[+]hnew” feature is to get the “hnew” histogram filled. If the user wants to “define the range”, he can simply call TPad::DrawFrame in advance (note that in this case, the histogram’s range does NOT need to be the same as the pad’s range).
w2b.C (1.5 KB)

Ok . Because this thread is already too long I suggest you post your requests in Jira (like you just did for an other one). This way it will be easier to keep track and, for the team members to follow and give there input.

I would like to comment your point #2:

When the histogram exits, the binning and limits are the user choice. And we cannot judge if this histogram has appropriate dimensions or not. So I think your suggestion to replace the histogram by an “appropriate new “hold” histogram” is wrong.

In case “histo” exists …
For the cases “>>histo” and “>>+histo” you only need to check that the dimensions of the “histo” are correct (you do not check its binning, of course).
However, as soon as you see “>>histo(npx, xmin, xmax[, …])” or “>>+histo(npx, xmin, xmax[, …])”, you should also check that the “new binning” defined this way is exactly the same as the “old binning” of the existing histogram.
If yes, you don’t care.
However, if the “new binning” is different from the “old binning”, you should replace the existing histogram with a new “histo” and set this “new binning” for it.

When I speak about checking histogram dimensions I really mean that, for example, you cannot fill a TH1F if the “varexp” requires a “TH2F” and vice versa. So, if the dimensions of the “varexp” do not agree with the dimensions of the existing histogram, that means that you should replace the old histogram with an appropriate new one.
Note that the “histo” may exist because it was created by a previous call “varexp>>histo” and the old “varexp” had different dimensions than in the current call.
Sometimes it may be useful to treat the “histo” as a kind of a “htemp” (a “temporary histogram” used for any “temporary” purposes). So one can reuse it many times as “varexp-1-d>>htemp” then “varexp-2-d>>htemp” and then “varexp-3-d>>htemp” (I think ROOT should automatically recreate the “htemp” with appropriate dimensions, when needed).

In case the Histogram dimension does not correspond to the variable list. The check is already done:

{
  TNtuple *n = new TNtuple("n", "n", "a:b:c");
  for (Int_t i = 0; i < 20; i++) n->Fill(gRandom->Rndm(), gRandom->Rndm(), i);  
  TH1F *hold = new TH1F("hold", "hold", 100, 0, 1);
  n->Draw("a:b>>hold", "", "");  
}

gives

Warning in <TSelectorDraw::Begin>: Deleting old histogram with different dimensions

In case you do:

{
  TNtuple *n = new TNtuple("n", "n", "a:b:c");
  for (Int_t i = 0; i < 20; i++) n->Fill(gRandom->Rndm(), gRandom->Rndm(), i);  
  n->Draw("a:b>>h(100,-3,3,100,-3.,3)", "", "");  
  n->Draw("a:b>>+h(100,-1,3,100,-1.,3)", "", "");  
}

it seems the new limits are used. May be it needs a closer check.

In fact it is quite easy to use that “+” feature.

Do

n->Draw(“a:b>>+h(100,-1,3,100,-1.,3)”, “”, “lego”);

then:

root [1] n->Draw(“a:b>>+h”,"", “lego”);
root [2] n->Draw(“a:b>>+h”,"", “lego”);
root [3] n->Draw(“a:b>>+h”,"", “lego”);
root [4] n->Draw(“a:b>>+h”,"", “lego”);
root [5] n->Draw(“a:b>>+h”,"", “lego”);
root [6] n->Draw(“a:b>>+h”,"", “lego”);
root [7] n->Draw(“a:b>>+h”,"", “lego”);
root [8] n->Draw(“a:b>>+h”,"", “lego”);
root [9] n->Draw(“a:b>>+h”,"", “lego”);

you see h growing… when you use + you should not specify the histo parameters as they already have been defined. As you as you specify them the histo is reset … sounds logical indeed.

Sorry for misunderstanding. I do not claim that the current ROOT fails in all my points.
I just try to create a precise algorithm how exactly it should behave in future (in my opinion).

BTW. I’m not sure what happens now if you call “>>+hnew(the same binning as in the previous call)”. In my proposal, I explicitly say that if the “new binning” is the same as the “old binning”, ROOT should simply ignore the “(…)” part and continue filling (well, I suspect that the current ROOT will unconditionally reset the histogram).

I’d like to add a small note to my point 4. What concerns graphic output (i.e. what’s drawn in the canvas).
I really think that ROOT should draw the filled histogram and it should NOT try to create any additional TGraph / TPolyMarker3D. In general, a histogram will be used in cases when the user expects many events. You don’t really want to create and draw graphs with hundreds of thousands or even millions of points, do you.

O.K.
In general, if you don’t like the idea of checking the binning, I can loosen my points 1. and 2. -> check only dimensions and do NOT check the binning.
Then, as soon as you see “>>[+]histo(new binning)”, you unconditionally recreate the “histo” with this “new binning” (regardless whether this “new binning” is different from the “old binning”, or not).

Yes ROOT reset the histogram in that case. May be we should update the doc.

I totally disagree with you on that point. The default drawing option for 2 and 3 variable plots must be the drawing of a marker at the exact x,y,(z) position. The exact events must be shown. The extension of this for more coordinates are the ||-Cord plots.

I fully agree with you about the “default behavior”.
However, “>>[+]histo” is NOT the “default behavior”. If the user EXPLICITLY asks for a histogram, he should get it.
What’s much more important, ROOT’s behavior should be exactly the same regardless whether the “histo” existed prior to this call or not (and that’s not the case in the current ROOT).

I fear to comment in such a technical thread, but as a user that was once confused by the result of using “>>” in a TTree::Draw command, I want to express an opinion.

In each of your examples to each other, you assume that the object foo “>>foo” (or “>>+foo”, or “>>foo(a,b,c)”) is actually called “histo” or “hold” or “hnew” so that it’s obvious that it’s a histogram. Remember that this is a generic ROOT object name, and the name might absolutely not imply (and never requires) a histogram. Try re-reading some of your posts in this thread with “MyGraph” as the placeholder name.

In the past one of my confusions was that I created a TGraph object with a name, and I tried to draw with “>>MyGraph” thinking that it would “fill” the TGraph with data points. Call this attempt naïve if you wish, but that’s where at least one user’s intuition went. It was difficult to learn that in fact MyGraph was deleted and turned into a histogram without my knowing.

In all of these bug reports and attempts to fix things, have you thought of possibly allowing the Draw command to fail? I think if I defined a histogram TH1D h(“h”,“h”,10,0,10); and then did t->Draw(“a:b:c >>h”);, that should give some kind of runtime error and fail, NOT completely change the kind of object that “h” is in an attempt to guess at what the user is doing. This is C++ after all, not Perl: fail early and fail hard.

I am thinking perhaps it is time to re-examine the TTree::Draw syntax to make things more explicit.

Jean-François