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

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 b1e609c was c039589, checked in by Mathieu Doucet <doucetm@…>, 10 years ago

pylint fixes

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