source: sasview/guiframe/local_perspectives/plotting/masking.py @ 0b12abb5

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 0b12abb5 was d955bf19, checked in by Gervaise Alina <gervyh@…>, 15 years ago

working on documentation

  • Property mode set to 100644
File size: 21.3 KB
RevLine 
[c5874f2]1
[d955bf19]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#If you use DANSE applications to do scientific research that leads to
8#publication, we ask that you acknowledge the use of the software with the
9#following sentence:
10#
11#"This work benefited from DANSE software developed under NSF award DMR-0520547."
12#
13#copyright 2008, University of Tennessee
14################################################################################
[c5874f2]15
16
[a5ca7ef]17##Todo: cleaning up, improving the maskplotpanel initialization, and testing.
[c5874f2]18import wx
19import sys
20
21import copy,numpy
22from danse.common.plottools.PlotPanel import PlotPanel
[a5ca7ef]23from danse.common.plottools.plottables import Graph
[c5874f2]24from binder import BindArtist
25from sans.guiframe.dataFitting import Data2D
26from boxMask import BoxMask
27from sectorMask import SectorMask
28from sans.guicomm.events import SlicerEvent, StatusEvent
29(InternalEvent, EVT_INTERNAL)   = wx.lib.newevent.NewEvent()
30from pylab import  gca, gcf
31import math,pylab,re
32DEFAULT_CMAP= pylab.cm.jet
33
34_BOX_WIDTH = 76
35_STATICBOX_WIDTH = 400
36_SCALE = 1e-6
37
38#SLD panel size
39if sys.platform.count("win32")>0:
40    _STATICBOX_WIDTH = 380
41    PANEL_SIZE = 420
42    FONT_VARIANT = 0
43else:
44    _STATICBOX_WIDTH = 410
45    PANEL_SIZE = 450
46    FONT_VARIANT = 1
47   
48
49           
50class MaskPanel(wx.Dialog):
51    """
[d955bf19]52    Provides the Mask Editor GUI.
[c5874f2]53    """
54    ## Internal nickname for the window, used by the AUI manager
55    window_name = "Mask Editor"
56    ## Name to appear on the window title bar
57    window_caption = "Mask Editor"
58    ## Flag to tell the AUI manager to put this panel in the center pane
59    CENTER_PANE = True
60    def __init__(self, parent=None,base=None,data =None, id = -1, *args, **kwds):
61        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
[d955bf19]62        kwds["size"] = wx.Size(_STATICBOX_WIDTH*2,PANEL_SIZE) 
63        wx.Dialog.__init__(self, parent, id = id,  *args, **kwds)
[c5874f2]64        if data != None:
65           
66            #Font size
67            kwds =[]
68            self.SetWindowVariant(variant=FONT_VARIANT)
69
70            self.SetTitle("Mask Editor for "+ data.name)
71            self.parent = base
72            self.data = data
73            self.str = self.data.__str__()
74            ## mask for 2D
75            self.mask = data.mask
76            self.default_mask = copy.deepcopy(data.mask)
77            ## masked data from GUI
78            self.slicer_mask = None
79            self.slicer = None
80            self.slicer_z = 5
81
82            self.data.interactive = True
83            ## when 2 data have the same id override the 1 st plotted
84            self.name = self.data.name
85
86            # Panel for 2D plot
[a5ca7ef]87            self.plotpanel    = Maskplotpanel(self, -1, style=wx.TRANSPARENT_WINDOW)
[c5874f2]88            self.cmap = DEFAULT_CMAP
89            ## Create Artist and bind it
90            self.subplot = self.plotpanel.subplot
91            self.connect = BindArtist(self.subplot.figure)
92
93            self._setup_layout()
94            self.newplot=Data2D(image=self.data.data)
95            self.newplot.setValues(self.data)
96            self.plotpanel.add_image(self.newplot) 
97            self._update_mask(self.mask)
98            self.Centre()
99            self.Layout()
100            # bind evt_close to _draw in fitpage
101            self.Bind(wx.EVT_CLOSE, self._draw_model)
102           
103    def ShowMessage(self, msg=''):
104        """
[d955bf19]105        Show error message when mask covers whole data area
[c5874f2]106        """
107        mssg = 'Erase, redraw or clear the mask. \n\r'
108        mssg += 'The data range can not be completely masked... \n\r'
109        mssg += msg
110        wx.MessageBox(mssg, 'Error', wx.OK | 
111            wx.ICON_ERROR)
112   
113    def _setup_layout(self):
114        """
[d955bf19]115        Set up the layout
[c5874f2]116        """
117        shape = "Select a Shape for Masking:"
118       
119        #  panel
120        sizer = wx.GridBagSizer(10,10)
121
122        #---------inputs----------------
123        #inputbox = wx.StaticBox(self, -1, "Draw Mask")
124        shape_txt = wx.StaticText(self, -1, shape) 
125        sizer.Add(shape_txt, (1, 1), flag=wx.TOP | wx.LEFT | wx.BOTTOM, border=5)
126               
127        #innersector_x_txt = wx.StaticText(self, -1, 'Inner Sector')
128        self.innersector_rb = wx.RadioButton(self, -1,"Double Wings")
129        self.Bind(wx.EVT_RADIOBUTTON,self.onInnerSectorMask , id=self.innersector_rb.GetId())
130        sizer.Add(self.innersector_rb, (2, 1),flag=wx.RIGHT | wx.BOTTOM, border=5)
131       
132        #innersector_x_txt = wx.StaticText(self, -1, 'Inner Sector')
133        self.innercircle_rb = wx.RadioButton(self, -1,"Circular Disk")
134        self.Bind(wx.EVT_RADIOBUTTON,self.onInnerRingMask , id=self.innercircle_rb.GetId())
135        sizer.Add(self.innercircle_rb, (3, 1),flag=wx.RIGHT | wx.BOTTOM, border=5)
136       
137        self.innerbox_rb = wx.RadioButton(self, -1,"Rectangular Disk")
138        self.Bind(wx.EVT_RADIOBUTTON,self.onInnerBoxMask , id=self.innerbox_rb.GetId())
139        sizer.Add(self.innerbox_rb, (4, 1),flag=wx.RIGHT | wx.BOTTOM, border=5)
140
141        #outersector_y_txt = wx.StaticText(self, -1, 'Outer Sector')
142        self.outersector_rb = wx.RadioButton(self, -1,"Double Wing Window")
143        self.Bind(wx.EVT_RADIOBUTTON,self.onOuterSectorMask , id=self.outersector_rb.GetId())
144        sizer.Add(self.outersector_rb, (5, 1),flag=wx.RIGHT | wx.BOTTOM, border=5)
145       
146        #outersector_y_txt = wx.StaticText(self, -1, 'Outer Sector')
147        self.outercircle_rb = wx.RadioButton(self, -1,"Circular Window")
148        self.Bind(wx.EVT_RADIOBUTTON,self.onOuterRingMask , id=self.outercircle_rb.GetId())
149        sizer.Add(self.outercircle_rb, (6, 1),flag=wx.RIGHT | wx.BOTTOM, border=5)
150       
151        #outerbox_txt = wx.StaticText(self, -1, 'Outer Box')
152        self.outerbox_rb = wx.RadioButton(self, -1,"Rectangular Window")
153        self.Bind(wx.EVT_RADIOBUTTON,self.onOuterBoxMask , id=self.outerbox_rb.GetId())
154        sizer.Add(self.outerbox_rb, (7, 1),flag=wx.RIGHT | wx.BOTTOM, border=5)
155       
156        self.innercircle_rb.SetValue(False)
157        self.outercircle_rb.SetValue(False)       
158        self.innerbox_rb.SetValue(False)
159        self.outerbox_rb.SetValue(False)
160        self.innersector_rb.SetValue(False)
161        self.outersector_rb.SetValue(False)
162       
163        sizer.Add(self.plotpanel,(0, 2), (13, 13), wx.EXPAND | wx.LEFT| wx.RIGHT, 15)
164
165        #-----Buttons------------1
166        id = wx.NewId()
167       
168        button_add = wx.Button(self, id, "Add")
169        button_add.SetToolTipString("Add the mask drawn.")
170        button_add.Bind(wx.EVT_BUTTON, self.onAddMask, id = button_add.GetId()) 
171        sizer.Add(button_add, (13, 7))
172       
173        id = wx.NewId()
174        button_erase = wx.Button(self, id, "Erase")
175        button_erase.SetToolTipString("Erase the mask drawn.")
176        button_erase.Bind(wx.EVT_BUTTON, self.onEraseMask, id = button_erase.GetId()) 
177        sizer.Add(button_erase, (13, 8))
178       
179        id = wx.NewId()
180        button_reset = wx.Button(self, id, "Reset")
181        button_reset.SetToolTipString("Reset the mask.")
182        button_reset.Bind(wx.EVT_BUTTON, self.onResetMask, id = button_reset.GetId()) 
183        sizer.Add(button_reset, (13, 9), flag=wx.RIGHT | wx.BOTTOM, border=15)
184       
185        id = wx.NewId()
186        button_reset = wx.Button(self, id, "Clear")
187        button_reset.SetToolTipString("Clear all mask.")
188        button_reset.Bind(wx.EVT_BUTTON, self.onClearMask, id = button_reset.GetId()) 
189        sizer.Add(button_reset, (13, 10), flag=wx.RIGHT | wx.BOTTOM, border=15)
190
191        sizer.AddGrowableCol(3)
192        sizer.AddGrowableRow(2)
193        self.SetSizerAndFit(sizer)
194
195        self.Centre()
196        self.Show(True)
197
198
199    def onInnerBoxMask(self,event=None):
200        """
[d955bf19]201        Call Draw Box Slicer and get mask inside of the box
[c5874f2]202        """
203        #get ready for next evt
204        event.Skip()       
205        from boxMask import BoxMask
206        if event !=None:
207            self.onClearSlicer(event)
208                   
209        self.slicer_z += 1
210        self.slicer =  BoxMask(self, self.subplot, zorder=self.slicer_z, side=True)
211
212        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
213        self.subplot.set_xlim(self.data.xmin, self.data.xmax)
214        self.update()
215        self.slicer_mask = self.slicer.update()
216       
217   
218    def onOuterBoxMask(self,event=None):
219        """
[d955bf19]220        Call Draw Box Slicer and get mask outside of the box
[c5874f2]221        """
222        event.Skip()       
223        from boxMask import BoxMask
224        if event !=None:
225            self.onClearSlicer(event)
226                   
227        self.slicer_z += 1
228        self.slicer =  BoxMask(self, self.subplot, zorder=self.slicer_z, side=False)
229
230        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
231        self.subplot.set_xlim(self.data.xmin, self.data.xmax)
232        self.update()
233        self.slicer_mask = self.slicer.update()
234
235       
236    def onInnerSectorMask(self,event=None):
237        """
[d955bf19]238        Call Draw Sector Slicer and get mask inside of the sector
[c5874f2]239        """
240        event.Skip()
241        from sectorMask import SectorMask
242        if event !=None:
243            self.onClearSlicer(event)
244
245        self.slicer_z += 1
246        self.slicer =  SectorMask(self, self.subplot, zorder=self.slicer_z, side=True)
247        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
248        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
249
250        self.update()
251        self.slicer_mask = self.slicer.update() 
[a5ca7ef]252
[c5874f2]253       
254    def onOuterSectorMask(self,event=None):
255        """
[d955bf19]256        Call Draw Sector Slicer and get mask outside of the sector
[c5874f2]257        """
258        event.Skip()
259        from sectorMask import SectorMask
260        if event !=None:
261            self.onClearSlicer(event)
262
263        self.slicer_z += 1
264        self.slicer =  SectorMask(self, self.subplot, zorder=self.slicer_z, side=False)
265        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
266        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
267
268        self.update()     
269        self.slicer_mask = self.slicer.update()   
[a5ca7ef]270
[c5874f2]271       
272    def onInnerRingMask(self, event=None):
273        """
[d955bf19]274        Perform inner circular cut on Phi and draw circular slicer
[c5874f2]275        """
276        event.Skip()
277        from AnnulusSlicer import CircularMask
278        if event !=None:
279            self.onClearSlicer(event)
280       
281        self.slicer_z += 1
282        self.slicer = CircularMask(self,self.subplot, zorder=self.slicer_z, side=True)
283        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
284        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
[a5ca7ef]285
[c5874f2]286        self.update()
287        self.slicer_mask = self.slicer.update() 
[a5ca7ef]288
[c5874f2]289       
290    def onOuterRingMask(self, event=None):
291        """
[d955bf19]292        Perform outer circular cut on Phi and draw circular slicer
[c5874f2]293        """
294        event.Skip()
295        from AnnulusSlicer import CircularMask
296        if event !=None:
297            self.onClearSlicer(event)
298       
299        self.slicer_z += 1
300        self.slicer = CircularMask(self,self.subplot, zorder=self.slicer_z, side=False)   
301        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
302        self.subplot.set_xlim(self.data.xmin, self.data.xmax)
303        self.update()
304        self.slicer_mask = self.slicer.update()     
305       
306    def onAddMask(self, event):
307        """
[d955bf19]308        Add new mask to old mask
[c5874f2]309        """
310        if not self.slicer==None:
311            data = Data2D()
312            data = self.data
313            self.slicer_mask = self.slicer.update()
314            data.mask = self.data.mask & self.slicer_mask
315
316            self._check_display_mask(data.mask, event)
317           
318    def _check_display_mask(self, mask, event):
319        """
[d955bf19]320        check if the mask valid and update the plot
321       
322        :param mask: mask data
323       
[c5874f2]324        """
325        ## Redraw the current image
326        self._update_mask(mask)
327
328    def onEraseMask(self, event):
329        """
[d955bf19]330        Erase new mask from old mask
[c5874f2]331        """
332        if not self.slicer==None:
333            self.slicer_mask = self.slicer.update()
334            mask = self.data.mask
335            mask[self.slicer_mask==False] = True
336
337            self._check_display_mask(mask, event)
338           
339    def onResetMask(self, event):
340        """
[d955bf19]341        Reset mask to the original mask
342        """       
[c5874f2]343        self.slicer_z += 1
344        self.slicer =  BoxMask(self, self.subplot, zorder=self.slicer_z, side=True)
345        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
346        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
347
348        mask = copy.deepcopy(self.default_mask)
349        self.data.mask = mask
350
351        # update mask plot
352        self._check_display_mask(mask, event)
353       
354    def onClearMask(self, event):
355        """
[d955bf19]356        Clear mask
[c5874f2]357        """           
358        self.slicer_z += 1
359        self.slicer =  BoxMask(self, self.subplot, zorder=self.slicer_z, side=True)
360        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
361        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
362
363        #mask = copy.deepcopy(self.default_mask)
364        mask = numpy.ones(len(self.data.mask), dtype=bool)
365        self.data.mask = mask
[a5ca7ef]366
[c5874f2]367        # update mask plot
368        self._check_display_mask(mask, event)
369       
370    def onClearSlicer(self, event):
371        """
[d955bf19]372        Clear the slicer on the plot
[c5874f2]373        """
374        if not self.slicer==None:
375            self.slicer.clear()
376            self.subplot.figure.canvas.draw()
377            self.slicer = None
378
379    def _setSlicer(self):
380        """
[d955bf19]381        Clear the previous slicer and create a new one.Post an internal
382        event.
383       
384        :param slicer: slicer class to create
[c5874f2]385       
[d955bf19]386        """
[c5874f2]387        ## Clear current slicer
388        if not self.slicer == None: 
389            self.slicer.clear()           
390        ## Create a new slicer   
391        self.slicer_z += 1
392        self.slicer = slicer(self, self.subplot, zorder=self.slicer_z)
393        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
394        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
395        ## Draw slicer
396        self.update()
397        self.slicer.update()
398        wx.PostEvent(self.parent, StatusEvent(status=\
399                        "Plotter2D._setSlicer  %s"%self.slicer.__class__.__name__))
400        # Post slicer event
401        event = self._getEmptySlicerEvent()
402        event.type = self.slicer.__class__.__name__
403       
404        event.obj_class = self.slicer.__class__
405        event.params = self.slicer.get_params()
406        wx.PostEvent(self, event)
407   
408    def update(self, draw=True):
409        """
[d955bf19]410        Respond to changes in the model by recalculating the
411        profiles and resetting the widgets.
[c5874f2]412        """
413        self.plotpanel.draw()
414       
415    def _set_mask(self, mask):
416        """
[d955bf19]417        Set mask
[c5874f2]418        """
419        self.data.mask = mask
420       
421    def _update_mask(self,mask):
422        """
[d955bf19]423        Respond to changes in masking
[c5874f2]424        """ 
425        # the case of liitle numbers of True points
426        if (len(mask[mask])<10 and self.data !=None):
427            self.ShowMessage()
428            mask = copy.deepcopy(self.mask)
429            self.data.mask = mask
430        else:
431            self.mask = mask
432
433        # make temperary data to plot
434        temp_mask = numpy.zeros(len(mask))
435        temp_data = copy.deepcopy(self.data)
436        # temp_data default is None
437        # This method is to distinguish between masked point and data point = 0.
438        temp_mask = temp_mask/temp_mask
439        temp_mask[mask] = temp_data.data[mask]
440        # set temp_data value for self.mask==True, else still None
441        #temp_mask[mask] = temp_data[mask]
442        temp_data.data[mask==False] = temp_mask[mask==False]
443        self.plotpanel.clear()
444        if self.slicer != None:
445            self.slicer.clear()
446            self.slicer = None
447       
448        # Post slicer None event
449        event = self._getEmptySlicerEvent()
450        wx.PostEvent(self, event)
451       
452        #replot
[a5ca7ef]453        ##This method not alway updating the plot(?): use manual plot
454        #self.newplot=Data2D(image=temp_data.data)
455        #self.newplot.setValues(temp_data)
456        #self.plotpanel.add_image(self.newplot)
[ca6c17e8]457       
[9266c66]458       
[ca6c17e8]459        ##use this method
[e306b96e]460        #set zmax and zmin to plot: Fix it w/ data.
461        if self.plotpanel.scale == 'log':
462            zmax = math.log(max(self.data.data[self.data.data>0]))
[c1d2af4]463            zmin = math.log(min(self.data.data[self.data.data>0]))
[e306b96e]464        else:
465            zmax = max(self.data.data[self.data.data>0])
466            zmin = min(self.data.data[self.data.data>0])
[ca6c17e8]467        #plot   
[c5874f2]468        plot = self.plotpanel.image(data= temp_mask,
469                       qx_data=self.data.qx_data,
470                       qy_data=self.data.qy_data,
471                       xmin= self.data.xmin,
472                       xmax= self.data.xmax,
473                       ymin= self.data.ymin,
474                       ymax= self.data.ymax,
[e306b96e]475                       zmin= zmin,
476                       zmax= zmax,
[c5874f2]477                       cmap= self.cmap,
478                       color=0,symbol=0,label=self.data.name)
[54180f9]479        # axis labels
480        self.plotpanel.axes[0].set_xlabel('$\\rm{Q}_{x}(\\AA^{-1})$')
481        self.plotpanel.axes[0].set_ylabel('$\\rm{Q}_{y}(\\AA^{-1})$')
[c5874f2]482       
483        self.plotpanel.render()
484        self.plotpanel.subplot.figure.canvas.draw_idle()
485       
486       
487    def _getEmptySlicerEvent(self):
488        """
[d955bf19]489        create an empty slicervent
[c5874f2]490        """
491        self.innerbox_rb.SetValue(False)
492        self.outerbox_rb.SetValue(False)
493        self.innersector_rb.SetValue(False)
494        self.outersector_rb.SetValue(False)
495        self.innercircle_rb.SetValue(False)
496        self.outercircle_rb.SetValue(False)
497
498        return SlicerEvent(type=None,
499                           params=None,
500                           obj_class=None) 
501             
502    def _draw_model(self,event):
503        """
[d955bf19]504         on_close, update the model2d plot
[c5874f2]505        """
506        pass
507       
508    def freeze_axes(self):
[d955bf19]509        """
510        """
[c5874f2]511        self.plotpanel.axes_frozen = True
[d955bf19]512       
[c5874f2]513    def thaw_axes(self):
[d955bf19]514        """
515        """
516        self.plotpanel.axes_frozen = False       
517         
[c5874f2]518    def onMouseMotion(self,event):
[d955bf19]519        """
520        """
[c5874f2]521        pass
[d955bf19]522   
[c5874f2]523    def onWheel(self, event):
[d955bf19]524        """
525        """
[c5874f2]526        pass 
527           
[a5ca7ef]528class Maskplotpanel(PlotPanel):
[d955bf19]529    """
530    """
531    def __init__(self, parent, id = -1, color = None, dpi = None, **kwargs):
532        """
533        """
[c5874f2]534        PlotPanel.__init__(self, parent, id=id, color=color, dpi=dpi, **kwargs)
535       
536        # Keep track of the parent Frame
537        self.parent = parent
538        # Internal list of plottable names (because graph
539        # doesn't have a dictionary of handles for the plottables)
540        self.plots = {}
[a5ca7ef]541        self.graph = Graph()
[c5874f2]542       
543    def add_toolbar(self):
544        """
[d955bf19]545        Add toolbar
[c5874f2]546        """
547        # Not implemented
548        pass
549    def on_set_focus(self, event):
550        """
[d955bf19]551        send to the parenet the current panel on focus
[c5874f2]552        """
553        #change the panel background
554        #self.SetColor((170, 202, 255))
555        self.draw()   
556         
557    def add_image(self, plot):
[d955bf19]558        """
559        """
[c5874f2]560        self.plots[plot.name] = plot
[a5ca7ef]561        #init graph
562        self.gaph = Graph()
563        #add plot
[c5874f2]564        self.graph.add(plot)
[a5ca7ef]565        #add axes
[c5874f2]566        self.graph.xaxis('\\rm{Q}_{x} ', 'A^{-1}')
567        self.graph.yaxis('\\rm{Q}_{y} ', 'A^{-1}')
[a5ca7ef]568        #draw
[c5874f2]569        self.graph.render(self)
570        self.subplot.figure.canvas.draw_idle()
[a5ca7ef]571       
[c5874f2]572    def onMouseMotion(self, event):
573        """
[d955bf19]574        Disable dragging 2D image
[c5874f2]575        """
576        pass
577   
578    def onContextMenu(self, event):
579        """
[d955bf19]580        Default context menu for a plot panel
[c5874f2]581        """
582        # Slicer plot popup menu
[b40439d9]583        slicerpop = wx.Menu()
[c5874f2]584        #id = wx.NewId()
585        #slicerpop.Append(id,'&Save image', 'Save image as PNG')
586        #wx.EVT_MENU(self, id, self.onSaveImage)
587       
588        id = wx.NewId()
589        slicerpop.Append(id, '&Toggle Linear/Log scale')
590        wx.EVT_MENU(self, id, self._onToggleScale)
591               
592        pos = event.GetPosition()
593        pos = self.ScreenToClient(pos)
594        self.PopupMenu(slicerpop, pos)
595
[e306b96e]596class ViewerFrame(wx.Frame):
597    """
[d955bf19]598    Add comment
[e306b96e]599    """
600    def __init__(self, parent, id, title):
601        """
[d955bf19]602        comment
603        :param parent: parent panel/container
[e306b96e]604        """
605        # Initialize the Frame object
606        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(950,850))
607       
608        # Panel for 1D plot
609        self.plotpanel    = Maskplotpanel(self, -1, style=wx.RAISED_BORDER)
[c5874f2]610
[e306b96e]611class ViewApp(wx.App):
612    def OnInit(self):
613        frame = ViewerFrame(None, -1, 'testView')   
614        frame.Show(True)
615        self.SetTopWindow(frame)
616       
617        return True
618               
[c5874f2]619if __name__ == "__main__": 
620    app = ViewApp(0)
621    app.MainLoop()     
Note: See TracBrowser for help on using the repository browser.