source: sasview/sansguiframe/src/sans/guiframe/local_perspectives/plotting/Plotter2D.py @ 9ccb7e1

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 9ccb7e1 was 0aca693, checked in by Jae Cho <jhjcho@…>, 12 years ago

Added showing "DataInfor?" from data panel as well as from plot

  • Property mode set to 100644
File size: 28.8 KB
Line 
1
2################################################################################
3#This software was developed by the University of Tennessee as part of the
4#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
5#project funded by the US National Science Foundation.
6#
7#See the license text in license.txt
8#
9#copyright 2008, University of Tennessee
10################################################################################
11
12
13import wx
14import sys
15import os
16import math
17import numpy
18import pylab
19import danse.common.plottools
20from danse.common.plottools.PlotPanel import PlotPanel
21from danse.common.plottools.plottables import Graph
22from danse.common.plottools.TextDialog import TextDialog
23from sans.guiframe.events import EVT_NEW_PLOT
24from sans.guiframe.events import EVT_SLICER_PARS
25from sans.guiframe.events import StatusEvent
26from sans.guiframe.events import NewPlotEvent
27from sans.guiframe.events import PanelOnFocusEvent
28from sans.guiframe.events import SlicerEvent
29from sans.guiframe.utils import PanelMenu
30from binder import BindArtist
31from Plotter1D import ModelPanel1D
32from danse.common.plottools.toolbar import NavigationToolBar
33from sans.guiframe.dataFitting import Data1D
34from matplotlib.font_manager import FontProperties
35(InternalEvent, EVT_INTERNAL) = wx.lib.newevent.NewEvent()
36
37DEFAULT_QMAX = 0.05
38DEFAULT_QSTEP = 0.001
39DEFAULT_BEAM = 0.005
40BIN_WIDTH = 1.0
41
42
43class NavigationToolBar2D(NavigationToolBar):
44    """
45    """
46    def __init__(self, canvas, parent=None):
47        NavigationToolBar.__init__(self, canvas=canvas, parent=parent)
48       
49    def delete_option(self):
50        """
51        remove default toolbar item
52        """
53        #delete reset button
54        self.DeleteToolByPos(0) 
55        #delete dragging
56        self.DeleteToolByPos(2) 
57        #delete unwanted button that configures subplot parameters
58        self.DeleteToolByPos(4)
59       
60    def add_option(self):
61        """
62        add item to the toolbar
63        """
64        #add button
65        id_context = wx.NewId()
66        context_tip = 'Graph Menu'
67        context =  wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR)
68        self.InsertSimpleTool(0, id_context, context, 
69                                   context_tip, context_tip)
70        wx.EVT_TOOL(self, id_context,  self.parent.onToolContextMenu)
71        self.InsertSeparator(1)
72        #add print button
73        id_print = wx.NewId()
74        print_bmp =  wx.ArtProvider.GetBitmap(wx.ART_PRINT, wx.ART_TOOLBAR)
75        self.AddSimpleTool(id_print, print_bmp,
76                           'Print', 'Activate printing')
77        wx.EVT_TOOL(self, id_print, self.on_print)
78       
79       
80class ModelPanel2D(ModelPanel1D):
81    """
82    Plot panel for use with the GUI manager
83    """
84   
85    ## Internal name for the AUI manager
86    window_name = "plotpanel"
87    ## Title to appear on top of the window
88    window_caption = "Plot Panel"
89    ## Flag to tell the GUI manager that this panel is not
90    #  tied to any perspective
91    ALWAYS_ON = True
92    ## Group ID
93    group_id = None
94   
95   
96    def __init__(self, parent, id=-1, data2d=None, color = None,
97                 dpi=None, style=wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
98        """
99        Initialize the panel
100        """
101        ModelPanel1D.__init__(self, parent, id=id, style=style, **kwargs)
102       
103        ## Reference to the parent window
104        self.parent = parent
105        ## Dictionary containing Plottables
106        self.plots = {}
107        ## Save reference of the current plotted
108        self.data2D = data2d
109        ## Unique ID (from gui_manager)
110        self.uid = None
111        ## Action IDs for internal call-backs
112        self.action_ids = {}
113        ## Create Artist and bind it
114        self.connect = BindArtist(self.subplot.figure)
115        ## Beam stop
116        self.beamstop_radius = DEFAULT_BEAM
117        ## to set the order of lines drawn first.
118        self.slicer_z = 5
119        ## Reference to the current slicer
120        self.slicer = None
121        ## event to send slicer info
122        self.Bind(EVT_INTERNAL, self._onEVT_INTERNAL)
123       
124        self.axes_frozen = False
125        ## panel that contains result from slicer motion (ex: Boxsum info)
126        self.panel_slicer = None
127        self.title_label = None
128        self.title_font = None
129        self.title_color = 'black'
130        ## Graph       
131        self.graph = Graph()
132        self.graph.xaxis("\\rm{Q}", 'A^{-1}')
133        self.graph.yaxis("\\rm{Intensity} ", "cm^{-1}")
134        self.graph.render(self)
135        ## store default value of zmin and zmax
136        self.default_zmin_ctl = self.zmin_2D
137        self.default_zmax_ctl = self.zmax_2D
138       
139    def onLeftDown(self, event): 
140        """
141        left button down and ready to drag
142       
143        """
144        # Check that the LEFT button was pressed
145        PlotPanel.onLeftDown(self, event)   
146        ax = event.inaxes
147        if ax != None:
148            # data coordinate position
149            pos_x = "%8.3g"% event.xdata
150            pos_y = "%8.3g"% event.ydata
151            position = "x: %s    y: %s" % (pos_x, pos_y)
152            wx.PostEvent(self.parent, StatusEvent(status=position))
153        self.plottable_selected(self.data2D.id)
154        self._manager.set_panel_on_focus(self)
155        wx.PostEvent(self.parent, PanelOnFocusEvent(panel=self))
156       
157    def add_toolbar(self):
158        """
159        add toolbar
160        """
161        self.enable_toolbar = True
162        self.toolbar = NavigationToolBar2D(parent=self, canvas=self.canvas)
163        self.toolbar.Realize()
164        # On Windows platform, default window size is incorrect, so set
165        # toolbar width to figure width.
166        tw, th = self.toolbar.GetSizeTuple()
167        fw, fh = self.canvas.GetSizeTuple()
168        self.toolbar.SetSize(wx.Size(fw, th))
169        self.sizer.Add(self.toolbar, 0, wx.LEFT|wx.EXPAND)
170        # update the axes menu on the toolbar
171        self.toolbar.update()
172         
173    def plot_data(self, data):
174        """
175        Data is ready to be displayed
176       
177        :TODO: this name should be changed to something more appropriate
178             Don't forget that changing this name will mean changing code
179             in plotting.py
180         
181        :param event: data event
182        """
183        xlo = None
184        xhi = None
185        ylo = None 
186        yhi = None
187        if data.__class__.__name__ == 'Data1D':
188            return
189        ## Update self.data2d with the current plot
190        self.data2D = data
191        if data.id in self.plots.keys():
192            #replace
193            xlo, xhi = self.subplot.get_xlim()
194            ylo, yhi = self.subplot.get_ylim()
195            self.graph.replace(data)
196            self.plots[data.id] = data
197        else:
198            self.plots[data.id] = data
199            self.graph.add(self.plots[data.id]) 
200            # update qmax with the new xmax of data plotted
201            self.qmax = data.xmax
202           
203        self.slicer = None
204        # Check axis labels
205        #TODO: Should re-factor this
206        ## render the graph with its new content
207               
208        #data2D: put 'Pixel (Number)' for axis title and unit in case of having no detector info and none in _units
209        if len(data.detector) < 1: 
210            if len(data._xunit) < 1 and len(data._yunit) < 1:
211                data._xaxis = '\\rm{x}'
212                data._yaxis = '\\rm{y}'
213                data._xunit = 'pixel'
214                data._yunit = 'pixel'
215       
216        # graph properties
217        self.graph.xaxis(data._xaxis, data._xunit)
218        self.graph.yaxis(data._yaxis, data._yunit)
219        if self._is_changed_legend_label:   
220                data.label = self.title_label
221       
222        if data.label == None:
223            data.label = data.name
224           
225        if not self.title_font:
226            self.graph.title(data.label)
227            self.graph.render(self)
228            # Set the axis labels on subplot
229            self._set_axis_labels()
230            self.draw_plot()
231        else:
232            self.graph.render(self)
233            self.draw_plot()
234            self.subplot.set_title(label=data.label,
235                                   fontproperties=self.title_font,
236                                   color=self.title_color)
237            self.subplot.figure.canvas.draw_idle() 
238       
239       
240        ## store default value of zmin and zmax
241        self.default_zmin_ctl = self.zmin_2D
242        self.default_zmax_ctl = self.zmax_2D
243        # Check if zoomed
244        toolbar_zoomed = self.toolbar.GetToolEnabled(self.toolbar._NTB2_BACK)
245        if not self.is_zoomed and not toolbar_zoomed:
246            return
247       
248        # Recover the x,y limits
249        if (xlo and xhi and ylo and yhi) != None:
250            if (xlo > data.xmin and xhi < data.xmax and\
251                        ylo > data.ymin and yhi < data.ymax):
252                self.subplot.set_xlim((xlo, xhi))     
253                self.subplot.set_ylim((ylo, yhi)) 
254            else: 
255                self.toolbar.update()
256                self._is_zoomed = False
257               
258        # Update Graph menu and help string       
259        pos = self.parent._window_menu.FindItem(self.window_caption)
260        helpString = 'Show/Hide Graph: '
261        helpString += (' ' + str(data.label) +';')
262        self.parent._window_menu.SetHelpString(pos, helpString)
263
264    def _set_axis_labels(self):
265        """
266        Set axis labels
267        """
268        data = self.data2D
269        # control axis labels from the panel itself
270        yname, yunits = data.get_yaxis()
271        if self.yaxis_label != None:
272            yname = self.yaxis_label
273            yunits = self.yaxis_unit
274        else:
275            self.yaxis_label = yname
276            self.yaxis_unit = yunits
277        xname, xunits = data.get_xaxis()
278        if self.xaxis_label != None:
279            xname = self.xaxis_label
280            xunits = self.xaxis_unit
281        else:
282            self.xaxis_label = xname
283            self.xaxis_unit = xunits
284        self.xaxis(xname, xunits, self.xaxis_font, 
285                   self.xaxis_color, self.xaxis_tick)
286        self.yaxis(yname, yunits, self.yaxis_font, 
287                   self.yaxis_color, self.yaxis_tick)
288       
289    def onContextMenu(self, event):
290        """
291        2D plot context menu
292       
293        :param event: wx context event
294       
295        """
296        slicerpop = PanelMenu()
297        slicerpop.set_plots(self.plots)
298        slicerpop.set_graph(self.graph)
299             
300        id = wx.NewId()
301        slicerpop.Append(id, '&Save Image')
302        wx.EVT_MENU(self, id, self.onSaveImage)
303       
304        id = wx.NewId()
305        slicerpop.Append(id,'&Print Image', 'Print image')
306        wx.EVT_MENU(self, id, self.onPrint)
307       
308        id = wx.NewId()
309        slicerpop.Append(id,'&Print Preview', 'Print preview')
310        wx.EVT_MENU(self, id, self.onPrinterPreview)
311
312        id = wx.NewId()
313        slicerpop.Append(id, '&Copy to Clipboard', 'Copy to the clipboard')
314        wx.EVT_MENU(self, id, self.OnCopyFigureMenu)
315        slicerpop.AppendSeparator()
316        # saving data
317        plot = self.data2D
318        id = wx.NewId()
319        name = plot.name
320        slicerpop.Append(id, "&Data Info" )
321        wx.EVT_MENU(self, id, self._onDataShow)
322
323        id = wx.NewId()
324        name = plot.name
325        slicerpop.Append(id, "&Save as a File (DAT)" )
326        self.action_ids[str(id)] = plot
327        wx.EVT_MENU(self, id, self._onSave)
328
329        slicerpop.AppendSeparator()
330        if len(self.data2D.detector) == 1:       
331           
332            item_list = self.parent.get_context_menu(self)
333            if (not item_list == None) and (not len(item_list) == 0) and\
334                self.data2D.name.split(" ")[0] != 'Residuals': 
335                # The line above; Not for trunk
336                for item in item_list:
337                    try:
338                        id = wx.NewId()
339                        slicerpop.Append(id, item[0], item[1])
340                        wx.EVT_MENU(self, id, item[2])
341                    except:
342                        msg = "ModelPanel1D.onContextMenu: "
343                        msg += "bad menu item  %s"%sys.exc_value
344                        wx.PostEvent(self.parent, StatusEvent(status=msg))
345                        pass
346                slicerpop.AppendSeparator()
347           
348            id = wx.NewId()
349            slicerpop.Append(id, '&Perform Circular Average')
350            wx.EVT_MENU(self, id, self.onCircular) \
351            # For Masked Data
352            if not plot.mask.all():
353                id = wx.NewId()
354                slicerpop.Append(id, '&Masked Circular Average')
355                wx.EVT_MENU(self, id, self.onMaskedCircular) 
356            id = wx.NewId()
357            slicerpop.Append(id, '&Sector [Q View]')
358            wx.EVT_MENU(self, id, self.onSectorQ) 
359            id = wx.NewId()
360            slicerpop.Append(id, '&Annulus [Phi View ]')
361            wx.EVT_MENU(self, id, self.onSectorPhi) 
362            id = wx.NewId()
363            slicerpop.Append(id, '&Box Sum')
364            wx.EVT_MENU(self, id, self.onBoxSum) 
365            id = wx.NewId()
366            slicerpop.Append(id, '&Box Averaging in Qx')
367            wx.EVT_MENU(self, id, self.onBoxavgX) 
368            id = wx.NewId()
369            slicerpop.Append(id, '&Box Averaging in Qy')
370            wx.EVT_MENU(self, id, self.onBoxavgY) 
371            if self.slicer != None:
372                id = wx.NewId()
373                slicerpop.Append(id, '&Clear Slicer')
374                wx.EVT_MENU(self, id,  self.onClearSlicer) 
375                if self.slicer.__class__.__name__  != "BoxSum":
376                    id = wx.NewId()
377                    slicerpop.Append(id, '&Edit Slicer Parameters')
378                    wx.EVT_MENU(self, id, self._onEditSlicer) 
379            slicerpop.AppendSeparator() 
380           
381        id = wx.NewId()
382        slicerpop.Append(id, '&Edit Graph Label', 'Edit Graph Label')
383        wx.EVT_MENU(self, id, self.onEditLabels)
384        slicerpop.AppendSeparator()
385       
386        id = wx.NewId()
387        slicerpop.Append(id, '&Edit Y Axis Label')
388        wx.EVT_MENU(self, id, self._on_yaxis_label)     
389        id = wx.NewId()
390        slicerpop.Append(id, '&Edit X Axis Label')
391        wx.EVT_MENU(self, id, self._on_xaxis_label)
392        id = wx.NewId()
393        slicerpop.Append(id, '&Toggle Grid On/Off', 'Toggle Grid On/Off')
394        wx.EVT_MENU(self, id, self.onGridOnOff)
395        slicerpop.AppendSeparator()
396       
397        id = wx.NewId()
398        slicerpop.Append(id, '&2D Color Map')
399        wx.EVT_MENU(self, id, self._onEditDetector)
400        slicerpop.AppendSeparator()
401       
402        id = wx.NewId()
403        slicerpop.Append(id, '&Toggle Linear/Log Scale')
404        wx.EVT_MENU(self, id, self._onToggleScale) 
405       
406       
407        slicerpop.AppendSeparator()
408        id = wx.NewId()
409        slicerpop.Append(id, '&Window Title')
410        wx.EVT_MENU(self, id, self.onChangeCaption)
411       
412        try:
413            pos_evt = event.GetPosition()
414            pos = self.ScreenToClient(pos_evt)
415        except:
416            pos_x, pos_y = self.toolbar.GetPositionTuple()
417            pos = (pos_x, pos_y + 5)
418        self.PopupMenu(slicerpop, pos)
419       
420           
421    def onEditLabels(self, event):
422        """
423        Edit legend label
424        """
425        selected_plot = self.plots[self.graph.selected_plottable]
426        label = selected_plot.label
427        dial = TextDialog(None, -1, 'Change Label', label)
428        if dial.ShowModal() == wx.ID_OK:
429            try:
430                FONT = FontProperties()
431                newlabel = dial.getText()
432                font = FONT.copy()
433                font.set_size(dial.getSize())
434                font.set_family(dial.getFamily())
435                font.set_style(dial.getStyle())
436                font.set_weight(dial.getWeight())
437                colour = dial.getColor()
438                if len(newlabel) > 0:
439                    # update Label
440                    selected_plot.label = newlabel
441                    self.graph.title(newlabel)
442                    self.title_label = selected_plot.label
443                    self.title_font = font
444                    self.title_color = colour
445                    ## render the graph
446                    self.subplot.set_title(label=self.title_label,
447                                           fontproperties=self.title_font,
448                                           color=self.title_color)
449                    self._is_changed_legend_label = True
450                    self.subplot.figure.canvas.draw_idle() 
451            except:
452                if self.parent != None:
453                    from sans.guiframe.events import StatusEvent
454                    msg= "Add Text: Error. Check your property values..."
455                    wx.PostEvent(self.parent, StatusEvent(status = msg ))
456                else:
457                    raise
458        dial.Destroy()
459       
460        # Update Graph menu and help string
461        if self.title_label != None:     
462            pos = self.parent._window_menu.FindItem(self.window_caption)
463            helpString = 'Show/Hide Graph: '
464            helpString += (' ' + str(self.title_label) +';')
465            self.parent._window_menu.SetHelpString(pos, helpString)
466
467       
468    def _onEditDetector(self, event):
469        """
470        Allow to view and edits  detector parameters
471       
472        :param event: wx.menu event
473       
474        """
475        import detector_dialog
476        dialog = detector_dialog.DetectorDialog(self, -1,base=self.parent,
477                       reset_zmin_ctl =self.default_zmin_ctl,
478                       reset_zmax_ctl = self.default_zmax_ctl,cmap=self.cmap)
479        ## info of current detector and data2D
480        xnpts = len(self.data2D.x_bins)
481        ynpts = len(self.data2D.y_bins)
482        xmax = max(self.data2D.xmin, self.data2D.xmax)
483        ymax = max(self.data2D.ymin, self.data2D.ymax)
484        qmax = math.sqrt(math.pow(xmax, 2) + math.pow(ymax, 2))
485        beam = self.data2D.xmin
486        ## set dialog window content
487        dialog.setContent(xnpts=xnpts,ynpts=ynpts,qmax=qmax,
488                           beam=self.data2D.xmin,
489                           zmin = self.zmin_2D,
490                          zmax = self.zmax_2D)
491        if dialog.ShowModal() == wx.ID_OK:
492            evt = dialog.getContent()
493            self.zmin_2D = evt.zmin
494            self.zmax_2D = evt.zmax
495            self.cmap = evt.cmap
496        dialog.Destroy()
497        ## Redraw the current image
498        self.image(data=self.data2D.data,
499                   qx_data=self.data2D.qx_data,
500                   qy_data=self.data2D.qy_data,
501                   xmin= self.data2D.xmin,
502                   xmax= self.data2D.xmax,
503                   ymin= self.data2D.ymin,
504                   ymax= self.data2D.ymax,
505                   zmin= self.zmin_2D,
506                   zmax= self.zmax_2D,
507                   cmap= self.cmap,
508                   color=0, symbol=0, label=self.data2D.name)
509        self.subplot.figure.canvas.draw_idle()
510       
511    def freeze_axes(self):
512        """
513        """
514        self.axes_frozen = True
515       
516    def thaw_axes(self):
517        """
518        """
519        self.axes_frozen = False
520       
521    def onMouseMotion(self,event):
522        """
523        """
524        pass
525   
526    def onWheel(self, event):
527        """
528        """
529        pass 
530     
531    def update(self, draw=True):
532        """
533        Respond to changes in the model by recalculating the
534        profiles and resetting the widgets.
535        """
536        self.draw_plot()
537       
538    def _getEmptySlicerEvent(self):
539        """
540        create an empty slicervent
541        """
542        return SlicerEvent(type=None, params=None, obj_class=None)
543       
544    def _onEVT_INTERNAL(self, event):
545        """
546        Draw the slicer
547       
548        :param event: wx.lib.newevent (SlicerEvent) containing slicer
549            parameter
550           
551        """
552        self._setSlicer(event.slicer)
553           
554    def _setSlicer(self, slicer):
555        """
556        Clear the previous slicer and create a new one.Post an internal
557        event.
558       
559        :param slicer: slicer class to create
560       
561        """
562        ## Clear current slicer
563        if not self.slicer == None: 
564            self.slicer.clear()           
565        ## Create a new slicer   
566        self.slicer_z += 1
567        self.slicer = slicer(self, self.subplot, zorder=self.slicer_z)
568        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
569        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
570        ## Draw slicer
571        self.update()
572        self.slicer.update()
573        msg = "Plotter2D._setSlicer  %s"%self.slicer.__class__.__name__
574        wx.PostEvent(self.parent, StatusEvent(status=msg))
575        # Post slicer event
576        event = self._getEmptySlicerEvent()
577        event.type = self.slicer.__class__.__name__
578        event.obj_class = self.slicer.__class__
579        event.params = self.slicer.get_params()
580        wx.PostEvent(self, event)
581       
582    def onMaskedCircular(self, event):
583        """
584        perform circular averaging on Data2D with mask if it exists
585       
586        :param event: wx.menu event
587       
588        """
589        self.onCircular(event, True)
590       
591    def onCircular(self, event, ismask=False):
592        """
593        perform circular averaging on Data2D
594       
595        :param event: wx.menu event
596       
597        """
598        # Find the best number of bins
599        npt = math.sqrt(len(self.data2D.data[numpy.isfinite(self.data2D.data)]))
600        npt = math.floor(npt)
601        from sans.dataloader.manipulations import CircularAverage
602        ## compute the maximum radius of data2D
603        self.qmax = max(math.fabs(self.data2D.xmax), 
604                        math.fabs(self.data2D.xmin))
605        self.ymax = max(math.fabs(self.data2D.ymax),
606                        math.fabs(self.data2D.ymin))
607        self.radius = math.sqrt(math.pow(self.qmax, 2)+ math.pow(self.ymax, 2)) 
608        ##Compute beam width
609        bin_width = (self.qmax + self.qmax)/npt
610        ## Create data1D circular average of data2D
611        Circle = CircularAverage(r_min=0, r_max=self.radius, 
612                                 bin_width=bin_width)
613        circ = Circle(self.data2D, ismask=ismask)
614        from sans.guiframe.dataFitting import Data1D
615        if hasattr(circ, "dxl"):
616            dxl = circ.dxl
617        else:
618            dxl = None
619        if hasattr(circ, "dxw"):
620            dxw = circ.dxw
621        else:
622            dxw = None
623
624        new_plot = Data1D(x=circ.x, y=circ.y, dy=circ.dy, dx=circ.dx)
625        new_plot.dxl = dxl
626        new_plot.dxw = dxw
627        new_plot.name = "Circ avg " + self.data2D.name
628        new_plot.source = self.data2D.source
629        #new_plot.info = self.data2D.info
630        new_plot.interactive = True
631        new_plot.detector = self.data2D.detector
632       
633        ## If the data file does not tell us what the axes are, just assume...
634        new_plot.xaxis("\\rm{Q}", "A^{-1}")
635        if hasattr(self.data2D, "scale") and \
636                    self.data2D.scale == 'linear':
637            new_plot.ytransform = 'y'
638            new_plot.yaxis("\\rm{Residuals} ", "normalized")
639        else:
640            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
641
642        new_plot.group_id = "Circ avg " + self.data2D.name
643        new_plot.id = "Circ avg " + self.data2D.name
644        new_plot.is_data = True
645        self.parent.update_theory(data_id=self.data2D, \
646                                       theory=new_plot)
647        wx.PostEvent(self.parent, 
648                     NewPlotEvent(plot=new_plot, title=new_plot.name))
649       
650    def _onEditSlicer(self, event):
651        """
652        Is available only when a slicer is drawn.Create a dialog
653        window where the user can enter value to reset slicer
654        parameters.
655       
656        :param event: wx.menu event
657       
658        """
659        if self.slicer != None:
660            from SlicerParameters import SlicerParameterPanel
661            dialog = SlicerParameterPanel(self, -1, "Slicer Parameters")
662            dialog.set_slicer(self.slicer.__class__.__name__,
663                            self.slicer.get_params())
664            if dialog.ShowModal() == wx.ID_OK:
665                dialog.Destroy() 
666       
667    def onSectorQ(self, event):
668        """
669        Perform sector averaging on Q and draw sector slicer
670        """
671        from SectorSlicer import SectorInteractor
672        self.onClearSlicer(event)
673        wx.PostEvent(self, InternalEvent(slicer=SectorInteractor))
674       
675    def onSectorPhi(self, event):
676        """
677        Perform sector averaging on Phi and draw annulus slicer
678        """
679        from AnnulusSlicer import AnnulusInteractor
680        self.onClearSlicer(event)
681        wx.PostEvent(self, InternalEvent(slicer=AnnulusInteractor))
682       
683    def onBoxSum(self, event):
684        """
685        """
686        from boxSum import BoxSum
687        self.onClearSlicer(event)
688        self.slicer_z += 1
689        self.slicer =  BoxSum(self, self.subplot, zorder=self.slicer_z)
690        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
691        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
692        self.update()
693        self.slicer.update()
694        ## Value used to initially set the slicer panel
695        type = self.slicer.__class__.__name__
696        params = self.slicer.get_params()
697        ## Create a new panel to display results of summation of Data2D
698        from slicerpanel import SlicerPanel
699        new_panel = SlicerPanel(parent=self.parent, id=-1,
700                                    base=self, type=type,
701                                    params=params, style=wx.RAISED_BORDER)
702       
703        new_panel.window_caption = self.slicer.__class__.__name__ + " " + \
704                                    str(self.data2D.name)
705        new_panel.window_name = self.slicer.__class__.__name__+ " " + \
706                                    str(self.data2D.name)
707        ## Store a reference of the new created panel
708        self.panel_slicer = new_panel
709        ## save the window_caption of the new panel in the current slicer
710        self.slicer.set_panel_name(name=new_panel.window_caption)
711        ## post slicer panel to guiframe to display it
712        from sans.guiframe.events import SlicerPanelEvent
713        wx.PostEvent(self.parent, SlicerPanelEvent(panel=self.panel_slicer,
714                                                    main_panel=self))
715
716    def onBoxavgX(self,event):
717        """
718        Perform 2D data averaging on Qx
719        Create a new slicer .
720       
721        :param event: wx.menu event
722        """
723        from boxSlicer import BoxInteractorX
724        self.onClearSlicer(event)
725        wx.PostEvent(self, InternalEvent(slicer=BoxInteractorX))
726       
727    def onBoxavgY(self,event):
728        """
729        Perform 2D data averaging on Qy
730        Create a new slicer .
731       
732        :param event: wx.menu event
733       
734        """
735        from boxSlicer import BoxInteractorY
736        self.onClearSlicer(event)
737        wx.PostEvent(self, InternalEvent(slicer=BoxInteractorY))
738       
739    def onClearSlicer(self, event):
740        """
741        Clear the slicer on the plot
742        """
743        if not self.slicer == None:
744            self.slicer.clear()
745            self.subplot.figure.canvas.draw()
746            self.slicer = None
747            # Post slicer None event
748            event = self._getEmptySlicerEvent()
749            wx.PostEvent(self, event)
750           
751    def _onSave(self, evt):
752        """
753        Save a data set to a dat(text) file
754       
755        :param evt: Menu event
756       
757        """
758        id = str(evt.GetId())
759        if self.parent != None:
760            self._default_save_location = self.parent._default_save_location
761        default_name = self.plots[self.graph.selected_plottable].label
762        if default_name.count('.') > 0:
763            default_name = default_name.split('.')[0]
764        default_name += "_out"
765        if id in self.action_ids:         
766            path = None
767            self.parent.save_data2d(self.data2D, default_name)
768           
769    def _onDataShow(self, evt):
770        """
771        Show the data set in text
772       
773        :param evt: Menu event
774       
775        """
776        menu = evt.GetEventObject()
777        id = evt.GetId()
778        self.set_selected_from_menu(menu, id)
779        data = self.plots[self.graph.selected_plottable]
780        default_name = data.label
781        if default_name.count('.') > 0:
782            default_name = default_name.split('.')[0]
783        #default_name += "_out"
784        if self.parent != None:
785            self.parent.show_data2d(data, default_name)
786       
Note: See TracBrowser for help on using the repository browser.