source: branches/alma/python/casatoolbar.py @ 1724

Last change on this file since 1724 was 1724, checked in by Kana Sugimoto, 14 years ago

New Development: Yes

JIRA Issue: Yes (CAS-1801)

Ready to Release: Yes

Interface Changes: Yes

What Interface Changed: two classes, CustomToolbarTkAgg? and CustomToolbarCommon?,

are created to a new module casatoolbar

Test Programs: run sdplot with plottype='spectra' and 'totalpower'

Put in Release Notes: Yes/No?

Module(s): CASA task sdplot, sdbaseline, sdstat, sdfit

Description:

Two new classes, CustomToolbarTkAgg? and CustomToolbarCommon?, are
created to a new module casatoolbar in order to remove backend dependency
of sdplot(). The other code are modified accordingly.
The additional toolbar, casabar, is now default in ASAP plotter
(asapplotter.plot and asapplotter.plottp).


File size: 8.3 KB
Line 
1import os
2import matplotlib
3######################################
4##    Add CASA custom toolbar       ##
5######################################
6class CustomToolbarCommon:
7    def __init__(self,parent):
8        self.plotter=parent
9        #self.figmgr=self.plotter._plotter.figmgr
10
11    ### select the nearest spectrum in pick radius
12    ###    and display spectral value on the toolbar.
13    def _select_spectrum(self,event):
14        # Do not fire event when in zooming/panning mode
15        mode = self.figmgr.toolbar.mode
16        if not mode =='':
17                return
18        # When selected point is out of panels
19        if event.inaxes == None:
20                return
21        # If not left button
22        if event.button != 1:
23                return
24
25        xclick=event.xdata
26        yclick=event.ydata
27        dist2=1000.
28        pickline=None
29        # If the pannel has picable objects
30        pflag=False
31        for lin in event.inaxes.lines:
32                if not lin.pickable(): continue
33                pflag=True
34                flag,pind = lin.contains(event)
35                if not flag: continue
36                # Get nearest point
37                inds = pind['ind']
38                xlin = lin.get_xdata()
39                ylin = lin.get_ydata()
40                for i in inds:
41                        d2=(xlin[i]-xclick)**2+(ylin[i]-yclick)**2
42                        if dist2 >= d2:
43                                dist2 = d2
44                                pickline = lin
45        # No pickcable line in the pannel
46        if not pflag: return
47        # Pickable but too far from mouse position
48        elif pickline is None:
49                picked='No line selected.'
50                self.figmgr.toolbar.set_message(picked)
51                return
52        del pind, inds, xlin, ylin
53        # Spectra are Picked
54        theplot = self.plotter._plotter
55        thetoolbar = self.figmgr.toolbar
56        thecanvas = self.figmgr.canvas
57        # Disconnect the default motion notify event
58        # Notice! the other buttons are also diabled!!!
59        thecanvas.mpl_disconnect(thetoolbar._idDrag)
60        # Get picked spectrum
61        xdata = pickline.get_xdata()
62        ydata = pickline.get_ydata()
63        titl=pickline.get_label()
64        titp=event.inaxes.title.get_text()
65        panel0=event.inaxes
66        picked="Selected: '"+titl+"' in panel '"+titp+"'."
67        thetoolbar.set_message(picked)
68        # Generate a navigation window
69        #naviwin=Navigationwindow(titp,titl)
70        #------------------------------------------------------#
71        # Show spectrum data at mouse position
72        def spec_data(event):
73                # Getting spectrum data of neiboring point
74                xclick=event.xdata
75                if event.inaxes != panel0:
76                        return
77                ipoint=len(xdata)-1
78                for i in range(len(xdata)-1):
79                        xl=xclick-xdata[i]
80                        xr=xclick-xdata[i+1]
81                        if xl*xr <= 0.:
82                                ipoint = i
83                                break
84                # Output spectral value on the navigation window
85                posi='[ %s, %s ]:  x = %.2f   value = %.2f'\
86                      %(titl,titp,xdata[ipoint],ydata[ipoint])
87                #naviwin.posi.set(posi)
88                thetoolbar.set_message(posi)
89        #------------------------------------------------------#
90        # Disconnect from mouse events
91        def discon(event):
92                #naviwin.window.destroy()
93                theplot.register('motion_notify',None)
94                # Re-activate the default motion_notify_event
95                thetoolbar._idDrag=thecanvas.mpl_connect('motion_notify_event', thetoolbar.mouse_move)
96                theplot.register('button_release',None)
97                return
98        #------------------------------------------------------#
99        # Show data value along with mouse movement
100        theplot.register('motion_notify',spec_data)
101        # Finish events when mouse button is released
102        theplot.register('button_release',discon)
103
104
105    ### Calculate statistics of the selected area.
106    def _single_mask(self,event):
107        # Do not fire event when in zooming/panning mode
108        if not self.figmgr.toolbar.mode == '': return
109        # When selected point is out of panels
110        if event.inaxes == None:
111                return
112        if event.button ==1: baseinv=True
113        elif event.button == 3: baseinv=False
114        else: return
115
116        def _calc_stats():
117                msk=mymask.get_mask()
118                mymask.scan.stats(stat='max',mask=msk)
119                mymask.scan.stats(stat='min',mask=msk)
120                mymask.scan.stats(stat='sum',mask=msk)
121                mymask.scan.stats(stat='mean',mask=msk)
122                mymask.scan.stats(stat='median',mask=msk)
123                mymask.scan.stats(stat='rms',mask=msk)
124                mymask.scan.stats(stat='stddev',mask=msk)
125
126        # Interactive mask definition
127        from asap.interactivemask import interactivemask
128        mymask=interactivemask(plotter=self.plotter,scan=self.plotter._data)
129        # Create initial mask
130        mymask.set_basemask(invert=baseinv)
131        # Inherit event
132        mymask.set_startevent(event)
133        # Set callback func
134        mymask.set_callback(_calc_stats)
135        # Selected mask
136        mymask.select_mask(once=True,showmask=False)
137
138#####################################
139##    Backend dependent Classes    ##
140#####################################
141### TkAgg
142if matplotlib.get_backend() == 'TkAgg': import Tkinter as Tk
143class CustomToolbarTkAgg(CustomToolbarCommon):
144    def __init__(self,parent):
145        from asap.asapplotter import asapplotter
146        if not isinstance(parent,asapplotter): return False
147        if not parent._plotter: return False
148        self._p=parent._plotter
149        self.figmgr=self._p.figmgr
150        self.canvas=self.figmgr.canvas
151        self.custombar=None
152        self.mode=''
153        self.button=True
154        self._add_custom_toolbar()
155        CustomToolbarCommon.__init__(self,parent)
156
157    def _add_custom_toolbar(self):
158        self.custombar=Tk.Frame(master=self.figmgr.window)
159        self.bSpec=self._NewButton(master=self.custombar,
160                                   text='spec value',
161                                   command=self.spec_show)
162        self.bStat=self._NewButton(master=self.custombar,
163                                   text='statistics',
164                                   command=self.stat_cal)
165        self.bQuit=self._NewButton(master=self.custombar,
166                                   text='Quit',
167                                   command=self.quit,
168                                   side=Tk.RIGHT)
169        self.custombar.pack(side=Tk.BOTTOM,fill=Tk.BOTH)
170       
171        ### temporary added
172        #self.bStat.config(state=Tk.DISABLED)
173        ###
174        #self.bSpec.config(relief='sunken')
175        #self.bStat.config(relief='raised')
176        #self.button=True
177        #self.spec_show()
178        self.disable_button()
179        return self
180
181    def _NewButton(self, master, text, command, side=Tk.LEFT):
182        if(os.uname()[0] == 'Darwin'):
183            b = Tk.Button(master=master, text=text, command=command)
184        else:
185            b = Tk.Button(master=master, text=text, padx=2, pady=2, command=command)
186        b.pack(side=side)
187        return b
188       
189    def spec_show(self):
190        if not self.figmgr.toolbar.mode == '' or not self.button: return
191        self.figmgr.toolbar.set_message('spec value: drag on a spec')
192        if self.mode == 'spec': return
193        self.bStat.config(relief='raised')
194        self.bSpec.config(relief='sunken')
195        self.mode='spec'
196        self.__disconnect_event()
197        #self.canvas.mpl_connect('button_press_event',self._select_spectrum)
198        self._p.register('button_press',self._select_spectrum)
199
200    def stat_cal(self):
201        if not self.figmgr.toolbar.mode == '' or not self.button: return
202        self.figmgr.toolbar.set_message('statistics: select a region')
203        if self.mode == 'stat': return
204        self.bSpec.config(relief='raised')
205        self.bStat.config(relief='sunken')
206        self.mode='stat'
207        self.__disconnect_event()
208        self._p.register('button_press',self._single_mask)
209
210    def quit(self):
211        self.__disconnect_event()
212        self.delete_bar()
213        self.figmgr.window.wm_withdraw()
214
215    def enable_button(self):
216        if self.button: return
217        self.bSpec.config(state=Tk.NORMAL)
218        self.bStat.config(state=Tk.NORMAL)
219        self.button=True
220        self.spec_show()
221       
222    def disable_button(self):
223        if not self.button: return
224        self.bStat.config(relief='raised',state=Tk.DISABLED)
225        self.bSpec.config(relief='raised',state=Tk.DISABLED)
226        self.button=False
227        self.mode=''
228        self.__disconnect_event()
229
230    def delete_bar(self):
231        self.__disconnect_event()
232        self.custombar.destroy()
233        self.custombar=None             
234
235    def __disconnect_event(self):
236        #idP=self.figmgr.toolbar._idPress
237        #idR=self.figmgr.toolbar._idRelease
238        #if idP is not None:
239        #    self.canvas.mpl_disconnect(idP)
240        #    self.figmgr.toolbar._idPress=None
241        #if idR is not None:
242        #    self.canvas.mpl_disconnect(idR)
243        #    self.figmgr.toolbar._idRelease=None
244        self._p.register('button_press',None)
245        self._p.register('button_release',None)
Note: See TracBrowser for help on using the repository browser.