source: sasview/sansguiframe/src/sans/guiframe/local_perspectives/plotting/Plotter2D.py @ 664c5a7

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 664c5a7 was 2a09236, checked in by Jae Cho <jhjcho@…>, 13 years ago

tick label works w/ 2D too.

  • Property mode set to 100644
File size: 28.1 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, "&Save as a File (DAT)" )
321        self.action_ids[str(id)] = plot
322        wx.EVT_MENU(self, id, self._onSave)
323
324        slicerpop.AppendSeparator()
325        if len(self.data2D.detector) == 1:       
326           
327            item_list = self.parent.get_context_menu(self)
328            if (not item_list == None) and (not len(item_list) == 0) and\
329                self.data2D.name.split(" ")[0] != 'Residuals': 
330                # The line above; Not for trunk
331                for item in item_list:
332                    try:
333                        id = wx.NewId()
334                        slicerpop.Append(id, item[0], item[1])
335                        wx.EVT_MENU(self, id, item[2])
336                    except:
337                        msg = "ModelPanel1D.onContextMenu: "
338                        msg += "bad menu item  %s"%sys.exc_value
339                        wx.PostEvent(self.parent, StatusEvent(status=msg))
340                        pass
341                slicerpop.AppendSeparator()
342           
343            id = wx.NewId()
344            slicerpop.Append(id, '&Perform Circular Average')
345            wx.EVT_MENU(self, id, self.onCircular) \
346            # For Masked Data
347            if not plot.mask.all():
348                id = wx.NewId()
349                slicerpop.Append(id, '&Masked Circular Average')
350                wx.EVT_MENU(self, id, self.onMaskedCircular) 
351            id = wx.NewId()
352            slicerpop.Append(id, '&Sector [Q View]')
353            wx.EVT_MENU(self, id, self.onSectorQ) 
354            id = wx.NewId()
355            slicerpop.Append(id, '&Annulus [Phi View ]')
356            wx.EVT_MENU(self, id, self.onSectorPhi) 
357            id = wx.NewId()
358            slicerpop.Append(id, '&Box Sum')
359            wx.EVT_MENU(self, id, self.onBoxSum) 
360            id = wx.NewId()
361            slicerpop.Append(id, '&Box Averaging in Qx')
362            wx.EVT_MENU(self, id, self.onBoxavgX) 
363            id = wx.NewId()
364            slicerpop.Append(id, '&Box Averaging in Qy')
365            wx.EVT_MENU(self, id, self.onBoxavgY) 
366            if self.slicer != None:
367                id = wx.NewId()
368                slicerpop.Append(id, '&Clear Slicer')
369                wx.EVT_MENU(self, id,  self.onClearSlicer) 
370                if self.slicer.__class__.__name__  != "BoxSum":
371                    id = wx.NewId()
372                    slicerpop.Append(id, '&Edit Slicer Parameters')
373                    wx.EVT_MENU(self, id, self._onEditSlicer) 
374            slicerpop.AppendSeparator() 
375           
376        id = wx.NewId()
377        slicerpop.Append(id, '&Edit Graph Label', 'Edit Graph Label')
378        wx.EVT_MENU(self, id, self.onEditLabels)
379        slicerpop.AppendSeparator()
380       
381        id = wx.NewId()
382        slicerpop.Append(id, '&Edit Y Axis Label')
383        wx.EVT_MENU(self, id, self._on_yaxis_label)     
384        id = wx.NewId()
385        slicerpop.Append(id, '&Edit X Axis Label')
386        wx.EVT_MENU(self, id, self._on_xaxis_label)
387        id = wx.NewId()
388        slicerpop.Append(id, '&Toggle Grid On/Off', 'Toggle Grid On/Off')
389        wx.EVT_MENU(self, id, self.onGridOnOff)
390        slicerpop.AppendSeparator()
391       
392        id = wx.NewId()
393        slicerpop.Append(id, '&2D Color Map')
394        wx.EVT_MENU(self, id, self._onEditDetector)
395        slicerpop.AppendSeparator()
396       
397        id = wx.NewId()
398        slicerpop.Append(id, '&Toggle Linear/Log Scale')
399        wx.EVT_MENU(self, id, self._onToggleScale) 
400       
401       
402        slicerpop.AppendSeparator()
403        id = wx.NewId()
404        slicerpop.Append(id, '&Window Title')
405        wx.EVT_MENU(self, id, self.onChangeCaption)
406       
407        try:
408            pos_evt = event.GetPosition()
409            pos = self.ScreenToClient(pos_evt)
410        except:
411            pos_x, pos_y = self.toolbar.GetPositionTuple()
412            pos = (pos_x, pos_y + 5)
413        self.PopupMenu(slicerpop, pos)
414       
415           
416    def onEditLabels(self, event):
417        """
418        Edit legend label
419        """
420        selected_plot = self.plots[self.graph.selected_plottable]
421        label = selected_plot.label
422        dial = TextDialog(None, -1, 'Change Label', label)
423        if dial.ShowModal() == wx.ID_OK:
424            try:
425                FONT = FontProperties()
426                newlabel = dial.getText()
427                font = FONT.copy()
428                font.set_size(dial.getSize())
429                font.set_family(dial.getFamily())
430                font.set_style(dial.getStyle())
431                font.set_weight(dial.getWeight())
432                colour = dial.getColor()
433                if len(newlabel) > 0:
434                    # update Label
435                    selected_plot.label = newlabel
436                    self.graph.title(newlabel)
437                    self.title_label = selected_plot.label
438                    self.title_font = font
439                    self.title_color = colour
440                    ## render the graph
441                    self.subplot.set_title(label=self.title_label,
442                                           fontproperties=self.title_font,
443                                           color=self.title_color)
444                    self._is_changed_legend_label = True
445                    self.subplot.figure.canvas.draw_idle() 
446            except:
447                if self.parent != None:
448                    from sans.guiframe.events import StatusEvent
449                    msg= "Add Text: Error. Check your property values..."
450                    wx.PostEvent(self.parent, StatusEvent(status = msg ))
451                else:
452                    raise
453        dial.Destroy()
454       
455        # Update Graph menu and help string
456        if self.title_label != None:     
457            pos = self.parent._window_menu.FindItem(self.window_caption)
458            helpString = 'Show/Hide Graph: '
459            helpString += (' ' + str(self.title_label) +';')
460            self.parent._window_menu.SetHelpString(pos, helpString)
461
462       
463    def _onEditDetector(self, event):
464        """
465        Allow to view and edits  detector parameters
466       
467        :param event: wx.menu event
468       
469        """
470        import detector_dialog
471        dialog = detector_dialog.DetectorDialog(self, -1,base=self.parent,
472                       reset_zmin_ctl =self.default_zmin_ctl,
473                       reset_zmax_ctl = self.default_zmax_ctl,cmap=self.cmap)
474        ## info of current detector and data2D
475        xnpts = len(self.data2D.x_bins)
476        ynpts = len(self.data2D.y_bins)
477        xmax = max(self.data2D.xmin, self.data2D.xmax)
478        ymax = max(self.data2D.ymin, self.data2D.ymax)
479        qmax = math.sqrt(math.pow(xmax, 2) + math.pow(ymax, 2))
480        beam = self.data2D.xmin
481        ## set dialog window content
482        dialog.setContent(xnpts=xnpts,ynpts=ynpts,qmax=qmax,
483                           beam=self.data2D.xmin,
484                           zmin = self.zmin_2D,
485                          zmax = self.zmax_2D)
486        if dialog.ShowModal() == wx.ID_OK:
487            evt = dialog.getContent()
488            self.zmin_2D = evt.zmin
489            self.zmax_2D = evt.zmax
490            self.cmap = evt.cmap
491        dialog.Destroy()
492        ## Redraw the current image
493        self.image(data=self.data2D.data,
494                   qx_data=self.data2D.qx_data,
495                   qy_data=self.data2D.qy_data,
496                   xmin= self.data2D.xmin,
497                   xmax= self.data2D.xmax,
498                   ymin= self.data2D.ymin,
499                   ymax= self.data2D.ymax,
500                   zmin= self.zmin_2D,
501                   zmax= self.zmax_2D,
502                   cmap= self.cmap,
503                   color=0, symbol=0, label=self.data2D.name)
504        self.subplot.figure.canvas.draw_idle()
505       
506    def freeze_axes(self):
507        """
508        """
509        self.axes_frozen = True
510       
511    def thaw_axes(self):
512        """
513        """
514        self.axes_frozen = False
515       
516    def onMouseMotion(self,event):
517        """
518        """
519        pass
520   
521    def onWheel(self, event):
522        """
523        """
524        pass 
525     
526    def update(self, draw=True):
527        """
528        Respond to changes in the model by recalculating the
529        profiles and resetting the widgets.
530        """
531        self.draw_plot()
532       
533    def _getEmptySlicerEvent(self):
534        """
535        create an empty slicervent
536        """
537        return SlicerEvent(type=None, params=None, obj_class=None)
538       
539    def _onEVT_INTERNAL(self, event):
540        """
541        Draw the slicer
542       
543        :param event: wx.lib.newevent (SlicerEvent) containing slicer
544            parameter
545           
546        """
547        self._setSlicer(event.slicer)
548           
549    def _setSlicer(self, slicer):
550        """
551        Clear the previous slicer and create a new one.Post an internal
552        event.
553       
554        :param slicer: slicer class to create
555       
556        """
557        ## Clear current slicer
558        if not self.slicer == None: 
559            self.slicer.clear()           
560        ## Create a new slicer   
561        self.slicer_z += 1
562        self.slicer = slicer(self, self.subplot, zorder=self.slicer_z)
563        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
564        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
565        ## Draw slicer
566        self.update()
567        self.slicer.update()
568        msg = "Plotter2D._setSlicer  %s"%self.slicer.__class__.__name__
569        wx.PostEvent(self.parent, StatusEvent(status=msg))
570        # Post slicer event
571        event = self._getEmptySlicerEvent()
572        event.type = self.slicer.__class__.__name__
573        event.obj_class = self.slicer.__class__
574        event.params = self.slicer.get_params()
575        wx.PostEvent(self, event)
576       
577    def onMaskedCircular(self, event):
578        """
579        perform circular averaging on Data2D with mask if it exists
580       
581        :param event: wx.menu event
582       
583        """
584        self.onCircular(event, True)
585       
586    def onCircular(self, event, ismask=False):
587        """
588        perform circular averaging on Data2D
589       
590        :param event: wx.menu event
591       
592        """
593        # Find the best number of bins
594        npt = math.sqrt(len(self.data2D.data[numpy.isfinite(self.data2D.data)]))
595        npt = math.floor(npt)
596        from sans.dataloader.manipulations import CircularAverage
597        ## compute the maximum radius of data2D
598        self.qmax = max(math.fabs(self.data2D.xmax), 
599                        math.fabs(self.data2D.xmin))
600        self.ymax = max(math.fabs(self.data2D.ymax),
601                        math.fabs(self.data2D.ymin))
602        self.radius = math.sqrt(math.pow(self.qmax, 2)+ math.pow(self.ymax, 2)) 
603        ##Compute beam width
604        bin_width = (self.qmax + self.qmax)/npt
605        ## Create data1D circular average of data2D
606        Circle = CircularAverage(r_min=0, r_max=self.radius, 
607                                 bin_width=bin_width)
608        circ = Circle(self.data2D, ismask=ismask)
609        from sans.guiframe.dataFitting import Data1D
610        if hasattr(circ, "dxl"):
611            dxl = circ.dxl
612        else:
613            dxl = None
614        if hasattr(circ, "dxw"):
615            dxw = circ.dxw
616        else:
617            dxw = None
618
619        new_plot = Data1D(x=circ.x, y=circ.y, dy=circ.dy, dx=circ.dx)
620        new_plot.dxl = dxl
621        new_plot.dxw = dxw
622        new_plot.name = "Circ avg " + self.data2D.name
623        new_plot.source = self.data2D.source
624        #new_plot.info = self.data2D.info
625        new_plot.interactive = True
626        new_plot.detector = self.data2D.detector
627       
628        ## If the data file does not tell us what the axes are, just assume...
629        new_plot.xaxis("\\rm{Q}", "A^{-1}")
630        if hasattr(self.data2D, "scale") and \
631                    self.data2D.scale == 'linear':
632            new_plot.ytransform = 'y'
633            new_plot.yaxis("\\rm{Residuals} ", "normalized")
634        else:
635            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
636
637        new_plot.group_id = "Circ avg " + self.data2D.name
638        new_plot.id = "Circ avg " + self.data2D.name
639        new_plot.is_data = True
640        self.parent.update_theory(data_id=self.data2D, \
641                                       theory=new_plot)
642        wx.PostEvent(self.parent, 
643                     NewPlotEvent(plot=new_plot, title=new_plot.name))
644       
645    def _onEditSlicer(self, event):
646        """
647        Is available only when a slicer is drawn.Create a dialog
648        window where the user can enter value to reset slicer
649        parameters.
650       
651        :param event: wx.menu event
652       
653        """
654        if self.slicer != None:
655            from SlicerParameters import SlicerParameterPanel
656            dialog = SlicerParameterPanel(self, -1, "Slicer Parameters")
657            dialog.set_slicer(self.slicer.__class__.__name__,
658                            self.slicer.get_params())
659            if dialog.ShowModal() == wx.ID_OK:
660                dialog.Destroy() 
661       
662    def onSectorQ(self, event):
663        """
664        Perform sector averaging on Q and draw sector slicer
665        """
666        from SectorSlicer import SectorInteractor
667        self.onClearSlicer(event)
668        wx.PostEvent(self, InternalEvent(slicer=SectorInteractor))
669       
670    def onSectorPhi(self, event):
671        """
672        Perform sector averaging on Phi and draw annulus slicer
673        """
674        from AnnulusSlicer import AnnulusInteractor
675        self.onClearSlicer(event)
676        wx.PostEvent(self, InternalEvent(slicer=AnnulusInteractor))
677       
678    def onBoxSum(self, event):
679        """
680        """
681        from boxSum import BoxSum
682        self.onClearSlicer(event)
683        self.slicer_z += 1
684        self.slicer =  BoxSum(self, self.subplot, zorder=self.slicer_z)
685        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
686        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
687        self.update()
688        self.slicer.update()
689        ## Value used to initially set the slicer panel
690        type = self.slicer.__class__.__name__
691        params = self.slicer.get_params()
692        ## Create a new panel to display results of summation of Data2D
693        from slicerpanel import SlicerPanel
694        new_panel = SlicerPanel(parent=self.parent, id=-1,
695                                    base=self, type=type,
696                                    params=params, style=wx.RAISED_BORDER)
697       
698        new_panel.window_caption = self.slicer.__class__.__name__ + " " + \
699                                    str(self.data2D.name)
700        new_panel.window_name = self.slicer.__class__.__name__+ " " + \
701                                    str(self.data2D.name)
702        ## Store a reference of the new created panel
703        self.panel_slicer = new_panel
704        ## save the window_caption of the new panel in the current slicer
705        self.slicer.set_panel_name(name=new_panel.window_caption)
706        ## post slicer panel to guiframe to display it
707        from sans.guiframe.events import SlicerPanelEvent
708        wx.PostEvent(self.parent, SlicerPanelEvent(panel=self.panel_slicer,
709                                                    main_panel=self))
710
711    def onBoxavgX(self,event):
712        """
713        Perform 2D data averaging on Qx
714        Create a new slicer .
715       
716        :param event: wx.menu event
717        """
718        from boxSlicer import BoxInteractorX
719        self.onClearSlicer(event)
720        wx.PostEvent(self, InternalEvent(slicer=BoxInteractorX))
721       
722    def onBoxavgY(self,event):
723        """
724        Perform 2D data averaging on Qy
725        Create a new slicer .
726       
727        :param event: wx.menu event
728       
729        """
730        from boxSlicer import BoxInteractorY
731        self.onClearSlicer(event)
732        wx.PostEvent(self, InternalEvent(slicer=BoxInteractorY))
733       
734    def onClearSlicer(self, event):
735        """
736        Clear the slicer on the plot
737        """
738        if not self.slicer == None:
739            self.slicer.clear()
740            self.subplot.figure.canvas.draw()
741            self.slicer = None
742            # Post slicer None event
743            event = self._getEmptySlicerEvent()
744            wx.PostEvent(self, event)
745           
746    def _onSave(self, evt):
747        """
748        Save a data set to a dat(text) file
749       
750        :param evt: Menu event
751       
752        """
753        id = str(evt.GetId())
754        if self.parent != None:
755            self._default_save_location = self.parent._default_save_location
756        default_name = self.plots[self.graph.selected_plottable].label
757        if default_name.count('.') > 0:
758            default_name = default_name.split('.')[0]
759        default_name += "_out"
760        if id in self.action_ids:         
761            path = None
762            self.parent.save_data2d(self.data2D, default_name)
763       
Note: See TracBrowser for help on using the repository browser.