source: sasview/invariantview/perspectives/invariant/invariant_panel.py @ 2fc9243

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 2fc9243 was dce0756, checked in by Gervaise Alina <gervyh@…>, 14 years ago

move txtcrtl

  • Property mode set to 100644
File size: 44.5 KB
RevLine 
[c128284]1"""
2    This module provide GUI for the neutron scattering length density calculator
3    @author: Gervaise B. Alina
4"""
5
6import wx
7import sys
8
[272d91e]9from sans.invariant import invariant
[c128284]10from sans.guiframe.utils import format_number, check_float
11from sans.guicomm.events import NewPlotEvent, StatusEvent
[d0cc0bbc]12from invariant_details import InvariantDetailsPanel, InvariantContainer
[518d35d]13from invariant_widgets import OutputTextCtrl, InvTextCtrl
[c128284]14# The minimum q-value to be used when extrapolating
15Q_MINIMUM  = 1e-5
16# The maximum q-value to be used when extrapolating
17Q_MAXIMUM  = 10
18# the maximum value to plot the theory data
19Q_MAXIMUM_PLOT = 2
20# the number of points to consider during fit
21NPTS = 10
22#Default value for background
23BACKGROUND = 0.0
24#default value for the scale
25SCALE = 1.0
[9ce7641c]26#default value of the contrast
27CONTRAST = 1.0
[d0cc0bbc]28#default value of the power used for power law
29POWER = 4.0
[c128284]30#Invariant panel size
31_BOX_WIDTH = 76
32
33if sys.platform.count("win32")>0:
34    _STATICBOX_WIDTH = 450
35    PANEL_WIDTH = 500
36    PANEL_HEIGHT = 700
37    FONT_VARIANT = 0
38else:
39    _STATICBOX_WIDTH = 480
40    PANEL_WIDTH = 530
41    PANEL_HEIGHT = 700
42    FONT_VARIANT = 1
[d0cc0bbc]43
44
[c128284]45class InvariantPanel(wx.ScrolledWindow):
46    """
47        Provides the Invariant GUI.
48    """
49    ## Internal nickname for the window, used by the AUI manager
50    window_name = "Invariant"
51    ## Name to appear on the window title bar
52    window_caption = "Invariant"
53    ## Flag to tell the AUI manager to put this panel in the center pane
54    CENTER_PANE = True
[272d91e]55    def __init__(self, parent, data=None, manager=None):
[c128284]56        wx.ScrolledWindow.__init__(self, parent, style= wx.FULL_REPAINT_ON_RESIZE )
57        #Font size
58        self.SetWindowVariant(variant=FONT_VARIANT)
59        #Object that receive status event
60        self.parent = parent
[272d91e]61        #plug-in using this panel
62        self._manager = manager
63        #Data uses for computation
64        self._data = data
[9ce7641c]65        #container of invariant value
66        self.inv_container = None
[c128284]67        #Draw the panel
68        self._do_layout()
[d0cc0bbc]69        self.reset_panel()
[a0a4486]70        if self.parent is not None:
71            msg = ""
72            wx.PostEvent(self.parent, StatusEvent(status= msg))
[9ce7641c]73       
[a0a4486]74    def err_check_on_data(self):
75        """
76            Check if data is valid for further computation
77        """
78        flag = False
79        #edit the panel
80        if self._data is not None:
81            if len(self._data.x[self._data.x==0]) > 0:
82                flag = True
83                msg = "Invariant: one of your q-values is zero. Delete that entry before proceeding"
84                wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop")) 
85        return flag
86   
[272d91e]87    def set_data(self, data):
[c128284]88        """
[272d91e]89            Set the data
[c128284]90        """
[272d91e]91        self._data = data
92        #edit the panel
93        if self._data is not None:
[a0a4486]94            self.err_check_on_data()
[272d91e]95            data_name = self._data.name
96            data_qmin = min (self._data.x)
97            data_qmax = max (self._data.x)
[9ce7641c]98            self.data_name_tcl.SetValue(str(data_name))
99            self.data_min_tcl.SetLabel(str(data_qmin))
100            self.data_max_tcl.SetLabel(str(data_qmax))
[277fad8]101            self.hint_msg_txt.SetLabel('')
[d0cc0bbc]102            self.reset_panel()
103            self.compute_invariant(event=None)
104           
105    def set_message(self):
106        """
107            Display warning message if available
108        """
109        if self.inv_container is not None:
110            if self.inv_container.existing_warning:
111                msg = "Warning! Computations on invariant require your "
112                msg += "attention.\n Please click on Details button."
113                self.hint_msg_txt.SetForegroundColour("red")
114            else:
115                msg = "For more information, click on Details button."
116                self.hint_msg_txt.SetForegroundColour("black")
117            self.hint_msg_txt.SetLabel(msg)
118        self.data_name_boxsizer.Layout()
119       
[c128284]120    def set_manager(self, manager):
121        """
[272d91e]122            set value for the manager
[c128284]123        """
[272d91e]124        self._manager = manager
[9ce7641c]125   
126    def get_background(self):
[c128284]127        """
[9ce7641c]128            @return the background textcrtl value as a float
[c128284]129        """
[9ce7641c]130        background = self.background_tcl.GetValue().lstrip().rstrip()
[c128284]131        if background == "":
[9ce7641c]132            raise ValueError, "Need a background"
133        if check_float(self.background_tcl):
134            return float(background)
135        else:
136            raise ValueError, "Receive invalid value for background : %s"%(background)
137   
138    def get_scale(self):
139        """
140            @return the scale textcrtl value as a float
141        """
142        scale = self.scale_tcl.GetValue().lstrip().rstrip()
[c128284]143        if scale == "":
[9ce7641c]144            raise ValueError, "Need a background"
145        if check_float(self.scale_tcl):
146            return float(scale)
147        else:
148            raise ValueError, "Receive invalid value for background : %s"%(scale)
149       
150    def get_contrast(self):
151        """
152            @return the contrast textcrtl value as a float
153        """
154        par_str = self.contrast_tcl.GetValue().strip()
155        contrast = None
156        if par_str !="" and check_float(self.contrast_tcl):
157            contrast = float(par_str)
158        return contrast
159   
160    def get_extrapolation_type(self, low_q, high_q):
161        """
162        """
163        extrapolation = None
164        if low_q  and not high_q:
165            extrapolation = "low"
166        elif not low_q  and high_q:
167            extrapolation = "high"
168        elif low_q and high_q:
169            extrapolation = "both"
170        return extrapolation
[272d91e]171           
[9ce7641c]172    def get_porod_const(self):
173        """
174            @return the porod constant textcrtl value as a float
175        """
176        par_str = self.porod_constant_tcl.GetValue().strip()
177        porod_const = None
178        if par_str !="" and check_float(self.porod_constant_tcl):
179            porod_const = float(par_str)
180        return porod_const
181   
182    def get_volume(self, inv, contrast, extrapolation):
183        """
184        """
185        if contrast is not None:
[c128284]186            try:
[9ce7641c]187                v, dv = inv.get_volume_fraction_with_error(contrast=contrast, 
188                                                           extrapolation=extrapolation)
189                self.volume_tcl.SetValue(format_number(v))
190                self.volume_err_tcl.SetValue(format_number(dv))
[c128284]191            except:
[9ce7641c]192                msg= "Error occurred computing volume fraction: %s"%sys.exc_value
[c128284]193                wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop"))
[9ce7641c]194               
195    def get_surface(self, inv, contrast, porod_const, extrapolation):
196        """
197        """
198        if contrast is not None and porod_const is not None:
[c128284]199            try:
[9ce7641c]200                s, ds = inv.get_surface_with_error(contrast=contrast,
201                                        porod_const=porod_const,
202                                        extrapolation=extrapolation)
203                self.surface_tcl.SetValue(format_number(s))
204                self.surface_err_tcl.SetValue(format_number(ds))
[c128284]205            except:
[4e74e13]206                msg = "Error occurred computing specific surface: %s"%sys.exc_value
[9ce7641c]207                wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop"))
[53b6b74]208               
[9ce7641c]209    def get_total_qstar(self, inv, extrapolation):
210        """
211        """
212        try:
213            qstar_total, qstar_total_err = inv.get_qstar_with_error(extrapolation)
214            self.invariant_total_tcl.SetValue(format_number(qstar_total))
[518d35d]215            self.invariant_total_err_tcl.SetValue(format_number(qstar_total_err))
[9ce7641c]216            self.inv_container.qstar_total = qstar_total
217            self.inv_container.qstar_total_err = qstar_total_err
[518d35d]218         
[9ce7641c]219        except:
220            msg= "Error occurred computing invariant using extrapolation: %s"%sys.exc_value
221            wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop")) 
222           
223    def get_low_qstar(self, inv, npts_low, low_q=False):
224        """
225        """
226        if low_q:
227            try: 
228                qstar_low, qstar_low_err = inv.get_qstar_low()
229                self.inv_container.qstar_low = qstar_low
230                self.inv_container.qstar_low_err = qstar_low_err
231                extrapolated_data = inv.get_extra_data_low(npts_in=npts_low) 
232                power_low = inv.get_extrapolation_power(range='low') 
[518d35d]233                if self.power_law_low.GetValue():
[d0cc0bbc]234                    self.power_low_tcl.SetValue(format_number(power_low))
[9ce7641c]235                self._manager.plot_theory(data=extrapolated_data,
236                                           name="Low-Q extrapolation")
237            except:
238                msg= "Error occurred computing low-Q invariant: %s"%sys.exc_value
239                wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop"))
[c128284]240        else:
[9ce7641c]241            self._manager.plot_theory(name="Low-Q extrapolation")
242           
243    def get_high_qstar(self, inv, high_q=False):
244        """
245        """
246        if high_q:
247            try: 
248                qstar_high, qstar_high_err = inv.get_qstar_high()
249                self.inv_container.qstar_high = qstar_high
250                self.inv_container.qstar_high_err = qstar_high_err
[518d35d]251                power_high = inv.get_extrapolation_power(range='high') 
[d0cc0bbc]252                self.power_high_tcl.SetValue(format_number(power_high))
[9ce7641c]253                high_out_data = inv.get_extra_data_high(q_end=Q_MAXIMUM_PLOT)
254                self._manager.plot_theory(data=high_out_data,
255                                           name="High-Q extrapolation")
256            except:
257                msg= "Error occurred computing high-Q invariant: %s"%sys.exc_value
258                wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop"))
259        else:
260            self._manager.plot_theory(name="High-Q extrapolation")
261           
262    def get_qstar(self, inv):
263        """
264        """
265        qstar, qstar_err = inv.get_qstar_with_error()
266        self.inv_container.qstar = qstar
267        self.inv_container.qstar_err = qstar_err
268             
269    def set_extrapolation_low(self, inv, low_q=False):
270        """
271            @return float value necessary to compute invariant a low q
272        """
273        #get funtion
274        if self.guinier.GetValue():
275            function_low = "guinier"
276        # get the function
[518d35d]277        power_low = None #2.0/3.0
[9ce7641c]278        if self.power_law_low.GetValue():
279            function_low = "power_law"
[518d35d]280            if self.fit_enable_low.GetValue():
[9ce7641c]281                #set value of power_low to none to allow fitting
282                power_low = None
283            else:
284                power_low = self.power_low_tcl.GetValue().lstrip().rstrip()
285                if check_float(self.power_low_tcl):
286                    power_low = float(power_low)
287                else:
288                    if low_q :
289                        #Raise error only when qstar at low q is requested
290                        msg = "Expect float for power at low q , got %s"%(power_low)
291                        raise ValueError, msg
[518d35d]292       
[9ce7641c]293        #Get the number of points to extrapolated
294        npts_low = self.npts_low_tcl.GetValue().lstrip().rstrip()   
295        if check_float(self.npts_low_tcl):
296            npts_low = float(npts_low)
297        else:
298            if low_q:
299                msg = "Expect float for number of points at low q , got %s"%(npts_low)
300                raise ValueError, msg
301        #Set the invariant calculator
302        inv.set_extrapolation(range="low", npts=npts_low,
303                                   function=function_low, power=power_low)   
304        return inv, npts_low 
305       
306    def set_extrapolation_high(self, inv, high_q=False):
307        """
308            @return float value necessary to compute invariant a high q
309        """
310        power_high = None
[277fad8]311        #if self.power_law_high.GetValue():
312        function_high = "power_law"
313        if self.fit_enable_high.GetValue():
314            #set value of power_high to none to allow fitting
315            power_high = None
316        else:
317            power_high = self.power_high_tcl.GetValue().lstrip().rstrip()
318            if check_float(self.power_high_tcl):
319                power_high = float(power_high)
[9ce7641c]320            else:
[277fad8]321                if high_q :
322                    #Raise error only when qstar at high q is requested
323                    msg = "Expect float for power at high q , got %s"%(power_high)
324                    raise ValueError, msg
[9ce7641c]325                         
326        npts_high = self.npts_high_tcl.GetValue().lstrip().rstrip()   
327        if check_float(self.npts_high_tcl):
328            npts_high = float(npts_high)
329        else:
330            if high_q:
331                msg = "Expect float for number of points at high q , got %s"%(npts_high)
332                raise ValueError, msg
333        inv.set_extrapolation(range="high", npts=npts_high,
334                                   function=function_high, power=power_high)
335        return inv, npts_high
336   
337    def display_details(self, event):
338        """
339            open another panel for more details on invariant calculation
340        """
[d3fac18]341        panel = InvariantDetailsPanel(parent=self, 
342                                           qstar_container=self.inv_container)
343        panel.ShowModal()
344        panel.Destroy()
[d0cc0bbc]345        self.button_calculate.SetFocus()
[9ce7641c]346       
[d0cc0bbc]347    def compute_invariant(self, event=None):
[9ce7641c]348        """
349            compute invariant
350        """
[437e639]351        msg= ""
352        wx.PostEvent(self.parent, StatusEvent(status= msg))
[a0a4486]353        if self._data is None or self.err_check_on_data():
[9ce7641c]354            return
[a0a4486]355   
[9ce7641c]356        #clear outputs textctrl
357        self._reset_output()
358        try:
359            background = self.get_background()
360            scale = self.get_scale()
361        except:
362            msg= "Invariant Error: %s"%(sys.exc_value)
363            wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop"))
364            return
365       
366        low_q = self.enable_low_cbox.GetValue()
367        high_q = self.enable_high_cbox.GetValue() 
368        #set invariant calculator
369        inv = invariant.InvariantCalculator(data=self._data,
370                                            background=background,
371                                            scale=scale)
[437e639]372        try:
373            inv, npts_low = self.set_extrapolation_low(inv=inv, low_q=low_q)
374            inv, npts_high = self.set_extrapolation_high(inv=inv, high_q=high_q)
375        except:
[518d35d]376            raise
377            #msg= "Error occurred computing invariant: %s"%sys.exc_value
378            #wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop"))
[437e639]379            return
[9ce7641c]380        #check the type of extrapolation
381        extrapolation = self.get_extrapolation_type(low_q=low_q, high_q=high_q)
[a0a4486]382       
[9ce7641c]383        #Compute invariant
384        try:
385            self.get_qstar(inv=inv)
386        except:
387            msg= "Error occurred computing invariant: %s"%sys.exc_value
[c128284]388            wx.PostEvent(self.parent, StatusEvent(status= msg, type="stop"))
389            return
[9ce7641c]390        #Compute qstar extrapolated to low q range
391        self.get_low_qstar(inv=inv, npts_low=npts_low, low_q=low_q)
392        #Compute qstar extrapolated to high q range
393        self.get_high_qstar(inv=inv, high_q=high_q)
394        #Compute qstar extrapolated to total q range and set value to txtcrtl
395        self.get_total_qstar(inv=inv, extrapolation=extrapolation)
396        # Parse additional parameters
397        porod_const = self.get_porod_const()       
398        contrast = self.get_contrast()
[f43827cc]399        try:
400            #Compute volume and set value to txtcrtl
401            self.get_volume(inv=inv, contrast=contrast, extrapolation=extrapolation)
402            #compute surface and set value to txtcrtl
403        except:
[4e74e13]404            msg = "Error occurred computing invariant: %s"%sys.exc_value
405            wx.PostEvent(self.parent, StatusEvent(status=msg))
[f43827cc]406        try:
407            self.get_surface(inv=inv, contrast=contrast, porod_const=porod_const, 
[9ce7641c]408                                    extrapolation=extrapolation)
[f43827cc]409        except:
[4e74e13]410            msg = "Error occurred computing invariant: %s"%sys.exc_value
[f43827cc]411            wx.PostEvent(self.parent, StatusEvent(status= msg))
[d0cc0bbc]412           
413        #compute percentage of each invariant
414        self.inv_container.compute_percentage()
415        #display a message
416        self.set_message()
[9ce7641c]417        #enable the button_ok for more details
[d0cc0bbc]418        self.button_details.Enable()
419        self.button_details.SetFocus()
[f338d3b]420   
421    def reset_panel(self):
422        """
423            set the panel at its initial state.
424        """
[d0cc0bbc]425        self.background_tcl.SetValue(str(BACKGROUND))
426        self.scale_tcl.SetValue(str(SCALE)) 
[4e74e13]427        self.contrast_tcl.SetValue(str(CONTRAST))
428        self.porod_constant_tcl.SetValue('') 
[d0cc0bbc]429        self.npts_low_tcl.SetValue(str(NPTS))
430        self.enable_low_cbox.SetValue(False)
431        self.fix_enable_low.SetValue(True)
432        self.power_low_tcl.SetValue(str(POWER))
433        self.guinier.SetValue(True)
434        self.power_low_tcl.Disable()
435        self.enable_high_cbox.SetValue(False)
436        self.fix_enable_high.SetValue(True)
437        self.power_high_tcl.SetValue(str(POWER))
438        self.npts_high_tcl.SetValue(str(NPTS))
439        self.button_details.Disable()
440        #Change the state of txtcrtl to enable/disable
441        self._enable_low_q_section()
442        #Change the state of txtcrtl to enable/disable
443        self._enable_high_q_section()
444        self._reset_output()
445        self.button_calculate.SetFocus()
[9ce7641c]446       
[c128284]447    def _reset_output(self):
448        """
449            clear outputs textcrtl
450        """
[9ce7641c]451        self.invariant_total_tcl.Clear()
452        self.invariant_total_err_tcl.Clear()
453        self.volume_tcl.Clear()
454        self.volume_err_tcl.Clear()
455        self.surface_tcl.Clear()
456        self.surface_err_tcl.Clear()
[a0a4486]457        #prepare a new container to put result of invariant
458        self.inv_container = InvariantContainer()
[9ce7641c]459       
460    def _define_structure(self):
[c128284]461        """
[9ce7641c]462            Define main sizers needed for this panel
[c128284]463        """
[d5f0dcb9]464        ## Box sizers must be defined first before defining buttons/textctrls (MAC).
[9ce7641c]465        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
466        #Sizer related to outputs
467        outputs_box = wx.StaticBox(self, -1, "Outputs")
468        self.outputs_sizer = wx.StaticBoxSizer(outputs_box, wx.VERTICAL)
469        self.outputs_sizer.SetMinSize((PANEL_WIDTH,-1))
470        #Sizer related to data
471        data_name_box = wx.StaticBox(self, -1, "I(q) Data Source")
472        self.data_name_boxsizer = wx.StaticBoxSizer(data_name_box, wx.VERTICAL)
473        self.data_name_boxsizer.SetMinSize((PANEL_WIDTH,-1))
474        self.hint_msg_sizer = wx.BoxSizer(wx.HORIZONTAL)
475        self.data_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
476        self.data_range_sizer = wx.BoxSizer(wx.HORIZONTAL)
[d0cc0bbc]477        #Sizer related to background and scale
478        self.bkg_scale_sizer = wx.BoxSizer(wx.HORIZONTAL) 
479        #Sizer related to contrast and porod constant
480        self.contrast_porod_sizer = wx.BoxSizer(wx.HORIZONTAL) 
481        #Sizer related to inputs
482        inputs_box = wx.StaticBox(self, -1, "Customized Inputs")
483        self.inputs_sizer = wx.StaticBoxSizer(inputs_box, wx.VERTICAL)
484        #Sizer related to extrapolation
[d5f0dcb9]485        extrapolation_box = wx.StaticBox(self, -1, "Extrapolation")
[9ce7641c]486        self.extrapolation_sizer = wx.StaticBoxSizer(extrapolation_box,
487                                                        wx.VERTICAL)
488        self.extrapolation_sizer.SetMinSize((PANEL_WIDTH,-1))
489        self.extrapolation_range_sizer = wx.BoxSizer(wx.HORIZONTAL)
490        self.extrapolation_low_high_sizer = wx.BoxSizer(wx.HORIZONTAL)
491        #Sizer related to extrapolation at low q range
[d5f0dcb9]492        low_q_box = wx.StaticBox(self, -1, "Low Q")
[9ce7641c]493        self.low_extrapolation_sizer = wx.StaticBoxSizer(low_q_box, wx.VERTICAL)
494        self.low_q_sizer = wx.GridBagSizer(5,5)
495        #Sizer related to extrapolation at low q range
496        high_q_box = wx.StaticBox(self, -1, "High Q")
497        self.high_extrapolation_sizer = wx.StaticBoxSizer(high_q_box, wx.VERTICAL)
498        self.high_q_sizer = wx.GridBagSizer(5,5)
499        #sizer to define outputs
500        self.volume_surface_sizer = wx.GridBagSizer(5,5)
501        #Sizer related to invariant output
[277fad8]502        self.invariant_sizer = wx.GridBagSizer(5, 5)
[9ce7641c]503        #Sizer related to button
504        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
[c128284]505       
[9ce7641c]506    def _layout_data_name(self):
507        """
508            Draw widgets related to data's name
509        """
510        #Sizer hint
[6848131]511        hint_msg = "First open data file from 'File' menu.  Then Highlight and right click on the data plot. \n"
512        hint_msg += "Finally, select 'Compute Invariant'. \n"
[277fad8]513        self.hint_msg_txt = wx.StaticText(self, -1, hint_msg) 
514        self.hint_msg_txt.SetForegroundColour("red")
[6848131]515        msg = "Highlight = mouse the mouse's cursor on the data until the plot's color changes to yellow"
516        self.hint_msg_txt.SetToolTipString(msg)
[277fad8]517        self.hint_msg_sizer.Add(self.hint_msg_txt)
[9ce7641c]518        #Data name [string]
519        data_name_txt = wx.StaticText(self, -1, 'Data : ') 
520       
[518d35d]521        self.data_name_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH*5, 20), style=0) 
[9ce7641c]522        self.data_name_tcl.SetToolTipString("Data's name.")
523        self.data_name_sizer.AddMany([(data_name_txt, 0, wx.LEFT|wx.RIGHT, 10),
524                                       (self.data_name_tcl, 0, wx.EXPAND)])
525        #Data range [string]
526        data_range_txt = wx.StaticText(self, -1, 'Total Q Range (1/A): ') 
527        data_min_txt = wx.StaticText(self, -1, 'Min : ') 
[518d35d]528        self.data_min_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)
[9ce7641c]529        self.data_min_tcl.SetToolTipString("The minimum value of q range.")
530        data_max_txt = wx.StaticText(self, -1, 'Max : ') 
[518d35d]531        self.data_max_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0) 
[9ce7641c]532        self.data_max_tcl.SetToolTipString("The maximum value of q range.")
533        self.data_range_sizer.AddMany([(data_range_txt, 0, wx.RIGHT, 10),
534                                       (data_min_txt, 0, wx.RIGHT, 10),
535                                       (self.data_min_tcl, 0, wx.RIGHT, 10),
536                                       (data_max_txt, 0, wx.RIGHT, 10),
537                                       (self.data_max_tcl, 0, wx.RIGHT, 10)])
538        self.data_name_boxsizer.AddMany([(self.hint_msg_sizer, 0 , wx.ALL, 10),
539                                         (self.data_name_sizer, 0 , wx.RIGHT, 10),
540                                         (self.data_range_sizer, 0 , wx.ALL, 10)])
541   
[d0cc0bbc]542    def _layout_bkg_scale(self):
[9ce7641c]543        """
[d0cc0bbc]544            Draw widgets related to background and scale
[9ce7641c]545        """
546        background_txt = wx.StaticText(self, -1, 'Background : ') 
[518d35d]547        self.background_tcl = InvTextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0) 
548        background_hint_txt = "background"
549        self.background_tcl.SetToolTipString(background_hint_txt)
550        background_unit_txt = wx.StaticText(self, -1, '[1/cm]') 
[9ce7641c]551        scale_txt = wx.StaticText(self, -1, 'Scale : ') 
[518d35d]552        self.scale_tcl = InvTextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)
553        scale_hint_txt = "Scale"
554        self.scale_tcl.SetToolTipString(scale_hint_txt)
[d0cc0bbc]555        self.bkg_scale_sizer.AddMany([(background_txt, 0, wx.LEFT, 10),
556                                       (self.background_tcl, 0, wx.LEFT, 5),
557                                       (background_unit_txt, 0, wx.LEFT, 10),
558                                       (scale_txt, 0, wx.LEFT, 70),
559                                       (self.scale_tcl, 0, wx.LEFT, 40)])
560 
561    def _layout_contrast_porod(self):
[9ce7641c]562        """
[d0cc0bbc]563            Draw widgets related to porod constant and contrast
[9ce7641c]564        """
565        contrast_txt = wx.StaticText(self, -1, 'Contrast : ') 
[518d35d]566        self.contrast_tcl = InvTextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)
567        contrast_hint_txt = "Contrast"
568        self.contrast_tcl.SetToolTipString(contrast_hint_txt)
569        contrast_unit_txt = wx.StaticText(self, -1, '[1/A^(2)]') 
[9ce7641c]570        porod_const_txt = wx.StaticText(self, -1, 'Porod Constant:') 
[518d35d]571        self.porod_constant_tcl = InvTextCtrl(self, -1, 
[9ce7641c]572                                              size=(_BOX_WIDTH, 20), style=0) 
[518d35d]573        porod_const_hint_txt = "Porod Constant"
574        self.porod_constant_tcl.SetToolTipString(porod_const_hint_txt)
[9ce7641c]575        optional_txt = wx.StaticText(self, -1, '(Optional)') 
[d0cc0bbc]576        self.contrast_porod_sizer.AddMany([(contrast_txt, 0, wx.LEFT, 10),
577                                           (self.contrast_tcl, 0, wx.LEFT, 20),
578                                           (contrast_unit_txt, 0, wx.LEFT, 10),
579                                           (porod_const_txt, 0, wx.LEFT, 50),
[9ce7641c]580                                       (self.porod_constant_tcl, 0, wx.LEFT, 0),
581                                       (optional_txt, 0, wx.LEFT, 10)])
582       
[518d35d]583    def _enable_fit_power_law_low(self, event=None):
584        """
585            Enable and disable the power value editing
586        """
587        if self.fix_enable_low.IsEnabled():
588            if self.fix_enable_low.GetValue():
589                self.power_low_tcl.Enable()
590            else:
591                self.power_low_tcl.Disable()
592           
593    def _enable_low_q_section(self, event=None):
594        """
595            Disable or enable some button if the user enable low q extrapolation
596        """
597        if self.enable_low_cbox.GetValue():
598            self.npts_low_tcl.Enable()
599            self.fix_enable_low.Enable()
600            self.fit_enable_low.Enable()
601            self.guinier.Enable()
602            self.power_law_low.Enable()
603
604        else:
605            self.npts_low_tcl.Disable()
606            self.fix_enable_low.Disable()
607            self.fit_enable_low.Disable()
608            self.guinier.Disable()
609            self.power_law_low.Disable()
610        self._enable_power_law_low()
611        self._enable_fit_power_law_low()
[d0cc0bbc]612        self.button_calculate.SetFocus()
[518d35d]613   
614    def _enable_power_law_low(self, event=None):
615        """
616            Enable editing power law section at low q range
617        """
618        if self.guinier.GetValue():
619            self.fix_enable_low.Disable()
620            self.fit_enable_low.Disable()
621            self.power_low_tcl.Disable()
622        else:
623            self.fix_enable_low.Enable()
624            self.fit_enable_low.Enable()
625            self.power_low_tcl.Enable()
626        self._enable_fit_power_law_low()
627           
[9ce7641c]628    def _layout_extrapolation_low(self):
629        """
630            Draw widgets related to extrapolation at low q range
631        """
[437e639]632        self.enable_low_cbox = wx.CheckBox(self, -1, "Enable Extrapolate Low Q")
[518d35d]633        wx.EVT_CHECKBOX(self, self.enable_low_cbox.GetId(),
634                                         self._enable_low_q_section)
635        self.fix_enable_low = wx.RadioButton(self, -1, 'Fix',
636                                         (10, 10),style=wx.RB_GROUP)
637        self.fit_enable_low = wx.RadioButton(self, -1, 'Fit', (10, 10))
638        self.Bind(wx.EVT_RADIOBUTTON, self._enable_fit_power_law_low,
639                                     id=self.fix_enable_low.GetId())
640        self.Bind(wx.EVT_RADIOBUTTON, self._enable_fit_power_law_low, 
641                                        id=self.fit_enable_low.GetId())
[c128284]642        self.guinier = wx.RadioButton(self, -1, 'Guinier',
643                                         (10, 10),style=wx.RB_GROUP)
[9ce7641c]644        self.power_law_low = wx.RadioButton(self, -1, 'Power Law', (10, 10))
[518d35d]645        self.Bind(wx.EVT_RADIOBUTTON, self._enable_power_law_low,
646                                     id=self.guinier.GetId())
647        self.Bind(wx.EVT_RADIOBUTTON, self._enable_power_law_low, 
648                                        id=self.power_law_low.GetId())
649       
[c128284]650        npts_low_txt = wx.StaticText(self, -1, 'Npts')
[518d35d]651        self.npts_low_tcl = InvTextCtrl(self, -1, size=(_BOX_WIDTH*2/3, -1))
[2661d8b]652        msg_hint = "Number of Q points to consider"
653        msg_hint +="while extrapolating the low-Q region"
[9ce7641c]654        self.npts_low_tcl.SetToolTipString(msg_hint)
655        power_txt = wx.StaticText(self, -1, 'Power')
[518d35d]656        self.power_low_tcl = InvTextCtrl(self, -1, size=(_BOX_WIDTH*2/3, -1))
[d0cc0bbc]657       
[9ce7641c]658        power_hint_txt = "Exponent to apply to the Power_law function."
659        self.power_low_tcl.SetToolTipString(power_hint_txt)
[c128284]660        iy = 0
661        ix = 0
[518d35d]662        self.low_q_sizer.Add(self.enable_low_cbox,(iy, ix),(1,5),
663                            wx.TOP|wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
664        iy += 1
665        ix = 0
666        self.low_q_sizer.Add(npts_low_txt,(iy, ix),(1,1),
667                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
668        ix += 1
669        self.low_q_sizer.Add(self.npts_low_tcl, (iy, ix), (1,1),
670                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
671        iy += 1
672        ix = 0
[9ce7641c]673        self.low_q_sizer.Add(self.guinier,(iy, ix),(1,2),
[c128284]674                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
675        iy += 1
676        ix = 0
[9ce7641c]677        self.low_q_sizer.Add(self.power_law_low,(iy, ix),(1,2),
[2661d8b]678                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[518d35d]679       
[2661d8b]680        # Parameter controls for power law
681        ix = 1
682        iy += 1
[518d35d]683        self.low_q_sizer.Add(self.fix_enable_low,(iy, ix),(1,1),
684                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
685        ix += 1
686        self.low_q_sizer.Add(self.fit_enable_low,(iy, ix),(1,1),
687                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[9ce7641c]688        ix = 1
689        iy += 1
690        self.low_q_sizer.Add(power_txt,(iy, ix),(1,1),
[518d35d]691                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[c128284]692        ix += 1
[9ce7641c]693        self.low_q_sizer.Add(self.power_low_tcl, (iy, ix), (1,1),
[c128284]694                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[9ce7641c]695        self.low_extrapolation_sizer.AddMany([(self.low_q_sizer, 0,
[d0cc0bbc]696                                                wx.BOTTOM|wx.RIGHT, 15)])
697       
[518d35d]698    def _enable_fit_power_law_high(self, event=None):
699        """
700            Enable and disable the power value editing
701        """
702        if self.fix_enable_high.IsEnabled():
703            if self.fix_enable_high.GetValue():
704                self.power_high_tcl.Enable()
705            else:
706                self.power_high_tcl.Disable()
[9ce7641c]707       
[518d35d]708    def _enable_high_q_section(self, event=None):
709        """
710            Disable or enable some button if the user enable high q extrapolation
711        """
712        if self.enable_high_cbox.GetValue():
713            self.npts_high_tcl.Enable()
714            self.power_law_high.Enable()
715            self.power_high_tcl.Enable()
716            self.fix_enable_high.Enable()
717            self.fit_enable_high.Enable()
718        else:
719            self.npts_high_tcl.Disable()
720            self.power_law_high.Disable()
721            self.power_high_tcl.Disable()
722            self.fix_enable_high.Disable()
723            self.fit_enable_high.Disable()
724        self._enable_fit_power_law_high()
[d0cc0bbc]725        self.button_calculate.SetFocus()
[518d35d]726 
[9ce7641c]727    def _layout_extrapolation_high(self):
728        """
729            Draw widgets related to extrapolation at high q range
730        """
[437e639]731        self.enable_high_cbox = wx.CheckBox(self, -1, "Enable Extrapolate high-Q")
[518d35d]732        wx.EVT_CHECKBOX(self, self.enable_high_cbox.GetId(),
733                                         self._enable_high_q_section)
734     
735        self.fix_enable_high = wx.RadioButton(self, -1, 'Fix',
736                                         (10, 10),style=wx.RB_GROUP)
737        self.fit_enable_high = wx.RadioButton(self, -1, 'Fit', (10, 10))
738        self.Bind(wx.EVT_RADIOBUTTON, self._enable_fit_power_law_high,
739                                     id=self.fix_enable_high.GetId())
740        self.Bind(wx.EVT_RADIOBUTTON, self._enable_fit_power_law_high, 
741                                        id=self.fit_enable_high.GetId())
742       
[277fad8]743        self.power_law_high = wx.StaticText(self, -1, 'Power Law')
[d0cc0bbc]744        msg_hint ="Check to extrapolate data at high-Q"
745        self.power_law_high.SetToolTipString(msg_hint)
[c128284]746        npts_high_txt = wx.StaticText(self, -1, 'Npts')
[518d35d]747        self.npts_high_tcl = InvTextCtrl(self, -1, size=(_BOX_WIDTH*2/3, -1))
[2661d8b]748        msg_hint = "Number of Q points to consider"
749        msg_hint += "while extrapolating the high-Q region"
[9ce7641c]750        self.npts_high_tcl.SetToolTipString(msg_hint)
751        power_txt = wx.StaticText(self, -1, 'Power')
[518d35d]752        self.power_high_tcl = InvTextCtrl(self, -1, size=(_BOX_WIDTH*2/3, -1))
[9ce7641c]753        power_hint_txt = "Exponent to apply to the Power_law function."
754        self.power_high_tcl.SetToolTipString(power_hint_txt)
[518d35d]755        iy = 0
756        ix = 0
757        self.high_q_sizer.Add(self.enable_high_cbox,(iy, ix),(1,5),
758                            wx.TOP|wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
759        iy += 1
760        ix = 0
761        self.high_q_sizer.Add(npts_high_txt,(iy, ix),(1,1),
762                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
763        ix += 1
764        self.high_q_sizer.Add(self.npts_high_tcl, (iy, ix), (1,1),
765                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
766        iy += 2
[c128284]767        ix = 0
[9ce7641c]768        self.high_q_sizer.Add(self.power_law_high,(iy, ix),(1,2),
[2661d8b]769                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[518d35d]770       
771        # Parameter controls for power law
[2661d8b]772        ix = 1
773        iy += 1
[518d35d]774        self.high_q_sizer.Add(self.fix_enable_high,(iy, ix),(1,1),
775                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
776        ix += 1
777        self.high_q_sizer.Add(self.fit_enable_high,(iy, ix),(1,1),
778                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[9ce7641c]779        ix = 1
780        iy += 1
781        self.high_q_sizer.Add(power_txt,(iy, ix),(1,1),
[c128284]782                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
783        ix += 1
[9ce7641c]784        self.high_q_sizer.Add(self.power_high_tcl, (iy, ix), (1,1),
[c128284]785                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[d0cc0bbc]786        self.high_extrapolation_sizer.AddMany([(self.high_q_sizer, 0, 
787                                                wx.BOTTOM|wx.RIGHT, 10)])
[c128284]788       
[9ce7641c]789    def _layout_extrapolation(self):
790        """
791            Draw widgets related to extrapolation
792        """
[518d35d]793        extra_hint = "Extrapolation Maximum Q Range [1/A]: "
[9ce7641c]794        extra_hint_txt = wx.StaticText(self, -1, extra_hint)
795        #Extrapolation range [string]
796        extrapolation_min_txt = wx.StaticText(self, -1, 'Min : ') 
[518d35d]797        self.extrapolation_min_tcl = OutputTextCtrl(self, -1, 
[9ce7641c]798                                                size=(_BOX_WIDTH, 20), style=0)
799        self.extrapolation_min_tcl.SetValue(str(Q_MINIMUM))
800        self.extrapolation_min_tcl.SetToolTipString("The minimum extrapolated q value.")
801        extrapolation_max_txt = wx.StaticText(self, -1, 'Max : ') 
[518d35d]802        self.extrapolation_max_tcl = OutputTextCtrl(self, -1,
[9ce7641c]803                                                  size=(_BOX_WIDTH, 20), style=0) 
804        self.extrapolation_max_tcl.SetValue(str(Q_MAXIMUM))
805        self.extrapolation_max_tcl.SetToolTipString("The maximum extrapolated q value.")
806        self.extrapolation_range_sizer.AddMany([(extra_hint_txt, 0, wx.LEFT, 10),
807                                                (extrapolation_min_txt, 0, wx.LEFT, 10),
808                                                (self.extrapolation_min_tcl,
809                                                            0, wx.LEFT, 10),
810                                                (extrapolation_max_txt, 0, wx.LEFT, 10),
811                                                (self.extrapolation_max_tcl,
812                                                            0, wx.LEFT, 10),
813                                                ])
814        self._layout_extrapolation_low()
815        self._layout_extrapolation_high()
816        self.extrapolation_low_high_sizer.AddMany([(self.low_extrapolation_sizer,
817                                                     0, wx.ALL, 10),
818                                                   (self.high_extrapolation_sizer,
819                                                    0, wx.ALL, 10)])
820        self.extrapolation_sizer.AddMany([(self.extrapolation_range_sizer, 0,
821                                            wx.RIGHT, 10),
822                                        (self.extrapolation_low_high_sizer, 0,
823                                           wx.ALL, 10)])
824       
825    def _layout_volume_surface_sizer(self):
826        """
827            Draw widgets related to volume and surface
828        """
829        unit_volume = ''
830        unit_surface = ''
831        uncertainty = "+/-" 
[dce0756]832        volume_txt = wx.StaticText(self, -1, 'Volume Fraction      ')
[518d35d]833        self.volume_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]834        self.volume_tcl.SetToolTipString("Volume fraction.")
[518d35d]835        self.volume_err_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]836        self.volume_err_tcl.SetToolTipString("Uncertainty on the volume fraction.")
[c128284]837        volume_units_txt = wx.StaticText(self, -1, unit_volume)
838       
[277fad8]839        surface_txt = wx.StaticText(self, -1, 'Specific Surface')
[518d35d]840        self.surface_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]841        self.surface_tcl.SetToolTipString("Specific surface value.")
[518d35d]842        self.surface_err_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]843        self.surface_err_tcl.SetToolTipString("Uncertainty on the specific surface.")
[c128284]844        surface_units_txt = wx.StaticText(self, -1, unit_surface)
845        iy = 0
846        ix = 0
[9ce7641c]847        self.volume_surface_sizer.Add(volume_txt, (iy, ix), (1,1),
[c128284]848                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[9ce7641c]849        ix += 1
850        self.volume_surface_sizer.Add(self.volume_tcl, (iy, ix), (1,1),
851                            wx.EXPAND|wx.ADJUST_MINSIZE, 10)
852        ix += 1
853        self.volume_surface_sizer.Add(wx.StaticText(self, -1, uncertainty),
854                         (iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 10) 
855        ix += 1
856        self.volume_surface_sizer.Add(self.volume_err_tcl, (iy, ix), (1,1),
857                            wx.EXPAND|wx.ADJUST_MINSIZE, 10) 
858        ix += 1
859        self.volume_surface_sizer.Add(volume_units_txt, (iy, ix), (1,1),
860                             wx.EXPAND|wx.ADJUST_MINSIZE, 10)
[c128284]861        iy += 1
862        ix = 0
[9ce7641c]863        self.volume_surface_sizer.Add(surface_txt, (iy, ix), (1,1),
864                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[c128284]865        ix += 1
[9ce7641c]866        self.volume_surface_sizer.Add(self.surface_tcl, (iy, ix), (1,1),
867                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[c128284]868        ix += 1
[9ce7641c]869        self.volume_surface_sizer.Add(wx.StaticText(self, -1, uncertainty),
[c128284]870                         (iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
871        ix += 1
[9ce7641c]872        self.volume_surface_sizer.Add(self.surface_err_tcl, (iy, ix), (1,1),
[c128284]873                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
874        ix += 1
[9ce7641c]875        self.volume_surface_sizer.Add(surface_units_txt, (iy, ix), (1,1),
876                            wx.EXPAND|wx.ADJUST_MINSIZE, 10)
877       
878    def _layout_invariant_sizer(self):
879        """
880            Draw widgets related to invariant
881        """
882        uncertainty = "+/-" 
[277fad8]883        unit_invariant = '[1/(cm * A)]'
[eed601e]884        invariant_total_txt = wx.StaticText(self, -1, 'Invariant Total [Q*]')
[518d35d]885        self.invariant_total_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[eed601e]886        msg_hint = "Total invariant [Q*], including extrapolated regions."
[9ce7641c]887        self.invariant_total_tcl.SetToolTipString(msg_hint)
[518d35d]888        self.invariant_total_err_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]889        self.invariant_total_err_tcl.SetToolTipString("Uncertainty on invariant.")
890        invariant_total_units_txt = wx.StaticText(self, -1, unit_invariant)
891   
892        #Invariant total
893        iy = 0
[c128284]894        ix = 0
[9ce7641c]895        self.invariant_sizer.Add(invariant_total_txt, (iy, ix), (1,1),
[c128284]896                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[9ce7641c]897        ix += 1
898        self.invariant_sizer.Add(self.invariant_total_tcl, (iy, ix), (1,1),
[dce0756]899                          wx.EXPAND|wx.ADJUST_MINSIZE, 10)
[c128284]900        ix += 1
[9ce7641c]901        self.invariant_sizer.Add( wx.StaticText(self, -1, uncertainty),
[277fad8]902                         (iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 10) 
[c128284]903        ix += 1
[9ce7641c]904        self.invariant_sizer.Add(self.invariant_total_err_tcl, (iy, ix), (1,1),
[277fad8]905                             wx.EXPAND|wx.ADJUST_MINSIZE, 10)
[c128284]906        ix += 1
[277fad8]907        self.invariant_sizer.Add(invariant_total_units_txt,(iy, ix), (1,1),
908                          wx.EXPAND|wx.ADJUST_MINSIZE, 10)
[9ce7641c]909 
[d0cc0bbc]910    def _layout_inputs_sizer(self):
911        """
912            Draw widgets related to inputs
913        """
914        self._layout_bkg_scale()
915        self._layout_contrast_porod()
916        self.inputs_sizer.AddMany([(self.bkg_scale_sizer, 0, wx.ALL, 5),
917                                    (self.contrast_porod_sizer, 0, wx.ALL, 5)])
918       
[9ce7641c]919    def _layout_outputs_sizer(self):
920        """
921            Draw widgets related to outputs
922        """
923        self._layout_volume_surface_sizer()
924        self._layout_invariant_sizer()
925        static_line = wx.StaticLine(self, -1)
926        self.outputs_sizer.AddMany([(self.volume_surface_sizer, 0, wx.ALL, 10),
927                                    (static_line, 0, wx.EXPAND, 0),
928                                    (self.invariant_sizer, 0, wx.ALL, 10)])
929    def _layout_button(self): 
930        """
931            Do the layout for the button widgets
932        """ 
933        #compute button
[c128284]934        id = wx.NewId()
[d0cc0bbc]935        self.button_calculate = wx.Button(self, id, "Compute")
936        self.button_calculate.SetToolTipString("Compute invariant")
[9ce7641c]937        self.Bind(wx.EVT_BUTTON, self.compute_invariant, id=id)   
938        #detail button
939        id = wx.NewId()
[d0cc0bbc]940        self.button_details = wx.Button(self, id, "Details?")
941        self.button_details.SetToolTipString("Give Details on Computation")
[9ce7641c]942        self.Bind(wx.EVT_BUTTON, self.display_details, id=id)
943        details = "Details on Invariant Total Calculations"
944        details_txt = wx.StaticText(self, -1, details)
[d0cc0bbc]945        self.button_sizer.AddMany([((10,10), 0 , wx.LEFT,0),
946                                   (details_txt, 0 , 
947                                    wx.RIGHT|wx.BOTTOM|wx.TOP, 10),
948                                   (self.button_details, 0 , wx.ALL, 10),
949                        (self.button_calculate, 0 , wx.RIGHT|wx.TOP|wx.BOTTOM, 10)])
[d5f0dcb9]950       
[9ce7641c]951    def _do_layout(self):
952        """
953            Draw window content
954        """
955        self._define_structure()
956        self._layout_data_name()
957        self._layout_extrapolation()
[d0cc0bbc]958        self._layout_inputs_sizer()
[9ce7641c]959        self._layout_outputs_sizer()
960        self._layout_button()
[d0cc0bbc]961        self.main_sizer.AddMany([(self.data_name_boxsizer, 1, wx.ALL, 10),
[9ce7641c]962                                  (self.outputs_sizer, 0,
963                                  wx.LEFT|wx.RIGHT|wx.BOTTOM, 10),
964                                  (self.button_sizer, 0,
[d0cc0bbc]965                                  wx.LEFT|wx.RIGHT|wx.BOTTOM, 10),
966                                 (self.inputs_sizer, 0,
967                                  wx.LEFT|wx.RIGHT|wx.BOTTOM, 10),
968                                  (self.extrapolation_sizer, 0,
[9ce7641c]969                                  wx.LEFT|wx.RIGHT|wx.BOTTOM, 10)])
970        self.SetSizer(self.main_sizer)
971        self.SetScrollbars(20,20,25,65)
972        self.SetAutoLayout(True)
[c128284]973   
974class InvariantDialog(wx.Dialog):
975    def __init__(self, parent=None, id=1,graph=None,
[272d91e]976                 data=None, title="Invariant",base=None):
977        wx.Dialog.__init__(self, parent, id, title, size=(PANEL_WIDTH,
[c128284]978                                                             PANEL_HEIGHT))
[272d91e]979        self.panel = InvariantPanel(self)
[c128284]980        self.Centre()
981        self.Show(True)
982       
983class InvariantWindow(wx.Frame):
[272d91e]984    def __init__(self, parent=None, id=1,graph=None, 
985                 data=None, title="Invariant",base=None):
[c128284]986       
[9ce7641c]987        wx.Frame.__init__(self, parent, id, title, size=(PANEL_WIDTH +100,
988                                                             PANEL_HEIGHT+100))
[c128284]989       
[272d91e]990        self.panel = InvariantPanel(self)
[c128284]991        self.Centre()
992        self.Show(True)
993       
994class MyApp(wx.App):
995    def OnInit(self):
996        wx.InitAllImageHandlers()
997        frame = InvariantWindow()
998        frame.Show(True)
999        self.SetTopWindow(frame)
1000       
1001        return True
[272d91e]1002     
[c128284]1003# end of class MyApp
1004
1005if __name__ == "__main__":
1006    app = MyApp(0)
1007    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.