[ROOT] Function Overriding

From: Guy Ron (ronguy@tauphy.tau.ac.il)
Date: Sun Jun 15 2003 - 12:39:00 MEST


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