Re: [ROOT] Function Overriding

From: Rene Brun (Rene.Brun@cern.ch)
Date: Mon Jun 16 2003 - 08:53:51 MEST


Hi Guy,

I cannot understand your logic in your version of THraph::ExecuteEvent
and I am not surprised that you get segmentation violations.
 - you have a test
      if (this==BBF->EGraph)...
   what is BBF ?

 - you create TH1 objects in the stack. These objects are automatically
   deleted when you leave the function!

An alternative to redefining this function is to see examples accessing
the mouse in the tutorials exec1.C, exec2.C, DynamicSlices.C

Rene Brun

Guy Ron wrote:
> 
> Hi All,
> I need to get an indication of a mouse button event on a graph and find
> the graph point clicked.
> To this end I've overridden the TGraph::ExecuteEvent function and added my
> own code at the bottom:
> 
> void TGraph::ExecuteEvent(Int_t event, Int_t px, Int_t py)
> {
> //*-*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*
> //*-*                  =========================================
> //  This member function is called when a graph is clicked with the
> locator
> //
> //  If Left button clicked on one of the line end points, this point
> //     follows the cursor until button is released.
> //
> //  if Middle button clicked, the line is moved parallel to itself
> //     until the button is released.
> //
>    Int_t i, d;
>    Double_t xmin, xmax, ymin, ymax, dx, dy, dxr, dyr;
>    const Int_t kMaxDiff = 10;
>    static Bool_t MIDDLE, BADCASE;
>    static Int_t ipoint, pxp, pyp;
>    static Int_t px1,px2,py1,py2;
>    static Int_t pxold, pyold, px1old, py1old, px2old, py2old;
>    static Int_t dpx, dpy;
>    static Int_t *x=0, *y=0;
> 
>    if (!IsEditable()) {gPad->SetCursor(kHand); return;}
>    if (!gPad->IsEditable()) return;
>    // printf("%i\n",event);
>    switch (event) {
> 
>       case kButton1Down:
>      printf("Button 1 Down\n");
>       BADCASE = kFALSE;
>       gVirtualX->SetLineColor(-1);
>       TAttLine::Modify();  //Change line attributes only if necessary
>       px1 = gPad->XtoAbsPixel(gPad->GetX1());
>       py1 = gPad->YtoAbsPixel(gPad->GetY1());
>       px2 = gPad->XtoAbsPixel(gPad->GetX2());
>       py2 = gPad->YtoAbsPixel(gPad->GetY2());
>       ipoint = -1;
> 
>       if (x || y) break;
>       x = new Int_t[fNpoints+1];
>       y = new Int_t[fNpoints+1];
>       for (i=0;i<fNpoints;i++) {
>          pxp = gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
>          pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
>          if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
>              pyp < -kMaxPixel || pyp >= kMaxPixel) {
>             BADCASE = kTRUE;
>             continue;
>          }
>          gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4,  pyp-4);
>          gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4,  pyp+4);
>          gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4,  pyp+4);
>          gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4,  pyp-4);
>          x[i] = pxp;
>          y[i] = pyp;
>          d   = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
>          if (d < kMaxDiff) ipoint =i;
>       }
>       dpx = 0;
>       dpy = 0;
>       pxold = px;
>       pyold = py;
>       if (ipoint < 0) return;
>       if (ipoint == 0) {
>          px1old = 0;
>          py1old = 0;
>          px2old = gPad->XtoAbsPixel(fX[1]);
>          py2old = gPad->YtoAbsPixel(fY[1]);
>       } else if (ipoint == fNpoints-1) {
>          px1old = gPad->XtoAbsPixel(gPad->XtoPad(fX[fNpoints-2]));
>          py1old = gPad->YtoAbsPixel(gPad->YtoPad(fY[fNpoints-2]));
>          px2old = 0;
>          py2old = 0;
>       } else {
>          px1old = gPad->XtoAbsPixel(gPad->XtoPad(fX[ipoint-1]));
>          py1old = gPad->YtoAbsPixel(gPad->YtoPad(fY[ipoint-1]));
>          px2old = gPad->XtoAbsPixel(gPad->XtoPad(fX[ipoint+1]));
>          py2old = gPad->YtoAbsPixel(gPad->YtoPad(fY[ipoint+1]));
>       }
>       pxold = gPad->XtoAbsPixel(gPad->XtoPad(fX[ipoint]));
>       pyold = gPad->YtoAbsPixel(gPad->YtoPad(fY[ipoint]));
>       /*
>     if (this==BBF->EGraph) {
> 
>       //printf("E Plane Point Number: %i\n",ipoint+1);
>       TCanvas *c1=new TCanvas();
> 
>       sprintf(dummy,"E Plane Channel %i TDC Left",ipoint+1);
>       TH1F tdcl("tdcl",dummy,100,0,2000);
>       sprintf(dummy,"E Plane Channel %i TDC Right",ipoint+1);
>       TH1F tdcr("tdcr",dummy,100,0,2000);
>       sprintf(dummy,"E Plane Channel %i ADC Left",ipoint+1);
>       TH1F adcl("adcl",dummy,100,0,2000);
>       sprintf(dummy,"E Plane Channel %i ADC Right",ipoint+1);
>       TH1F adcr("adcr",dummy,100,0,2000);
> 
>       //c1->Divide(2,2);
>       sprintf(dummy,"BB.tp.e.lt.data[%i]",ipoint);
>       sprintf(dummy1,"BB.tp.e.lt.data[%i]>0",ipoint);
>       BBTree->Draw(dummy,dummy1);
> 
>       c1->cd(2);
>       sprintf(dummy,"BB.tp.e.rt.data[%i]",ipoint);
>       BBTree->Draw(dummy);
>       c1->cd(3);
>       sprintf(dummy,"BB.tp.e.la.data[%i]",ipoint);
>       BBTree->Draw(dummy);
>       c1->cd(4);
>       sprintf(dummy,"BB.tp.e.ra.data[%i]",ipoint);
>       BBTree->Draw(dummy);
> 
>       //      BBTree->Draw("BB.tp.e.nlthit");
> 
>      } else  if (this==BBF->DEGraph) {
> 
>      }     */
>      break;
> 
>    case kMouseMotion:
> 
>       MIDDLE = kTRUE;
>       for (i=0;i<fNpoints;i++) {
>          pxp = gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
>          pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
>          d   = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
>          if (d < kMaxDiff) MIDDLE = kFALSE;
>       }
> 
> //*-*- check if point is close to an axis
>       if (MIDDLE) gPad->SetCursor(kMove);
>       else gPad->SetCursor(kHand);
>       break;
> 
>    case kButton1Motion:
>          if (MIDDLE) {
>          for(i=0;i<fNpoints-1;i++) {
>             gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx,
> y[i+1]+dpy);
>             pxp = x[i]+dpx;
>             pyp = y[i]+dpy;
>             if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
>                 pyp < -kMaxPixel || pyp >= kMaxPixel) continue;
>             gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4,  pyp-4);
>             gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4,  pyp+4);
>             gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4,  pyp+4);
>             gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4,  pyp-4);
>          }
>          pxp = x[fNpoints-1]+dpx;
>          pyp = y[fNpoints-1]+dpy;
>          gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4,  pyp-4);
>          gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4,  pyp+4);
>          gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4,  pyp+4);
>          gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4,  pyp-4);
>          dpx += px - pxold;
>          dpy += py - pyold;
>          pxold = px;
>          pyold = py;
>          for(i=0;i<fNpoints-1;i++) {
>             gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx,
> y[i+1]+dpy);
>             pxp = x[i]+dpx;
>             pyp = y[i]+dpy;
>             if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
>                 pyp < -kMaxPixel || pyp >= kMaxPixel) continue;
>             gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4,  pyp-4);
>             gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4,  pyp+4);
>             gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4,  pyp+4);
>             gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4,  pyp-4);
>          }
>          pxp = x[fNpoints-1]+dpx;
>          pyp = y[fNpoints-1]+dpy;
>          gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4,  pyp-4);
>          gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4,  pyp+4);
>          gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4,  pyp+4);
>          gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4,  pyp-4);
>       } else {
>          if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold,  pyold);
>          if (px2old) gVirtualX->DrawLine(pxold,  pyold,  px2old, py2old);
>          gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4,  pyold-4);
>          gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4,  pyold+4);
>          gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4,  pyold+4);
>          gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4,  pyold-4);
>          pxold = px;
>          pxold = TMath::Max(pxold, px1);
>          pxold = TMath::Min(pxold, px2);
>          pyold = py;
>          pyold = TMath::Max(pyold, py2);
>          pyold = TMath::Min(pyold, py1);
>          if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold,  pyold);
>          if (px2old) gVirtualX->DrawLine(pxold,  pyold,  px2old, py2old);
>          gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4,  pyold-4);
>          gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4,  pyold+4);
>          gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4,  pyold+4);
>          gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4,  pyold-4);
>       }
> 
>      break;
> 
>    case kButton1Up:
> 
>       xmin = gPad->GetUxmin();
>       xmax = gPad->GetUxmax();
>       ymin = gPad->GetUymin();
>       ymax = gPad->GetUymax();
>       dx   = xmax-xmin;
>       dy   = ymax-ymin;
>       dxr  = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
>       dyr  = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
> 
>          gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
>                       ymin - dyr*gPad->GetBottomMargin(),
>                       xmax + dxr*gPad->GetRightMargin(),
>                       ymax + dyr*gPad->GetTopMargin());
>          gPad->RangeAxis(xmin, ymin, xmax, ymax);
> 
>       if (MIDDLE) {
>          for(i=0;i<fNpoints;i++) {
>             if (BADCASE) continue;  //do not update if big zoom and points
> moved
>             fX[i] = gPad->PadtoX(gPad->AbsPixeltoX(x[i]+dpx));
>             fY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy));
>          }
>       } else {
>          fX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(pxold));
>          fY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(pyold));
>          if (InheritsFrom("TCutG")) {
>             //make sure first and last point are the same
>             if (ipoint == 0) {
>                fX[fNpoints-1] = fX[0];
>                fY[fNpoints-1] = fY[0];
>             }
>             if (ipoint == fNpoints-1) {
>                fX[0] = fX[fNpoints-1];
>                fY[0] = fY[fNpoints-1];
>             }
>          }
> 
>       }
> 
>       BADCASE = kFALSE;
>       delete [] x; x = 0;
>       delete [] y; y = 0;
>       gPad->Modified(kTRUE);
>       gVirtualX->SetLineColor(-1);
>   if (this==BBF->EGraph) {
> 
>       //printf("E Plane Point Number: %i\n",ipoint+1);
>       TCanvas *c1=new TCanvas();
> 
>       sprintf(dummy,"E Plane Channel %i TDC Left",ipoint+1);
>       TH1F tdcl("tdcl",dummy,100,0,2000);
>       sprintf(dummy,"E Plane Channel %i TDC Right",ipoint+1);
>       TH1F tdcr("tdcr",dummy,100,0,2000);
>       sprintf(dummy,"E Plane Channel %i ADC Left",ipoint+1);
>       TH1F adcl("adcl",dummy,100,0,2000);
>       sprintf(dummy,"E Plane Channel %i ADC Right",ipoint+1);
>       TH1F adcr("adcr",dummy,100,0,2000);
> 
>       //c1->Divide(2,2);
>       sprintf(dummy,"BB.tp.e.lt.data[%i]",ipoint);
>       sprintf(dummy1,"BB.tp.e.lt.data[%i]>0",ipoint);
>       BBTree->Draw(dummy,dummy1);
> 
>       //      BBTree->Draw("BB.tp.e.nlthit");
> 
>      } else  if (this==BBF->DEGraph) {
> 
>      }
> 
>    }
>    }
> 
> The problem is that when I do this I get the following error message when
> clicking on the graph:
> 
>  *** Break *** segmentation violation
>  Generating stack trace...
>  0x401aa93b in TUnixSystem::StackTrace(void) + 0x25b from
> /home/rshneor/root/lib/libCore.so
>  0x401a95ba in TUnixSystem::DispatchSignals(ESignals) + 0xb2 from
> /home/rshneor/root/lib/libCore.so
>  0x401a8763 in <unknown> from /home/rshneor/root/lib/libCore.so
>  0x401ac1fd in <unknown> from /home/rshneor/root/lib/libCore.so
>  0x41036f05 in <unknown> from /lib/i686/libpthread.so.0
>  0x42029188 in <unknown> from ./BBgui
>  0x00000000 in <unknown function>
> 
> and the program still runs, when I try to divide the new canvas, though,
> and try to plot several histograms it crashes completely.
> 
> My questions are:
> 1. What's happening and is there any way to avoid it?
> 2. I may be able to work around this by storing the number of the clicked
> opint somewhere and using a timer to plot the histograms, so how do I set
> up such a timer?
> 
> Thanks,
>                 Guy Ron
>                 Tel Aviv University



This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:12 MET