source: sasview/src/sas/guiframe/local_perspectives/plotting/Plotter2D.py @ ae2a197

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 ae2a197 was 098f3d2, checked in by Doucet, Mathieu <doucetm@…>, 9 years ago

Remove print preview menu items. Fix 2D plotting from fit perspective.

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