Discrepancy between cont and cont1

Hello,

I’m getting some strange differences in behavior between drawing my contour plots with the “cont” option vs. “cont1”.

I need to save the graphs of the contours so I use the “cont list” option when drawing my histogram. However, one contour level always returns with 0 graphs.

I decided to check if cont1 would give me the output I expected, and it did. However, that meant that “cont1” was giving me different output from “cont”

I’ve attached a test script to demonstrate my problem. When you use 1 contour, cont1 gives two loops (correct) and cont gives zero. With 2 contours, cont1 gives 4 loops (again correct), but cont gives two. It seems to me that cont is dropping the lowest contour, but perhaps there is something else going on.

Any ideas?

Josh de Bever
CSI Medical Physics Group
The University of Western Ontario
London, Ontario, Canada

System: Mac OSX 10.3.5, ROOT v4.00/08
ROOTtest3.C (3.56 KB)

Olivier will process your mail as soon as he is back on Monday.

Rene

Hi,

As explained in the the help of THistPainter::PaintContour, the option LIST must be used with the option CONT, not with CONT1. Seems to me your example is working fine with CONT. Your histogram has only one contour (you set it with SetContours) and after Draw("CONT LIST) you get one contour in TotalConts. Using LIST with CONT1 doesn’t work (I have tried with the example FirstContour.C in the tutorials directory ). Have I missed something ?

I know that in order for the graphs to be saved CONT must be used not CONT1. However, the results of calculating the contours with CONT and CONT1 differ.

My script shows side by side results of what CONT calculates and what CONT1 calculates. It seems to me, they should be the same with the exception that CONT1 won’t save the graphs. On our system, CONT and CONT1 are returning different contours regardless of the number of contours you ask for (specifically CONT is always missing one set of contours, while CONT1 gives me the results I expect).

My example is perhaps complicated by the fact that for every contour I expect 2 graphs. When I run the script with 1 contour, CONT1 returns 2 graphs (expected), while CONT returns none (unexpected). Similarly for 2 coutours, CONT1 returns 4 graphs(correct) but CONT returns only 2. Is this not the case when you run my script? The left and right plots should be identical but are not when run on our system.

Josh

I do not understand how you get 2 graphs with CONT1. With your macro I did the following:
[color=red]
HistStreamFn->Draw(“CONT LIST”);
[/color]
As you said this gives:
[color=red][i]
Input Functions Calculated

Contour 0 has 0 Graphs
ContLevel[0]: Z = -0.400000

    Extracted 1 Contours and 0 Graphs 

[/i][/color]
(I am not sure that LIST is able to return several graphs for one contour, but that is an other issue). Then I tried:
[color=red]
HistStreamFn->Draw(“CONT1 LIST”);
[/color]
and I get:
[color=red][i]
Input Functions Calculated
***No Contours Were Extracted!

    Extracted 0 Contours and 0 Graphs 

[/i][/color]

So as you can see LIST with CONT1 returns no contours and no graphs (with is expected according to the documentation)

Sorry, I see how my description is confusing.

When I said CONT1 returns 2 graphs but CONT returns 0, I didn’t mean that “CONT1 LIST” was actually saving the graphs and returning 2 graphs. You’re right, that doesn’t work.

What I meant to say was, the plot on the left was drawn using CONT1 and it drew 2 “Loops” as desired.

The plot on the right is drawn using “CONT LIST”, and I would expect it to return two “loops” (or filled regions) aswell. I.E. both plots are of the same coutour level, of the same graph, yet they plot different things.

I am suspicious of CONT because everytime I call “CONT LIST” one of my contour levels ALWAYS returns with 0 graphs. I wrote this script as a minimalist example to show this.

I also see how my talk of taking two contours was a bit confusing. To see this, uncomment line 73 and change the first argument of SetContour() on line 76 to 2 (or download the attached script).

What happens on my system after making those changes is that the plot on the left generated with CONT1 now has 4 “loops”, one in each quadrant. The plot on the right generated with “CONT LIST” however only has 2. Furthermore, CONT reports that it retrieved 2 contour levels, but only 2 graphs (it should have returned 4 graphs).

I know for a fact that LIST can (and does) return more than one graph per contour (if necessary) so that is not an issue.

Is that a better description my problem/suspected bug?

Josh
ROOTtest3a.C (3.7 KB)

Hi,

Yes that is a better description. Give me a bit of time to look again at this
problem with the new hints you gave me !

Cheers, Olivier

Hi Josh,

This problem is now fixed in the CVS head. Thanks to have reported it.

Cheers, Olivier

That’s great, thanks for taking care of it so quickly.

Josh

Hello again,

I’ve moved my code over to the most recent update, but I’ve run into new troubles.

The good news is, all contours now return with valid graphs. The bad news is I’m having ordering and drawing problems.

My code depends on the z-level of each graph. So far I’ve assumed that the contours are returned in the same z-order as they were passed into SetContour(). This doesn’t seem to be the case anymore. I’m not sure the contour function made any guarantee of preserving the order, but this seems to be the most intuitive behaviour. Is the algorithm supposed to keep the z-order constant? If not, is there anyway to get the z-level of the graph? I know you can get the z-level of a contour with GetContour(), but if the z-order of the graphs is not preserved, this won’t help.

The other problem I’m having is with the plot CONT generates (this may be linked to the above problem). If you specify one contour, the correct graphs are returned in the linked list, but CONT doesn’t draw anything.

Also, If you set 2 contours below zero (say -0.4, -0.2) the contour closest to zero seems to be drawn before the most negative contour resulting in only one visible contour region. This behaviour seems strange to me.

Lastly, I was wondering if SetConour() is expecting the contours in any specific order. My apologies if I missed this in the documentation, but my plots don’t work if I pass the contours to SetContour() in order of highest to lowest. I MUST order the levels from lowest to highest. It might be worth adding a comment in the function header if it doesn’t already exist.

Thanks

Josh

Yes you are right the contour algorithm (CONT1, CONT …) doesn’t work if the contours are not defined in increasing order in SetContour.

Do you have any ideas about the other problems I described? They are occuring even with the contours passed in properly.

Josh

have you an example which demonstrates them ?

The “OneContNoPlot.C” macro demonstrates the problem where asking for one contour results in no plot from CONT, but CONT1 succeeds. NOTE: the graphs ARE properly returned by LIST).

