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

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 296f290 was 79492222, checked in by krzywon, 10 years ago

Changed the file and folder names to remove all SANS references.

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