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

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 df7ed14 was 90b9a17, checked in by Jae Cho <jhjcho@…>, 14 years ago

minor improvement in High Q plot especially when background is set close to the I_min value

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