GetEventX wrong?

I’m trying to overload the TGraphErrors::RemovePoint function by creating a class that inherits from TGraphErrors. The overloaded RemovePoint function uses the same code as the original one to get the position of the mouse (gPad->GetEventX() and gPad->GetEventY()), but for some reason it doesn’t always return the correct position.

I tried replicating it with a simple example, but there it always works (when assuming the returned position to be in absolute pixels), see the attached code.

Unfortunately the code with the problem is too complex to post here, but in that case when clicking on a point at (274., 346.), the resulting x,y are either 108.608, -81.429 (from absolute pixels) or 487.503, -81.429 (from pixels). I double checked that the result of gPad->GetName() indicates that the right pad is being used, and that I use the right parent for all constructors (as that was causing a similar issue at one point with the example).

Does anyone have an idea what I might be doing wrong or what else I could check? Is there anything I could print out to better understand why gPad->AbsPixeltoX(gPad->GetEventX()) returns the wrong x-position for me?

Test.C (5.5 KB)

I tried adding more output to the RemovePoint function and now I seem to be able to reproduce this with the modified example (attached).

The screenshot shows the window I get, and if I click on the third point of the right frame (2, 1.41) and then the fifth point on the left frame (6, 36), I get this output:

`
root [0]
Processing Test.C…
root [1] Using x, y 238, 242 on cal_1: abs to x,y 2.02801, 1.39598, pix to x,y 5.46551, 1.39598
x1 -1.375, x2 12.375, y1 -0.434813, y2 3.91332, Wh 418, Ww 598, uxmin 0, uxmax 11, uymin 0, uymax 3.47851, range -1.375, -0.434813; 12.375, 3.91332, axis 0, 0; 11, 3.47851

root [1] Using x, y 299, 366 on ProjectionCanvas1: abs to x,y 6, -2.33612, pix to x,y 6, -2.33612
x1 -1.5, x2 13.5, y1 -15.6125, y2 149.513, Wh 398, Ww 598, uxmin 0, uxmax 12, uymin 0.9, uymax 133, range -1.5, -15.6125; 13.5, 149.513, axis 0, 0.9; 12, 133

root [1]
`

So adding some output made the clicking the fifth point on the left frame (which is at x=6, y=36) report x=5.46551 (probably correct), and y=-2.33612 (completely wrong?).

I also tried going in a different order, starting with 5th point on the left frame, then the 3rd point on the right, and then the 5th point on the left again:

`
root [0]
Processing Test.C…
root [1] Using x, y 300, 341 on ProjectionCanvas1: abs to x,y 6.02508, 8.03605, pix to x,y 6.02508, 8.03605
x1 -1.5, x2 13.5, y1 -15.6125, y2 149.513, Wh 398, Ww 598, uxmin 0, uxmax 12, uymin 0.9, uymax 133, range -1.5, -15.6125; 13.5, 149.513, axis 0, 0.9; 12, 133

root [1] Using x, y 239, 244 on cal_1: abs to x,y 2.05675, 1.37517, pix to x,y 5.49425, 1.37517
x1 -1.375, x2 12.375, y1 -0.434813, y2 3.91332, Wh 418, Ww 598, uxmin 0, uxmax 11, uymin 0, uymax 3.47851, range -1.375, -0.434813; 12.375, 3.91332, axis 0, 0; 11, 3.47851

root [1] Using x, y 300, 275 on ProjectionCanvas1: abs to x,y 6.02508, 35.4186, pix to x,y 6.02508, 35.4186
x1 -1.5, x2 13.5, y1 -15.6125, y2 149.513, Wh 398, Ww 598, uxmin 0, uxmax 12, uymin 0.9, uymax 133, range -1.5, -15.6125; 13.5, 149.513, axis 0, 0.9; 12, 133
`
So now the first time it reports (6.02508, 8.03605) for (6, 36), and the second time it gives (6.02508, 35.4186)? And that is even though the pixel position is lower in the second case (275) than the first one (341).

Test.C (6.1 KB)

Hi,

Adding @couet in the loop.

Cheers,
D

In your latest example, if I replace myGraph by TGraph it is working fine: the points are removed correctly. I will now check what is different in your myGraph class.

Next step: I am now using your class myGraph again but I copy/paste the exact same code of
TGraph::RemovePoint() in your method myGraph::RemovePoint(). ie:

Int_t myGraph::RemovePoint()
{
   if (!gPad) {
      Error("RemovePoint", "Cannot be used without gPad, requires last mouse position");
      return -1;
   }

   Int_t px = gPad->GetEventX();
   Int_t py = gPad->GetEventY();

   //localize point to be deleted
   Int_t ipoint = -2;
   // start with a small window (in case the mouse is very close to one point)
   for (Int_t i = 0; i < fNpoints; i++) {
      Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
      Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
      if (dpx * dpx + dpy * dpy < 100) {
         ipoint = i;
         break;
      }
   }
   return RemovePoint(ipoint);
}

Then it is working fine again: the right point is deleted when I right click on it and select RemovePoint.

