source: sasview/invariantview/perspectives/invariant/invariant_panel.py @ 00e8df8

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 00e8df8 was f43827cc, checked in by Gervaise Alina <gervyh@…>, 15 years ago

add error check

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