“TwoContsDrawOrder.C” demonstrates the problem where less negative (or closest to zero) contours are drawn before the most negative contours. It’s interesting to note that if a positive contour is added the CORRECT output is given. (change the first argument of SetContour() on line 77 to 3 to see this).

The problem I’m having with the order LIST returns the contour levels may be linked to these problems. I’m trying to put together a concise example, but its tricky because I only noticed through the processing I do on the returned graphs. To show it without the extra code might be harder. I’ll work on that and post another script.

Josh
TwocontsDrawOrder.C (3.87 KB)
OneContNoPlot.C (3.8 KB)

In OneContNoPlot.C the contour is drawn but using the canvas background color. That’s why you to not see it. try:

c->cd(2);
c_2->SetFillColor(9);

Regarding the second example. It is a drawing order problem. When 2 contours are drawn, -0.4 is drawn first and is hidden by -0.2 which covers it. I do not understand yet drawing order algorithm. I need more time to fix that.

Ok, well that figured out the “One Contour” problem.

I have attached a script that demonstrates that LIST isn’t returning the contour levels in the same order as they were passed in. The plots might need some explanation, I’ll do my best.

  • I have drawn the actual graphs returned by LIST. Each contour level gets its own pad.

  • The contour level increases from left to right i.e. left most pad = contour #1, and then to the right contour #2 etc.

  • Negative contours should produce two loops in the top left and bottom right quadrants. Positive contours should produce the opposite.

It helps to run this script under 3 cases, each time adding one contour. Modify argument 1 of SetContour() on line 68 to do this.

When I run this script with 2 contours (both negative), I get the correct output. The first contour is smaller that the less negtive 2nd contour as expected. Also, it’s important to note the # of points on each graph. The smaller contours should have fewer points. We see:

z = -0.4 has 2 graphs of 107pts
z = -0.2 has 2 graphs of 133pts

running the script again but adding a 3rd (Positive) contour level, we see that the # of points changes. Now:

z = -0.4 has 2 graphs of 133pts
z = -0.2 has 2 graphs of 133pts
z = 0.2 has 2 graphs of 107pts

Also, the plots have changed. We now see cont[0] is a positive large ring, cont[1] is a negtive large ring, and cont[2] is a negative small ring. This shows that the bottom and top contours have flipped order when returned by LIST. Or:

ContIN[0] --> ContOUT[2]
ContIN[1] --> ContOUT[1]
ContIN[2] --> ContOUT[0]

running the script again with 4 contours (2 neg, 2 pos), we see the same misordering. The plots show: Large Pos, Large Neg, Small Neg, Small Pos. We can also see this in the # of points per contour.

z = -0.4 has 2 graphs of 133pts
z = -0.2 has 2 graphs of 133pts
z = 0.2 has 2 graphs of 107pts
z = 0.4 has 2 graphs of 107pts

Because the histogram2D is symmetric, we expect Z = +/- 0.2 to have the same # of points. Also, Z = 0.4 should not have the same # of points as the larger Z = 0.2

Sorry about the lengthy post. Let me know if my description makes sense to you.

Thanks,

Josh
ContListOrder.C (4.2 KB)

I think I understand the algoritm now. In order to draw the contour in the right order (to avoid they hide each other), they should be drawn from the lowest to the highest when they are positive but from the highest to the lowest when they are negative. A sorting algogrithm does that . That algorithm seems, in fact, to be wrong when there is only negative contours. In that case they are drawn from lowest to highest (even if they are negative) that is why when you ask for contours -0.4 and -0.2 you see only 2 red graphs. I will try to fix that.
So in any case, with the LIST option, you will not get the contours in the order you entered them if some are negatives.

Ok that’s great, that’s what I was thinking aswell.

As long as I know to expect them in that order, I can compensate for it.

Many thanks for your help with this,

Josh

Hi Josh,

The problem is now fixed in the CVS head. Now the contours are drawn and returned correctly when they are all on the negative side. So, as I said earlier, the positive contours are ordered from the smallest to the largest and the negative contours from the largest to the smallest. Thanks to have reported these problems.

Olivier