source: sasview/invariantview/perspectives/invariant/invariant_panel.py @ c5dca87

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 c5dca87 was 353f467, checked in by Jae Cho <jhjcho@…>, 15 years ago

fixed plotting bug

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