## \file
## \ingroup tutorial_pyroot
## \notebook
## Example of function called when a mouse event occurs in a pad.
## When moving the mouse in the canvas, a second canvas shows the
## projection along X of the bin corresponding to the Y position
## of the mouse. The resulting histogram is fitted with a gaussian.
## A "dynamic" line shows the current bin position in Y.
## This more elaborated example can be used as a starting point
## to develop more powerful interactive applications exploiting CINT
## as a development engine.
##
## Note that a class is used to hold on to the canvas that display
## the selected slice.
##
## \macro_image
## \macro_code
##
## \author Rene Brun, Johann Cohen-Tanugi, Wim Lavrijsen, Enric Tejedor
##
## Ajay Y. Deo
## Run this as: python2 -i DynamicSlice_GG.py 

import sys
import ctypes
import array

#from ROOT import TPad, TFile, TPaveLabel, TPaveText, TSpectrum, TSpectrum2
#from ROOT import gRandom, gPad, gROOT, gVirtualX
#from ROOT import kTRUE, kRed
#from ROOT import TCanvas, TH2, TH2F
from ROOT import *

class DynamicExec:

   def __init__( self ):
      self._cX   = None
      self._cY   = None
      self._old  = None

   def __call__( self ):

      h = gPad.GetSelected();
      if not h:
         return

      if not isinstance( h, TH2 ):
         return

      gPad.GetCanvas().FeedbackMode( kTRUE )

    # erase old position and draw a line at current position
      px = gPad.GetEventX()
      py = gPad.GetEventY()

      uxmin, uxmax = gPad.GetUxmin(), gPad.GetUxmax()
      uymin, uymax = gPad.GetUymin(), gPad.GetUymax()
      pxmin, pxmax = gPad.XtoAbsPixel( uxmin ), gPad.XtoAbsPixel( uxmax )
      pymin, pymax = gPad.YtoAbsPixel( uymin ), gPad.YtoAbsPixel( uymax )

      if self._old != None:
         gVirtualX.DrawLine( pxmin, self._old[1], pxmax, self._old[1] )
         gVirtualX.DrawLine( self._old[0], pymin, self._old[0], pymax )
      gVirtualX.DrawLine( pxmin, py, pxmax, py )
      gVirtualX.DrawLine( px, pymin, px, pymax )

      self._old = px, py

      upx = gPad.AbsPixeltoX( px )
      x = gPad.PadtoX( upx )
      upy = gPad.AbsPixeltoY( py )
      y = gPad.PadtoY( upy )

      padsav = gPad

    # create or set the display canvases
      if not self._cX:
         self._cX = TCanvas( 'c2', 'Projection Canvas in X', 730, 10, 700, 500 )
      else:
         self._DestroyPrimitive( 'X' )

      if not self._cY:
         self._cY = TCanvas( 'c3', 'Projection Canvas in Y', 10, 550, 700, 500 )
      else:
         self._DestroyPrimitive( 'Y' )

      self.DrawSlice( h, y, 'Y' )
      self.DrawSlice( h, x, 'X' )

      padsav.cd()

   def _DestroyPrimitive( self, xy ):
      proj = getattr( self, '_c'+xy ).GetPrimitive( 'Projection '+xy )
      if proj:
         proj.IsA().Destructor( proj )

   def DrawSlice( self, histo, value, xy ):
      yx = xy == 'X' and 'Y' or 'X'

    # draw slice corresponding to mouse position
      canvas = getattr( self, '_c'+xy )
      canvas.SetGrid()
      canvas.cd()

      bin = getattr( histo, 'Get%saxis' % xy )().FindBin( value )
      #hp = getattr( histo, 'Projection' + yx )( '', bin, bin )
      hp = getattr( histo, 'Projection' + yx )( '', bin-4, bin+4 )
      hp.SetFillColor( 38 )
      hp.SetName( 'Projection ' + xy )
      hp.SetTitle( xy + '-Projection of %d keV' % (bin/2) + ' from %d' %((bin-4)/2) + ' to %d' %((bin+4)/2) )

      #hp.Draw()

      npeaks = 100
      threshold = 0.5
      s = TSpectrum(2*npeaks)
      nfound = s.Search(hp,3,"",threshold)
      xfound = s.GetPositionX()
      #print(nfound)

      pPosition = [0]*nfound
      pHeight = [0]*nfound

      for p in range (0, nfound):
          #print(xfound[p])
          pPosition[p] = xfound[p]
          xbin = hp.GetXaxis().FindBin(pPosition[p])
          pHeight[p] = hp.GetBinContent(xbin)
          #print(pPosition[p], pHeight[p])
          #t2 = TText(0.5*pPosition[p]-1,pHeight[p]*0.90, '%g' %((pPosition[p])*0.5))
          #t2 = TText(pPosition[p]-1, pHeight[p]*0.90, '%d %(pPosition[p])')
          #t2 = TText(pPosition[p]-1, pHeight[p]*0.90, Form('%g' %(pPosition[p])))
          t2 = TText(pPosition[p]-1, pHeight[p]*0.90, Form("%s" %(pPosition[p])))
          t2.SetTextAngle(90)
          t2.SetTextColor(kBlue)
          t2.SetTextSize(0.03)
          t2.Draw()
          
          #functions = hp.GetListOfFunctions()
          #pm = functions.FindObject("TPolyMarker")
          #functions.Remove(pm)
      gPad.Modified()
      gPad.Update()
      #canvas.Update()

if __name__ == '__main__':
 # create a new canvas.
   c1 = TCanvas('c1', 'Dynamic Slicer', 10, 10, 700, 500 )
   #c1.SetFillColor( 42 )
   #c1.SetFrameFillColor( 33 )

# We connect the ROOT file
#
example = TFile( 'test54.root' )
example.ls()

his2D_wb = gROOT.FindObject( 'his2D_clean' )
his2D_wb.GetXaxis().SetRangeUser(100., 2000.);
his2D_wb.GetYaxis().SetRangeUser(100., 2000.);

xmin = his2D_wb.GetXaxis().GetXmin();
xmax = his2D_wb.GetXaxis().GetXmax();

new_xmin = xmin/2
new_xmax = xmax/2

his2D_wb.GetXaxis().SetLimits(new_xmin, new_xmax);
his2D_wb.GetYaxis().SetLimits(new_xmin, new_xmax);

his2D_wb.Draw( 'COLZ' )

 # Add a TExec object to the canvas (explicit use of __main__ is for IPython)
import __main__
__main__.slicer = DynamicExec()
c1.AddExec( 'dynamic', 'TPython::Exec( "slicer()" );' )
c1.SetLogz()
c1.Update()
