source: sasview/sansguiframe/src/sans/guiframe/local_perspectives/plotting/Plotter2D.py @ 0899c82

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 0899c82 was 0899c82, checked in by Jae Cho <jhjcho@…>, 12 years ago

Added copy/paste on grid cells

  • Property mode set to 100644
File size: 30.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 danse.common.plottools.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
35from graphAppearance import graphAppearance
36(InternalEvent, EVT_INTERNAL) = wx.lib.newevent.NewEvent()
37
38DEFAULT_QMAX = 0.05
39DEFAULT_QSTEP = 0.001
40DEFAULT_BEAM = 0.005
41BIN_WIDTH = 1.0
42
43
44def find_key(dic, val):
45    """return the key of dictionary dic given the value"""
46    return [k for k, v in dic.iteritems() if v == val][0]
47
48
49class NavigationToolBar2D(NavigationToolBar):
50    """
51    """
52    def __init__(self, canvas, parent=None):
53        NavigationToolBar.__init__(self, canvas=canvas, parent=parent)
54       
55    def delete_option(self):
56        """
57        remove default toolbar item
58        """
59        #delete reset button
60        self.DeleteToolByPos(0) 
61        #delete dragging
62        self.DeleteToolByPos(2) 
63        #delete unwanted button that configures subplot parameters
64        self.DeleteToolByPos(4)
65       
66    def add_option(self):
67        """
68        add item to the toolbar
69        """
70        #add button
71        id_context = wx.NewId()
72        context_tip = 'Graph Menu'
73        context =  wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR)
74        self.InsertSimpleTool(0, id_context, context, 
75                                   context_tip, context_tip)
76        wx.EVT_TOOL(self, id_context,  self.parent.onToolContextMenu)
77        self.InsertSeparator(1)
78        #add print button
79        id_print = wx.NewId()
80        print_bmp =  wx.ArtProvider.GetBitmap(wx.ART_PRINT, wx.ART_TOOLBAR)
81        self.AddSimpleTool(id_print, print_bmp,
82                           'Print', 'Activate printing')
83        wx.EVT_TOOL(self, id_print, self.on_print)
84       
85       
86class ModelPanel2D(ModelPanel1D):
87    """
88    Plot panel for use with the GUI manager
89    """
90   
91    ## Internal name for the AUI manager
92    window_name = "plotpanel"
93    ## Title to appear on top of the window
94    window_caption = "Plot Panel"
95    ## Flag to tell the GUI manager that this panel is not
96    #  tied to any perspective
97    ALWAYS_ON = True
98    ## Group ID
99    group_id = None
100   
101   
102    def __init__(self, parent, id=-1, data2d=None, color = None,
103                 dpi=None, style=wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
104        """
105        Initialize the panel
106        """
107        ModelPanel1D.__init__(self, parent, id=id, style=style, **kwargs)
108       
109        ## Reference to the parent window
110        self.parent = parent
111        ## Dictionary containing Plottables
112        self.plots = {}
113        ## Save reference of the current plotted
114        self.data2D = data2d
115        ## Unique ID (from gui_manager)
116        self.uid = None
117        ## Action IDs for internal call-backs
118        self.action_ids = {}
119        ## Create Artist and bind it
120        self.connect = BindArtist(self.subplot.figure)
121        ## Beam stop
122        self.beamstop_radius = DEFAULT_BEAM
123        ## to set the order of lines drawn first.
124        self.slicer_z = 5
125        ## Reference to the current slicer
126        self.slicer = None
127        ## event to send slicer info
128        self.Bind(EVT_INTERNAL, self._onEVT_INTERNAL)
129       
130        self.axes_frozen = False
131        ## panel that contains result from slicer motion (ex: Boxsum info)
132        self.panel_slicer = None
133        self.title_label = None
134        self.title_font = None
135        self.title_color = 'black'
136        ## Graph       
137        self.graph = Graph()
138        self.graph.xaxis("\\rm{Q}", 'A^{-1}')
139        self.graph.yaxis("\\rm{Intensity} ", "cm^{-1}")
140        self.graph.render(self)
141        ## store default value of zmin and zmax
142        self.default_zmin_ctl = self.zmin_2D
143        self.default_zmax_ctl = self.zmax_2D
144       
145    def onLeftDown(self, event): 
146        """
147        left button down and ready to drag
148       
149        """
150        # Check that the LEFT button was pressed
151        PlotPanel.onLeftDown(self, event)   
152        ax = event.inaxes
153        if ax != None:
154            # data coordinate position
155            pos_x = "%8.3g"% event.xdata
156            pos_y = "%8.3g"% event.ydata
157            position = "x: %s    y: %s" % (pos_x, pos_y)
158            wx.PostEvent(self.parent, StatusEvent(status=position))
159        self.plottable_selected(self.data2D.id)
160        self._manager.set_panel_on_focus(self)
161        wx.PostEvent(self.parent, PanelOnFocusEvent(panel=self))
162       
163    def add_toolbar(self):
164        """
165        add toolbar
166        """
167        self.enable_toolbar = True
168        self.toolbar = NavigationToolBar2D(parent=self, canvas=self.canvas)
169        self.toolbar.Realize()
170        # On Windows platform, default window size is incorrect, so set
171        # toolbar width to figure width.
172        tw, th = self.toolbar.GetSizeTuple()
173        fw, fh = self.canvas.GetSizeTuple()
174        self.toolbar.SetSize(wx.Size(fw, th))
175        self.sizer.Add(self.toolbar, 0, wx.LEFT|wx.EXPAND)
176        # update the axes menu on the toolbar
177        self.toolbar.update()
178         
179    def plot_data(self, data):
180        """
181        Data is ready to be displayed
182       
183        :TODO: this name should be changed to something more appropriate
184             Don't forget that changing this name will mean changing code
185             in plotting.py
186         
187        :param event: data event
188        """
189        xlo = None
190        xhi = None
191        ylo = None 
192        yhi = None
193        if data.__class__.__name__ == 'Data1D':
194            return
195        ## Update self.data2d with the current plot
196        self.data2D = data
197        if data.id in self.plots.keys():
198            #replace
199            xlo, xhi = self.subplot.get_xlim()
200            ylo, yhi = self.subplot.get_ylim()
201            self.graph.replace(data)
202            self.plots[data.id] = data
203        else:
204            self.plots[data.id] = data
205            self.graph.add(self.plots[data.id]) 
206            # update qmax with the new xmax of data plotted
207            self.qmax = data.xmax 
208        self.slicer = None
209        # Check axis labels
210        #TODO: Should re-factor this
211        ## render the graph with its new content   
212        #data2D: put 'Pixel (Number)' for axis title and unit in case of having no detector info and none in _units
213        if len(data.detector) < 1: 
214            if len(data._xunit) < 1 and len(data._yunit) < 1:
215                data._xaxis = '\\rm{x}'
216                data._yaxis = '\\rm{y}'
217                data._xunit = 'pixel'
218                data._yunit = 'pixel'
219        # graph properties
220        self.graph.xaxis(data._xaxis, data._xunit)
221        self.graph.yaxis(data._yaxis, data._yunit)
222        if self._is_changed_legend_label:   
223                data.label = self.title_label
224        if data.label == None:
225            data.label = data.name   
226        if not self.title_font:
227            self.graph.title(data.label)
228            self.graph.render(self)
229            # Set the axis labels on subplot
230            self._set_axis_labels()
231            self.draw_plot()
232        else:
233            self.graph.render(self)
234            self.draw_plot()
235            self.subplot.set_title(label=data.label,
236                                   fontproperties=self.title_font,
237                                   color=self.title_color)
238            self.subplot.figure.canvas.draw_idle()   
239        # Update Graph menu and help string       
240        pos = self.parent._window_menu.FindItem(self.window_caption)
241        helpString = 'Show/Hide Graph: '
242        helpString += (' ' + str(data.label) +';')
243        self.parent._window_menu.SetHelpString(pos, helpString)
244        ## store default value of zmin and zmax
245        self.default_zmin_ctl = self.zmin_2D
246        self.default_zmax_ctl = self.zmax_2D
247        # Check if zoomed
248        toolbar_zoomed = self.toolbar.GetToolEnabled(self.toolbar._NTB2_BACK)
249        if not self.is_zoomed and not toolbar_zoomed:
250            return
251        # Recover the x,y limits
252        if (xlo and xhi and ylo and yhi) != None:
253            if (xlo > data.xmin and xhi < data.xmax and\
254                        ylo > data.ymin and yhi < data.ymax):
255                self.subplot.set_xlim((xlo, xhi))     
256                self.subplot.set_ylim((ylo, yhi)) 
257            else: 
258                self.toolbar.update()
259                self._is_zoomed = False
260
261    def _set_axis_labels(self):
262        """
263        Set axis labels
264        """
265        data = self.data2D
266        # control axis labels from the panel itself
267        yname, yunits = data.get_yaxis()
268        if self.yaxis_label != None:
269            yname = self.yaxis_label
270            yunits = self.yaxis_unit
271        else:
272            self.yaxis_label = yname
273            self.yaxis_unit = yunits
274        xname, xunits = data.get_xaxis()
275        if self.xaxis_label != None:
276            xname = self.xaxis_label
277            xunits = self.xaxis_unit
278        else:
279            self.xaxis_label = xname
280            self.xaxis_unit = xunits
281        self.xaxis(xname, xunits, self.xaxis_font, 
282                   self.xaxis_color, self.xaxis_tick)
283        self.yaxis(yname, yunits, self.yaxis_font, 
284                   self.yaxis_color, self.yaxis_tick)
285       
286    def onContextMenu(self, event):
287        """
288        2D plot context menu
289       
290        :param event: wx context event
291       
292        """
293        slicerpop = PanelMenu()
294        slicerpop.set_plots(self.plots)
295        slicerpop.set_graph(self.graph)
296             
297        id = wx.NewId()
298        slicerpop.Append(id, '&Save Image')
299        wx.EVT_MENU(self, id, self.onSaveImage)
300       
301        id = wx.NewId()
302        slicerpop.Append(id,'&Print Image', 'Print image')
303        wx.EVT_MENU(self, id, self.onPrint)
304       
305        id = wx.NewId()
306        slicerpop.Append(id,'&Print Preview', 'Print preview')
307        wx.EVT_MENU(self, id, self.onPrinterPreview)
308
309        id = wx.NewId()
310        slicerpop.Append(id, '&Copy to Clipboard', 'Copy to the clipboard')
311        wx.EVT_MENU(self, id, self.OnCopyFigureMenu)
312        slicerpop.AppendSeparator()
313        # saving data
314        plot = self.data2D
315        id = wx.NewId()
316        name = plot.name
317        slicerpop.Append(id, "&Data Info" )
318        wx.EVT_MENU(self, id, self._onDataShow)
319
320        id = wx.NewId()
321        name = plot.name
322        slicerpop.Append(id, "&Save as a File (DAT)" )
323        self.action_ids[str(id)] = plot
324        wx.EVT_MENU(self, id, self._onSave)
325
326        slicerpop.AppendSeparator()
327        if len(self.data2D.detector) == 1:       
328           
329            item_list = self.parent.get_current_context_menu(self)
330            if (not item_list == None) and (not len(item_list) == 0) and\
331                self.data2D.name.split(" ")[0] != 'Residuals': 
332                # The line above; Not for trunk
333                for item in item_list:
334                    try:
335                        id = wx.NewId()
336                        slicerpop.Append(id, item[0], item[1])
337                        wx.EVT_MENU(self, id, item[2])
338                    except:
339                        msg = "ModelPanel1D.onContextMenu: "
340                        msg += "bad menu item  %s"%sys.exc_value
341                        wx.PostEvent(self.parent, StatusEvent(status=msg))
342                        pass
343                slicerpop.AppendSeparator()
344           
345            id = wx.NewId()
346            slicerpop.Append(id, '&Perform Circular Average')
347            wx.EVT_MENU(self, id, self.onCircular) \
348            # For Masked Data
349            if not plot.mask.all():
350                id = wx.NewId()
351                slicerpop.Append(id, '&Masked Circular Average')
352                wx.EVT_MENU(self, id, self.onMaskedCircular) 
353            id = wx.NewId()
354            slicerpop.Append(id, '&Sector [Q View]')
355            wx.EVT_MENU(self, id, self.onSectorQ) 
356            id = wx.NewId()
357            slicerpop.Append(id, '&Annulus [Phi View ]')
358            wx.EVT_MENU(self, id, self.onSectorPhi) 
359            id = wx.NewId()
360            slicerpop.Append(id, '&Box Sum')
361            wx.EVT_MENU(self, id, self.onBoxSum) 
362            id = wx.NewId()
363            slicerpop.Append(id, '&Box Averaging in Qx')
364            wx.EVT_MENU(self, id, self.onBoxavgX) 
365            id = wx.NewId()
366            slicerpop.Append(id, '&Box Averaging in Qy')
367            wx.EVT_MENU(self, id, self.onBoxavgY) 
368            if self.slicer != None:
369                id = wx.NewId()
370                slicerpop.Append(id, '&Clear Slicer')
371                wx.EVT_MENU(self, id,  self.onClearSlicer) 
372                if self.slicer.__class__.__name__  != "BoxSum":
373                    id = wx.NewId()
374                    slicerpop.Append(id, '&Edit Slicer Parameters')
375                    wx.EVT_MENU(self, id, self._onEditSlicer) 
376            slicerpop.AppendSeparator() 
377           
378        id = wx.NewId()
379        slicerpop.Append(id, '&Edit Graph Label', 'Edit Graph Label')
380        wx.EVT_MENU(self, id, self.onEditLabels)
381        slicerpop.AppendSeparator()
382       
383        # ILL mod here
384
385        id = wx.NewId()
386        slicerpop.Append(id, '&Modify graph appearance','Modify graph appearance')
387        wx.EVT_MENU(self, id, self.modifyGraphAppearance)
388        slicerpop.AppendSeparator()
389
390
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 = "2daverage"  + 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           
764    def _onDataShow(self, evt):
765        """
766        Show the data set in text
767       
768        :param evt: Menu event
769       
770        """
771        menu = evt.GetEventObject()
772        id = evt.GetId()
773        self.set_selected_from_menu(menu, id)
774        data = self.plots[self.graph.selected_plottable]
775        default_name = data.label
776        if default_name.count('.') > 0:
777            default_name = default_name.split('.')[0]
778        #default_name += "_out"
779        if self.parent != None:
780            self.parent.show_data2d(data, default_name)
781       
782
783    def modifyGraphAppearance(self,e):
784        self.graphApp = graphAppearance(self,'Modify graph appearance',
785                                        legend=False)
786
787       
788
789        self.graphApp.setDefaults(self.grid_on,self.legend_on,
790                                  self.xaxis_label,self.yaxis_label,
791                                  self.xaxis_unit,self.yaxis_unit,
792                                  self.xaxis_font,self.yaxis_font,
793                                  find_key(self.get_loc_label(),self.legendLoc),
794                                  self.xcolor,self.ycolor)
795        self.graphApp.Bind(wx.EVT_CLOSE, self.on_graphApp_close)
796   
797
798    def on_graphApp_close(self,e):
799        # gets values from graph appearance dialog and sends them off
800        # to modify the plot
801
802        self.onGridOnOff(self.graphApp.get_togglegrid())
803
804       
805        self.xaxis_label = self.graphApp.get_xlab()
806        self.yaxis_label = self.graphApp.get_ylab()
807        self.xaxis_unit = self.graphApp.get_xunit()
808        self.yaxis_unit = self.graphApp.get_yunit()
809
810        self.xaxis(self.xaxis_label,self.xaxis_unit,
811                   self.graphApp.get_xfont(),self.graphApp.get_xcolor())
812        self.yaxis(self.yaxis_label,self.yaxis_unit,
813                   self.graphApp.get_yfont(),self.graphApp.get_ycolor())
814
815        self.graphApp.Destroy()
Note: See TracBrowser for help on using the repository browser.