So GetEventX seems to work fine. Therefore the problem is very likely
in your implementation of myGraph::RemovePoint() ?

Can you confirm that if you do the same as I did (ie: blindly copy/paste the TGraph::RemovePoint()), then it works fine for also for you ?

Yes, using the code from TGraph::RemovePoint() works fine in this example. I went and tried to slowly change it back to the code I had (by adding the additional output and then removing the original TGraph code), and now I have the same code and it’s working?
So I’m back to the situation from the first post, I have code to complicated to post here (I think) that shows the issue, and simple examples don’t re-create the issue.
I tried replacing the myGraph class in the example with the more complicated one that I have, but whenever I add the line
#include "TCalibrationGraph.h"
to include the custom classes, root just exits without any error message or anything else. This happens if I do that in the example script, or even if I just type that line in cint. I tried using .L Test.C+ to see if that shows me more, and I needed to add some more include statements to get that to “work”, but even then, root quits without error message after outputting
Info in <TUnixSystem::ACLiC>: creating shared library /path/./Test_C.so

Have you tried to put the TGraph::RemovePoint() code in your complicated code ?

It looks like a different issue, isn’t it ?

I tried replacing my function with the code from TGraph::RemovePoint(), but it still looks like it does not work. It’s a bit hard to tell as in the more complex code the graph is plotted on top of another graph which contains the exact same points.

I will create a separate issue for the fact that root quits w/o error message when trying to include the header file.

I made this small example with two graphs at the exact same position.

{
   const Int_t n = 20;
   Double_t x[n], y[n], y1[n];
   for (Int_t i=0;i<n;i++) {
      x[i] = i*0.15;
      y[i] = 10*sin(x[i]+0.2);
   }
   auto gr0 = new TGraph(n,x,y);
   auto gr1 = new TGraph(n,x,y);
   gr0->SetMarkerStyle(3);
   gr1->SetMarkerStyle(3);
   gr1->SetMarkerColor(2);
   gr1->Draw("AP");
   gr0->Draw("P");
}

The first graph is red the 2nd is black. You can remove a point interactively from the black graph as it is drawn on top. Then you see the red dot appearing. But then you cannot remove the red dot because the black graph sill hides the red one because graphs are always picked as line even if they are drawn with markers only. If you move the black graph then you can delete the red point.

I managed to figure out why I wasn’t able to use a more complicated class in the example. I’ve attached the macro, plus the header and source for my custom class, and a LinkDef.h file.
To run the example I used

rootcint -f myGraphDict.cxx -I. myGraph.h LinkDef.h
g++ -fPIC -shared -o libmyGraph.so myGraph.cxx myGraphDict.cxx $(root-config --cflags)

and then within the root-session I used

.L libmyGraph.so
.x Test.C

to run it. Then I click on the right side on the point at x = 4, y = 2 and select RemovePoint from the menu. This is the output I sometimes get:

root [2] virtual Int_t myGraph::RemovePoint()
px, py 306,  243 on gPad cal_1: abs to x,y 3.98244, 1.38558
0: dpx = 139 = 306 - 167, dpy = -133 = 243 - 376 not the point we're looking for
1: dpx = 104 = 306 - 202, dpy = -37 = 243 - 280 not the point we're looking for
2: dpx = 69 = 306 - 237, dpy = 3 = 243 - 240 not the point we're looking for
3: dpx = 0 = 306 - 306, dpy = 60 = 243 - 183 not the point we're looking for
4: dpx = -35 = 306 - 341, dpy = 82 = 243 - 161 not the point we're looking for
5: dpx = -70 = 306 - 376, dpy = 103 = 243 - 140 not the point we're looking for
6: dpx = -104 = 306 - 410, dpy = 122 = 243 - 121 not the point we're looking for
7: dpx = -157 = 306 - 463, dpy = 148 = 243 - 95 not the point we're looking for
8: dpx = -174 = 306 - 480, dpy = 156 = 243 - 87 not the point we're looking for
9: dpx = -209 = 306 - 515, dpy = 171 = 243 - 72 not the point we're looking for
Failed to find point close to px, py 306,  243 on gPad cal_1: x,y 3.98244, 1.38558

The myGraph::RemovePoint() function is essentially just a copy of the TGraph::RemovePoint() function, with some added cout statements, and calls to other functions at the end of it. The point where it stops here though is before any other functions are called.

If I then zoom in on the x-axis and unzoom again before clicking at the same point and selecting the same menu item, it works and the point is removed.

As mentioned this only happens sometimes, other times it works the first time I try it.

When it works, the second line of output (after the function name) is

px, py 308,  187 on gPad cal_1: abs to x,y 4.03992, 1.9681

or

px, py 305,  184 on gPad cal_1: abs to x,y 3.96345, 1.99365

so the y-position is very different from when it fails (then it’s around 240 instead of 180), but I do click close to the point (cursor changes), and I definitely do not click around y = 1.4!

Test.C (5.2 KB)
myGraph.h (8.9 KB)
myGraph.cxx (33.8 KB)
LinkDef.h (282 Bytes)