source: sasview/prview/perspectives/pr/inversion_panel.py @ 0ccd214

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 0ccd214 was 0ccd214, checked in by Mathieu Doucet <doucetm@…>, 15 years ago

prview: changed default sizes of panel objects

  • Property mode set to 100644
File size: 46.5 KB
Line 
1#!/usr/bin/env python
2
3# version
4__id__ = "$Id: aboutdialog.py 1193 2007-05-03 17:29:59Z dmitriy $"
5__revision__ = "$Revision: 1193 $"
6
7import wx
8import os
9import sys
10import logging
11from sans.guicomm.events import StatusEvent   
12from inversion_state import InversionState
13
14class InversionDlg(wx.Dialog):
15    def __init__(self, parent, id, title, plots, file=False, pars=True):
16       
17        # Estimate size
18        nplots = len(plots)
19        # y size for data set only
20        ysize  = 110 + nplots*20
21        # y size including parameters
22        if pars:
23            ysize  += 90
24       
25        wx.Dialog.__init__(self, parent, id, title, size=(250, ysize))
26        self.SetTitle(title)
27
28        # Data set
29        self.datasets = InversionPanel(self, -1, plots)
30        vbox = wx.BoxSizer(wx.VERTICAL)
31
32        vbox.Add(self.datasets)
33
34        # Parameters
35        self.pars_flag = False
36        if pars==True:
37            self.pars_flag = True
38            self.pars = ParsDialog(self, -1, file=file)
39            vbox.Add(self.pars)
40
41        static_line = wx.StaticLine(self, -1)
42        vbox.Add(static_line, 0, wx.EXPAND, 0)
43       
44        button_OK = wx.Button(self, wx.ID_OK, "OK")
45        button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
46       
47        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
48        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
49        sizer_button.Add(button_OK, 0, wx.LEFT|wx.ADJUST_MINSIZE, 10)
50        sizer_button.Add(button_Cancel, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)       
51        vbox.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
52
53        self.SetSizer(vbox)
54        self.SetAutoLayout(True)
55       
56        self.Layout()
57        self.Centre()
58
59    def get_content(self):
60        dataset = self.datasets.get_selected()
61        if self.pars_flag:
62            nfunc, alpha, dmax, file = self.pars.getContent()
63            return dataset, nfunc, alpha, dmax
64        else:
65            return dataset
66   
67    def set_content(self, dataset, nfunc, alpha, dmax):
68        if not dataset==None and dataset in self.datasets.radio_buttons.keys():
69            self.datasets.radio_buttons[dataset].SetValue(True)
70        if self.pars_flag:
71            self.pars.setContent(nfunc, alpha, dmax, None)
72
73class InversionPanel(wx.Panel):
74   
75    def __init__(self, parent, id = -1, plots = None, **kwargs):
76        wx.Panel.__init__(self, parent, id = id, **kwargs)
77       
78        self.plots = plots
79        self.radio_buttons = {}
80       
81        self._do_layout()
82       
83    def _do_layout(self):
84        panel = wx.Panel(self, -1)
85        vbox = wx.BoxSizer(wx.VERTICAL)
86
87        ysize = 30+20*len(self.plots)
88        wx.StaticBox(panel, -1, 'Choose a data set', (5, 5), (230, ysize))
89        ypos = 30
90        self.radio_buttons = {}
91        for item in self.plots.keys():
92            self.radio_buttons[self.plots[item].name] = wx.RadioButton(panel, -1, self.plots[item].name, (15, ypos))
93            ypos += 20
94       
95        vbox.Add(panel)
96
97        self.SetSizer(vbox)
98       
99    def get_selected(self):
100        for item in self.radio_buttons:
101            if self.radio_buttons[item].GetValue():
102                return item
103        return None
104
105class InversionControl(wx.Panel):
106    window_name = 'pr_control'
107    window_caption = "P(r) control panel"
108    CENTER_PANE = True
109   
110    # Figure of merit parameters [default]
111   
112    ## Oscillation parameters (sin function = 1.1)
113    oscillation_max = 1.5
114   
115    def __init__(self, parent, id = -1, plots = None, standalone=False, **kwargs):
116        wx.Panel.__init__(self, parent, id = id, **kwargs)
117       
118        self.plots = plots
119        self.radio_buttons = {}
120        self.parent = parent
121       
122        ## Data file TextCtrl
123        self.data_file  = None
124        self.plot_data  = None
125        self.nfunc_ctl  = None
126        self.alpha_ctl  = None
127        self.dmax_ctl   = None
128        self.time_ctl   = None
129        self.chi2_ctl   = None
130        self.osc_ctl    = None
131        self.file_radio = None
132        self.plot_radio = None
133        self.label_sugg = None
134        self.qmin_ctl   = None
135        self.qmax_ctl   = None
136        self.swidth_ctl = None
137        self.sheight_ctl = None
138       
139        self.rg_ctl     = None
140        self.iq0_ctl    = None
141        self.bck_chk    = None
142        self.bck_ctl    = None
143       
144        # TextCtrl for fraction of positive P(r)
145        self.pos_ctl = None
146       
147        # TextCtrl for fraction of 1 sigma positive P(r)
148        self.pos_err_ctl = None 
149       
150        ## Estimates
151        self.alpha_estimate_ctl = None
152        self.nterms_estimate_ctl = None
153       
154        ## D_max distance explorator
155        self.distance_explorator_ctl = None
156       
157        ## Data manager
158        self.manager   = None
159       
160        ## Standalone flage
161        self.standalone = standalone
162       
163        ## Default file location for save
164        self._default_save_location = os.getcwd()
165       
166       
167        # Default width
168        self._default_width = 350
169        self._do_layout()
170       
171    def __setattr__(self, name, value):
172        """
173            Allow direct hooks to text boxes
174        """
175        if name=='nfunc':
176            self.nfunc_ctl.SetValue(str(int(value)))
177        elif name=='d_max':
178            self.dmax_ctl.SetValue(str(value))
179        elif name=='alpha':
180            self.alpha_ctl.SetValue(str(value))
181        elif name=='chi2':
182            self.chi2_ctl.SetValue("%-5.2g" % value)
183        elif name=='bck':
184            self.bck_ctl.SetValue("%-5.2g" % value)
185        elif name=='q_min':
186            self.qmin_ctl.SetValue("%-5.2g" % value)
187        elif name=='q_max':
188            self.qmax_ctl.SetValue("%-5.2g" % value)
189        elif name=='elapsed':
190            self.time_ctl.SetValue("%-5.2g" % value)
191        elif name=='rg':
192            self.rg_ctl.SetValue("%-5.2g" % value)
193        elif name=='iq0':
194            self.iq0_ctl.SetValue("%-5.2g" % value)
195        elif name=='oscillation':
196            self.osc_ctl.SetValue("%-5.2g" % value)
197        elif name=='slit_width':
198            self.swidth_ctl.SetValue("%-5.2g" % value)
199        elif name=='slit_height':
200            self.sheight_ctl.SetValue("%-5.2g" % value)
201        elif name=='positive':
202            self.pos_ctl.SetValue("%-5.2g" % value)
203        elif name=='pos_err':
204            self.pos_err_ctl.SetValue("%-5.2g" % value)
205        elif name=='alpha_estimate':
206            self.alpha_estimate_ctl.SetToolTipString("Click to accept value.")
207            self.alpha_estimate_ctl.Enable(True)
208            self.alpha_estimate_ctl.SetLabel("%-3.1g" % value)
209            #self.alpha_estimate_ctl.Show()
210            #self.label_sugg.Show()
211        elif name=='nterms_estimate':
212            self.nterms_estimate_ctl.SetToolTipString("Click to accept value.")
213            self.nterms_estimate_ctl.Enable(True)
214            self.nterms_estimate_ctl.SetLabel("%-g" % value)
215        elif name=='plotname':
216            self.plot_data.SetValue(str(value))
217            self._on_pars_changed(None)
218        elif name=='datafile':
219            self.plot_data.SetValue(str(value))
220            self._on_pars_changed(None)
221        else:
222            wx.Panel.__setattr__(self, name, value)
223       
224    def __getattr__(self, name):
225        """
226            Allow direct hooks to text boxes
227        """
228        if name=='nfunc':
229            try:
230                return int(self.nfunc_ctl.GetValue())
231            except:
232                return -1
233        elif name=='d_max':
234            try:
235                return self.dmax_ctl.GetValue()
236            except:
237                return -1.0
238        elif name=='alpha':
239            try:
240                return self.alpha_ctl.GetValue()
241            except:
242                return -1.0
243        elif name=='chi2':
244            try:
245                return float(self.chi2_ctl.GetValue())
246            except:
247                return None
248        elif name=='bck':
249            try:
250                return float(self.bck_ctl.GetValue())
251            except:
252                return None
253        elif name=='q_min':
254            try:
255                return float(self.qmin_ctl.GetValue())
256            except:
257                return 0.0
258        elif name=='q_max':
259            try:
260                return float(self.qmax_ctl.GetValue())
261            except:
262                return 0.0
263        elif name=='elapsed':
264            try:
265                return float(self.time_ctl.GetValue())
266            except:
267                return None
268        elif name=='rg':
269            try:
270                return float(self.rg_ctl.GetValue())
271            except:
272                return None
273        elif name=='iq0':
274            try:
275                return float(self.iq0_ctl.GetValue())
276            except:
277                return None
278        elif name=='oscillation':
279            try:
280                return float(self.osc_ctl.GetValue())
281            except:
282                return None
283        elif name=='slit_width':
284            try:
285                return float(self.swidth_ctl.GetValue())
286            except:
287                return None
288        elif name=='slit_height':
289            try:
290                return float(self.sheight_ctl.GetValue())
291            except:
292                return None
293        elif name=='pos':
294            try:
295                return float(self.pos_ctl.GetValue())
296            except:
297                return None
298        elif name=='pos_err':
299            try:
300                return float(self.pos_err_ctl.GetValue())
301            except:
302                return None
303        elif name=='alpha_estimate':
304            try:
305                return float(self.alpha_estimate_ctl.GetLabel())
306            except:
307                return None
308        elif name=='nterms_estimate':
309            try:
310                return int(self.nterms_estimate_ctl.GetLabel())
311            except:
312                return None
313        elif name=='plotname':
314            return self.plot_data.GetValue()
315        elif name=='datafile':
316            return self.plot_data.GetValue()
317        else:
318            return wx.Panel.__getattribute__(self, name)
319       
320    def _save_state(self, evt=None):
321        """
322            Method used to create a memento of the current state
323           
324            @return: state object
325        """
326        # Ask the user the location of the file to write to.
327        path = None
328        dlg = wx.FileDialog(self, "Choose a file", self._default_save_location, "", "*.prv", wx.SAVE)
329        if dlg.ShowModal() == wx.ID_OK:
330            path = dlg.GetPath()
331            self._default_save_location = os.path.dirname(path)
332        else:
333            return None
334       
335        dlg.Destroy()
336               
337        # Construct the state object   
338        state = InversionState()
339       
340        # Read the panel's parameters
341        flag, alpha, dmax, nfunc, qmin, \
342        qmax, height, width = self._read_pars()
343       
344        state.nfunc = nfunc
345        state.d_max = dmax
346        state.alpha = alpha
347        state.qmin  = qmin
348        state.qmax  = qmax
349        state.width = width
350        state.height = height
351       
352        # Data file
353        state.file = self.plot_data.GetValue()
354       
355        # Background evaluation checkbox
356        state.estimate_bck = self.bck_chk.IsChecked()
357       
358        # Estimates
359        state.nterms_estimate = self.nterms_estimate
360        state.alpha_estimate = self.alpha_estimate
361       
362        # Read the output values
363        state.chi2    = self.chi2
364        state.elapsed = self.elapsed
365        state.osc     = self.oscillation
366        state.pos     = self.pos
367        state.pos_err = self.pos_err
368        state.rg      = self.rg
369        state.iq0     = self.iq0
370        state.bck     = self.bck
371           
372        self.manager.save_data(filepath=path, prstate=state)
373       
374        return state
375   
376    def set_state(self, state):
377        """
378            Set the state of the panel and inversion problem to
379            the state passed as a parameter.
380            Execute the inversion immediately after filling the
381            controls.
382           
383            @param state: InversionState object
384        """
385        if state.nfunc is not None:
386            self.nfunc = state.nfunc
387        if state.d_max is not None:
388            self.d_max = state.d_max
389        if state.alpha is not None:
390            self.alpha = state.alpha
391        if state.qmin is not None:
392            self.q_min  = state.qmin
393        if state.qmax is not None:
394            self.q_max  = state.qmax
395        if state.width is not None:
396            self.slit_width = state.width
397        if state.height is not None:
398            self.slit_height = state.height
399       
400        # Data file
401        self.plot_data.SetValue(str(state.file))
402   
403        # Background evaluation checkbox
404        self.bck_chk.SetValue(state.estimate_bck)
405       
406        # Estimates
407        if state.nterms_estimate is not None:
408            self.nterms_estimate = state.nterms_estimate
409        if state.alpha_estimate is not None: 
410            self.alpha_estimate = state.alpha_estimate
411   
412       
413        # Read the output values
414        if state.chi2 is not None:
415            self.chi2    = state.chi2
416        if state.elapsed is not None:
417            self.elapsed = state.elapsed
418        if state.osc is not None:
419            self.oscillation = state.osc
420        if state.pos is not None:
421            self.positive = state.pos
422        if state.pos_err is not None:
423            self.pos_err = state.pos_err
424        if state.rg is not None:
425            self.rg      = state.rg
426        if state.iq0 is not None:
427            self.iq0     = state.iq0
428        if state.bck is not None:
429            self.bck     = state.bck
430
431        # Perform inversion
432        if self.standalone == False:
433            self._on_invert(None)   
434       
435    def set_manager(self, manager):
436        self.manager = manager
437       
438    def _do_layout(self):
439        vbox = wx.GridBagSizer(0,0)
440        iy_vb = 0
441
442        # ----- I(q) data -----
443        databox = wx.StaticBox(self, -1, "I(q) data source")
444       
445        boxsizer1 = wx.StaticBoxSizer(databox, wx.VERTICAL)
446        boxsizer1.SetMinSize((self._default_width,50))
447        pars_sizer = wx.GridBagSizer(5,5)
448
449        iy = 0
450        self.file_radio = wx.StaticText(self, -1, "Data:")
451        pars_sizer.Add(self.file_radio, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
452       
453        self.plot_data = wx.TextCtrl(self, -1, size=(220,20))
454        self.plot_data.SetEditable(False)
455        pars_sizer.Add(self.plot_data, (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 15)
456       
457        self.bck_chk = wx.CheckBox(self, -1, "Estimate background level")
458        self.bck_chk.SetToolTipString("Check box to let the fit estimate the constant background level.")
459        self.bck_chk.Bind(wx.EVT_CHECKBOX, self._on_pars_changed)
460        iy += 1
461        pars_sizer.Add(self.bck_chk, (iy,0), (1,2), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
462        boxsizer1.Add(pars_sizer, 0, wx.EXPAND) 
463        vbox.Add(boxsizer1, (iy_vb,0), (1,1), wx.LEFT|wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE|wx.TOP, 5)
464       
465        # ----- Add slit parameters -----
466        if True:
467            sbox = wx.StaticBox(self, -1, "Slit parameters")
468            sboxsizer = wx.StaticBoxSizer(sbox, wx.VERTICAL)
469            sboxsizer.SetMinSize((self._default_width,20))
470           
471            sizer_slit = wx.GridBagSizer(5,5)
472   
473            label_sheight = wx.StaticText(self, -1, "Height", size=(40,20))
474            label_swidth = wx.StaticText(self, -1, "Width", size=(40,20))
475            #label_sunits1 = wx.StaticText(self, -1, "[A^(-1)]")
476            label_sunits2 = wx.StaticText(self, -1, "[A^(-1)]", size=(55,20))
477            self.sheight_ctl = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER, size=(60,20))
478            self.swidth_ctl = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER, size=(60,20))
479            self.sheight_ctl.SetToolTipString("Enter slit height in units of Q or leave blank.")
480            self.swidth_ctl.SetToolTipString("Enter slit width in units of Q or leave blank.")
481            #self.sheight_ctl.Bind(wx.EVT_TEXT, self._on_pars_changed)
482            #self.swidth_ctl.Bind(wx.EVT_TEXT,  self._on_pars_changed)
483           
484            iy = 0
485            sizer_slit.Add(label_sheight,    (iy,0), (1,1), wx.LEFT|wx.EXPAND, 5)
486            sizer_slit.Add(self.sheight_ctl, (iy,1), (1,1), wx.LEFT|wx.EXPAND, 5)
487            #sizer_slit.Add(label_sunits1,    (iy,2), (1,1), wx.LEFT|wx.EXPAND, 10)
488            sizer_slit.Add(label_swidth,     (iy,2), (1,1), wx.LEFT|wx.EXPAND, 5)
489            sizer_slit.Add(self.swidth_ctl,  (iy,3), (1,1), wx.LEFT|wx.EXPAND, 5)
490            sizer_slit.Add(label_sunits2,    (iy,4), (1,1), wx.LEFT|wx.EXPAND, 5)
491           
492            sboxsizer.Add(sizer_slit, wx.TOP, 15)
493            iy_vb += 1
494            vbox.Add(sboxsizer, (iy_vb,0), (1,1), wx.LEFT|wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
495       
496       
497        # ----- Q range -----
498        qbox = wx.StaticBox(self, -1, "Q range")
499        qboxsizer = wx.StaticBoxSizer(qbox, wx.VERTICAL)
500        qboxsizer.SetMinSize((self._default_width,20))
501       
502        sizer_q = wx.GridBagSizer(5,5)
503
504        label_qmin = wx.StaticText(self, -1, "Q min", size=(40,20))
505        label_qmax = wx.StaticText(self, -1, "Q max", size=(40,20))
506        #label_qunits1 = wx.StaticText(self, -1, "[A^(-1)]")
507        label_qunits2 = wx.StaticText(self, -1, "[A^(-1)]", size=(55,20))
508        self.qmin_ctl = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER, size=(60,20))
509        self.qmax_ctl = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER, size=(60,20))
510        self.qmin_ctl.SetToolTipString("Select a lower bound for Q or leave blank.")
511        self.qmax_ctl.SetToolTipString("Select an upper bound for Q or leave blank.")
512        self.qmin_ctl.Bind(wx.EVT_TEXT, self._on_pars_changed)
513        self.qmax_ctl.Bind(wx.EVT_TEXT, self._on_pars_changed)
514       
515        iy = 0
516        sizer_q.Add(label_qmin,    (iy,0), (1,1), wx.LEFT|wx.EXPAND, 5)
517        sizer_q.Add(self.qmin_ctl, (iy,1), (1,1), wx.LEFT|wx.EXPAND, 5)
518        #sizer_q.Add(label_qunits1, (iy,2), (1,1), wx.LEFT|wx.EXPAND, 15)
519        sizer_q.Add(label_qmax,    (iy,2), (1,1), wx.LEFT|wx.EXPAND, 5)
520        sizer_q.Add(self.qmax_ctl, (iy,3), (1,1), wx.LEFT|wx.EXPAND, 5)
521        sizer_q.Add(label_qunits2, (iy,4), (1,1), wx.LEFT|wx.EXPAND, 5)
522        qboxsizer.Add(sizer_q, wx.TOP, 15)
523
524        iy_vb += 1
525        vbox.Add(qboxsizer, (iy_vb,0), (1,1), wx.LEFT|wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
526       
527       
528       
529
530        # ----- Parameters -----
531        parsbox = wx.StaticBox(self, -1, "Parameters")
532        boxsizer2 = wx.StaticBoxSizer(parsbox, wx.VERTICAL)
533        boxsizer2.SetMinSize((self._default_width,50))
534       
535        explanation  = "P(r) is found by fitting a set of base functions to I(Q). "
536        explanation += "The minimization involves a regularization term to ensure "
537        explanation += "a smooth P(r). The regularization constant gives the size of that " 
538        explanation += "term. The suggested value is the value above which the "
539        explanation += "output P(r) will have only one peak."
540        label_explain = wx.StaticText(self, -1, explanation, size=(280,120))
541        boxsizer2.Add(label_explain,  wx.LEFT|wx.BOTTOM, 5)
542       
543       
544       
545        label_nfunc = wx.StaticText(self, -1, "Number of terms")
546        label_nfunc.SetMinSize((120,20))
547        label_alpha = wx.StaticText(self, -1, "Regularization constant")
548        label_dmax  = wx.StaticText(self, -1, "Max distance [A]")
549        self.label_sugg  = wx.StaticText(self, -1, "Suggested value")
550        #self.label_sugg.Hide()
551       
552        self.nfunc_ctl = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER, size=(60,20))
553        self.nfunc_ctl.SetToolTipString("Number of terms in the expansion.")
554        self.alpha_ctl = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER, size=(60,20))
555        self.alpha_ctl.SetToolTipString("Control parameter for the size of the regularization term.")
556        self.dmax_ctl  = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER, size=(60,20))
557        self.dmax_ctl.SetToolTipString("Maximum distance between any two points in the system.")
558        id = wx.NewId()
559        self.alpha_estimate_ctl  = wx.Button(self, id, "")
560        #self.alpha_estimate_ctl.Hide()
561        self.Bind(wx.EVT_BUTTON, self._on_accept_alpha, id = id)   
562        self.alpha_estimate_ctl.Enable(False)
563        #self.alpha_estimate_ctl.SetBackgroundColour('#ffdf85')
564        #self.alpha_estimate_ctl.SetBackgroundColour(self.GetBackgroundColour())
565        self.alpha_estimate_ctl.SetToolTipString("Waiting for estimate...")
566       
567        id = wx.NewId()
568        self.nterms_estimate_ctl  = wx.Button(self, id, "")
569        #self.nterms_estimate_ctl.Hide()
570        self.Bind(wx.EVT_BUTTON, self._on_accept_nterms, id = id)   
571        self.nterms_estimate_ctl.Enable(False)
572        #self.nterms_estimate_ctl.SetBackgroundColour('#ffdf85')
573        #self.nterms_estimate_ctl.SetBackgroundColour(self.GetBackgroundColour())
574        self.nterms_estimate_ctl.SetToolTipString("Waiting for estimate...")
575       
576        self.nfunc_ctl.Bind(wx.EVT_TEXT, self._read_pars)
577        self.alpha_ctl.Bind(wx.EVT_TEXT, self._read_pars)
578        self.dmax_ctl.Bind(wx.EVT_TEXT, self._on_pars_changed)
579       
580        # Distance explorator
581        id = wx.NewId()
582        self.distance_explorator_ctl = wx.Button(self, id, "Explore")
583        self.Bind(wx.EVT_BUTTON, self._on_explore, id = id)           
584       
585       
586        sizer_params = wx.GridBagSizer(5,5)
587
588        iy = 0
589        sizer_params.Add(self.label_sugg,       (iy,2), (1,1), wx.LEFT, 15)
590        iy += 1
591        sizer_params.Add(label_nfunc,      (iy,0), (1,1), wx.LEFT, 15)
592        sizer_params.Add(self.nfunc_ctl,   (iy,1), (1,1), wx.RIGHT, 0)
593        sizer_params.Add(self.nterms_estimate_ctl, (iy,2), (1,1), wx.LEFT, 15)
594        iy += 1
595        sizer_params.Add(label_alpha,      (iy,0), (1,1), wx.LEFT, 15)
596        sizer_params.Add(self.alpha_ctl,   (iy,1), (1,1), wx.RIGHT, 0)
597        sizer_params.Add(self.alpha_estimate_ctl, (iy,2), (1,1), wx.LEFT, 15)
598        iy += 1
599        sizer_params.Add(label_dmax, (iy,0), (1,1), wx.LEFT, 15)
600        sizer_params.Add(self.dmax_ctl,   (iy,1), (1,1), wx.RIGHT, 0)
601        sizer_params.Add(self.distance_explorator_ctl,   (iy,2), (1,1), wx.LEFT, 15)
602
603        boxsizer2.Add(sizer_params, 0)
604       
605        iy_vb += 1
606        vbox.Add(boxsizer2, (iy_vb,0), (1,1), wx.LEFT|wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
607
608
609        # ----- Results -----
610        resbox = wx.StaticBox(self, -1, "Outputs")
611        ressizer = wx.StaticBoxSizer(resbox, wx.VERTICAL)
612        ressizer.SetMinSize((self._default_width,50))
613       
614        label_rg       = wx.StaticText(self, -1, "Rg")
615        label_rg_unit  = wx.StaticText(self, -1, "[A]")
616        label_iq0      = wx.StaticText(self, -1, "I(Q=0)")
617        label_iq0_unit = wx.StaticText(self, -1, "[A^(-1)]")
618        label_bck      = wx.StaticText(self, -1, "Background")
619        label_bck_unit = wx.StaticText(self, -1, "[A^(-1)]")
620        self.rg_ctl    = wx.TextCtrl(self, -1, size=(60,20))
621        self.rg_ctl.SetEditable(False)
622        self.rg_ctl.SetToolTipString("Radius of gyration for the computed P(r).")
623        self.iq0_ctl   = wx.TextCtrl(self, -1, size=(60,20))
624        self.iq0_ctl.SetEditable(False)
625        self.iq0_ctl.SetToolTipString("Scattering intensity at Q=0 for the computed P(r).")
626        self.bck_ctl   = wx.TextCtrl(self, -1, size=(60,20))
627        self.bck_ctl.SetEditable(False)
628        self.bck_ctl.SetToolTipString("Value of estimated constant background.")
629       
630        label_time = wx.StaticText(self, -1, "Computation time")
631        label_time_unit = wx.StaticText(self, -1, "secs")
632        label_time.SetMinSize((120,20))
633        label_chi2 = wx.StaticText(self, -1, "Chi2/dof")
634        label_osc = wx.StaticText(self, -1, "Oscillations")
635        label_pos = wx.StaticText(self, -1, "Positive fraction")
636        label_pos_err = wx.StaticText(self, -1, "1-sigma positive fraction")
637       
638        self.time_ctl = wx.TextCtrl(self, -1, size=(60,20))
639        self.time_ctl.SetEditable(False)
640        self.time_ctl.SetToolTipString("Computation time for the last inversion, in seconds.")
641       
642        self.chi2_ctl = wx.TextCtrl(self, -1, size=(60,20))
643        self.chi2_ctl.SetEditable(False)
644        self.chi2_ctl.SetToolTipString("Chi^2 over degrees of freedom.")
645       
646        # Oscillation parameter
647        self.osc_ctl = wx.TextCtrl(self, -1, size=(60,20))
648        self.osc_ctl.SetEditable(False)
649        self.osc_ctl.SetToolTipString("Oscillation parameter. P(r) for a sphere has an oscillation parameter of 1.1.")
650       
651        # Positive fraction figure of merit
652        self.pos_ctl = wx.TextCtrl(self, -1, size=(60,20))
653        self.pos_ctl.SetEditable(False)
654        self.pos_ctl.SetToolTipString("Fraction of P(r) that is positive. Theoretically, P(r) is defined positive.")
655       
656        # 1-simga positive fraction figure of merit
657        self.pos_err_ctl = wx.TextCtrl(self, -1, size=(60,20))
658        self.pos_err_ctl.SetEditable(False)
659        message  = "Fraction of P(r) that is at least 1 standard deviation greater than zero.\n"
660        message += "This figure of merit tells you about the size of the P(r) errors.\n"
661        message += "If it is close to 1 and the other figures of merit are bad, consider changing "
662        message += "the maximum distance."
663        self.pos_err_ctl.SetToolTipString(message)
664       
665        sizer_res = wx.GridBagSizer(5,5)
666
667        iy = 0
668        sizer_res.Add(label_rg, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
669        sizer_res.Add(self.rg_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
670        sizer_res.Add(label_rg_unit,   (iy,2), (1,1), wx.RIGHT|wx.EXPAND, 15)
671        iy += 1
672        sizer_res.Add(label_iq0, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
673        sizer_res.Add(self.iq0_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
674        sizer_res.Add(label_iq0_unit,   (iy,2), (1,1), wx.RIGHT|wx.EXPAND, 15)
675        iy += 1
676        sizer_res.Add(label_bck, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
677        sizer_res.Add(self.bck_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
678        sizer_res.Add(label_bck_unit,   (iy,2), (1,1), wx.RIGHT|wx.EXPAND, 15)
679        iy += 1
680        sizer_res.Add(label_time, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
681        sizer_res.Add(self.time_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
682        sizer_res.Add(label_time_unit,   (iy,2), (1,1), wx.RIGHT|wx.EXPAND, 15)
683        iy += 1
684        sizer_res.Add(label_chi2, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
685        sizer_res.Add(self.chi2_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
686        iy += 1
687        sizer_res.Add(label_osc, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
688        sizer_res.Add(self.osc_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
689
690        iy += 1
691        sizer_res.Add(label_pos, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
692        sizer_res.Add(self.pos_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
693
694        iy += 1
695        sizer_res.Add(label_pos_err, (iy,0), (1,1), wx.LEFT|wx.EXPAND, 15)
696        sizer_res.Add(self.pos_err_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND, 15)
697
698        ressizer.Add(sizer_res, 0)
699        iy_vb += 1
700        vbox.Add(ressizer, (iy_vb,0), (1,1), wx.LEFT|wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
701
702        # ----- Buttons -----
703        id = wx.NewId()
704        button_OK = wx.Button(self, id, "Compute")
705        button_OK.SetToolTipString("Perform P(r) inversion.")
706        self.Bind(wx.EVT_BUTTON, self._on_invert, id = id)   
707       
708        id = wx.NewId()
709        button_Reset = wx.Button(self, id, "Reset")
710        button_Reset.SetToolTipString("Reset inversion parameters to default.")
711        self.Bind(wx.EVT_BUTTON, self._on_reset, id = id)   
712        #button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
713       
714        id = wx.NewId()
715        button_Save = wx.Button(self, id, "Save")
716        button_Save.SetToolTipString("Save the current P(r) work to file.")
717        self.Bind(wx.EVT_BUTTON, self._save_state, id = id)   
718       
719        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
720        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
721        sizer_button.Add(button_Save, 0, wx.LEFT|wx.ADJUST_MINSIZE, 10)
722        sizer_button.Add(button_Reset, 0, wx.LEFT|wx.ADJUST_MINSIZE, 10)
723        sizer_button.Add(button_OK, 0, wx.LEFT|wx.ADJUST_MINSIZE, 10)
724        #sizer_button.Add(button_Cancel, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)       
725        iy_vb += 1
726        vbox.Add(sizer_button, (iy_vb,0), (1,1), wx.EXPAND|wx.BOTTOM|wx.TOP|wx.RIGHT, 10)
727
728        self.Bind(wx.EVT_TEXT_ENTER, self._on_invert)
729
730        self.SetSizer(vbox)
731       
732    def _on_accept_alpha(self, evt):
733        """
734            User has accepted the estimated alpha,
735            set it as part of the input parameters
736        """
737        try:
738            alpha = self.alpha_estimate_ctl.GetLabel()
739            tmp = float(alpha)
740            self.alpha_ctl.SetValue(alpha)
741        except:
742            # No estimate or bad estimate, either do nothing
743            import sys
744            print "InversionControl._on_accept_alpha: %s" % sys.exc_value
745            pass
746   
747    def _on_accept_nterms(self, evt):
748        """
749            User has accepted the estimated number of terms,
750            set it as part of the input parameters
751        """
752        try:
753            nterms = self.nterms_estimate_ctl.GetLabel()
754            tmp = float(nterms)
755            self.nfunc_ctl.SetValue(nterms)
756        except:
757            # No estimate or bad estimate, either do nothing
758            import sys
759            print "InversionControl._on_accept_nterms: %s" % sys.exc_value
760            pass
761       
762    def _on_reset(self, evt):
763        """
764            Resets inversion parameters
765        """
766        self.nfunc = self.manager.DEFAULT_NFUNC
767        self.d_max = self.manager.DEFAULT_DMAX
768        self.alpha = self.manager.DEFAULT_ALPHA
769        self.qmin_ctl.SetValue("")
770        self.qmax_ctl.SetValue("")
771        self.time_ctl.SetValue("")
772        self.rg_ctl.SetValue("")
773        self.iq0_ctl.SetValue("")
774        self.bck_ctl.SetValue("")
775        self.chi2_ctl.SetValue("")
776        self.osc_ctl.SetValue("")
777        self.pos_ctl.SetValue("")
778        self.pos_err_ctl.SetValue("")
779        self.alpha_estimate_ctl.Enable(False)
780        self.alpha_estimate_ctl.SetLabel("")
781        self.nterms_estimate_ctl.Enable(False)
782        self.nterms_estimate_ctl.SetLabel("")
783        self._on_pars_changed()
784       
785    def _on_pars_changed(self, evt=None):
786        """
787            Called when an input parameter has changed
788            We will estimate the alpha parameter behind the
789            scenes.
790        """
791        flag, alpha, dmax, nfunc, qmin, qmax, height, width = self._read_pars()
792        has_bck = self.bck_chk.IsChecked()
793       
794        # If the pars are valid, estimate alpha
795        if flag:
796            self.nterms_estimate_ctl.Enable(False)
797            self.alpha_estimate_ctl.Enable(False)
798           
799            dataset = self.plot_data.GetValue()
800            self.manager.estimate_plot_inversion(alpha=alpha, nfunc=nfunc, 
801                                                 d_max=dmax,
802                                                 q_min=qmin, q_max=qmax,
803                                                 bck=has_bck, 
804                                                 height=height,
805                                                 width=width)
806       
807    def _read_pars(self, evt=None):   
808        alpha = 0
809        nfunc = 5
810        dmax  = 120
811        qmin  = 0
812        qmax  = 0
813        height = 0
814        width  = 0
815       
816        flag = True
817       
818       
819        # Read slit height
820        try:
821            height_str = self.sheight_ctl.GetValue()
822            if len(height_str.lstrip().rstrip())==0:
823                height = 0
824            else:
825                height = float(height_str)
826                self.sheight_ctl.SetBackgroundColour(wx.WHITE)
827                self.sheight_ctl.Refresh()
828        except:
829            flag = False
830            self.sheight_ctl.SetBackgroundColour("pink")
831            self.sheight_ctl.Refresh()
832           
833        # Read slit width
834        try:
835            width_str = self.swidth_ctl.GetValue()
836            if len(width_str.lstrip().rstrip())==0:
837                width = 0
838            else:
839                width = float(width_str)
840                self.swidth_ctl.SetBackgroundColour(wx.WHITE)
841                self.swidth_ctl.Refresh()
842        except:
843            flag = False
844            self.swidth_ctl.SetBackgroundColour("pink")
845            self.swidth_ctl.Refresh()
846       
847        # Read alpha
848        try:
849            alpha = float(self.alpha_ctl.GetValue())
850            self.alpha_ctl.SetBackgroundColour(wx.WHITE)
851            self.alpha_ctl.Refresh()
852        except:
853            flag = False
854            self.alpha_ctl.SetBackgroundColour("pink")
855            self.alpha_ctl.Refresh()
856       
857        # Read d_max   
858        try:
859            dmax = float(self.dmax_ctl.GetValue())
860            self.dmax_ctl.SetBackgroundColour(wx.WHITE)
861            self.dmax_ctl.Refresh()
862        except:
863            flag = False
864            self.dmax_ctl.SetBackgroundColour("pink")
865            self.dmax_ctl.Refresh()
866           
867        # Read nfunc
868        try:
869            nfunc = int(self.nfunc_ctl.GetValue())
870            npts = self.manager.get_npts()
871            if npts>0 and nfunc>npts:
872                message = "Number of function terms should be smaller than the number of points"
873                wx.PostEvent(self.manager.parent, StatusEvent(status=message))
874                raise ValueError, message
875            self.nfunc_ctl.SetBackgroundColour(wx.WHITE)
876            self.nfunc_ctl.Refresh()
877        except:
878            flag = False
879            self.nfunc_ctl.SetBackgroundColour("pink")
880            self.nfunc_ctl.Refresh()
881       
882        # Read qmin
883        try:
884            qmin_str = self.qmin_ctl.GetValue()
885            if len(qmin_str.lstrip().rstrip())==0:
886                qmin = None
887            else:
888                qmin = float(qmin_str)
889                self.qmin_ctl.SetBackgroundColour(wx.WHITE)
890                self.qmin_ctl.Refresh()
891        except:
892            flag = False
893            self.qmin_ctl.SetBackgroundColour("pink")
894            self.qmin_ctl.Refresh()
895       
896        # Read qmax
897        try:
898            qmax_str = self.qmax_ctl.GetValue()
899            if len(qmax_str.lstrip().rstrip())==0:
900                qmax = None
901            else:
902                qmax = float(qmax_str)
903                self.qmax_ctl.SetBackgroundColour(wx.WHITE)
904                self.qmax_ctl.Refresh()
905        except:
906            flag = False
907            self.qmax_ctl.SetBackgroundColour("pink")
908            self.qmax_ctl.Refresh()
909       
910        return flag, alpha, dmax, nfunc, qmin, qmax, height, width
911   
912    def _on_explore(self, evt):
913        """
914            Invoke the d_max exploration dialog
915        """
916        from explore_dialog import ExploreDialog
917        if self.manager._last_pr is not None:
918            pr = self.manager._create_plot_pr()
919            dialog = ExploreDialog(pr, 10, None, -1, "")
920            dialog.ShowModal()
921        else:
922            message = "No data to analyze. Please load a data set to proceed."
923            wx.PostEvent(self.manager.parent, StatusEvent(status=message))
924           
925    def _on_invert(self, evt):
926        """
927            Perform inversion
928            @param silent: when True, there will be no output for the user
929        """
930        # Get the data from the form
931        # Push it to the manager
932       
933        flag, alpha, dmax, nfunc, qmin, qmax, height, width = self._read_pars()
934        has_bck = self.bck_chk.IsChecked()
935       
936        if flag:
937            dataset = self.plot_data.GetValue()
938            if len(dataset.strip())==0:
939                message = "No data to invert. Select a data set before proceeding with P(r) inversion."
940                wx.PostEvent(self.manager.parent, StatusEvent(status=message))
941            else:
942                self.manager.setup_plot_inversion(alpha=alpha, nfunc=nfunc, 
943                                                  d_max=dmax,
944                                                  q_min=qmin, q_max=qmax,
945                                                  bck=has_bck,
946                                                  height=height,
947                                                  width=width)
948        else:
949            message = "The P(r) form contains invalid values: please submit it again."
950            wx.PostEvent(self.parent, StatusEvent(status=message))
951       
952    def _change_file(self, evt=None, filepath=None):
953        """
954            Choose a new input file for I(q)
955        """
956        import os
957        if not self.manager==None:
958            path = self.manager.choose_file(path=filepath)
959           
960            if path and os.path.isfile(path):
961                self.plot_data.SetValue(str(path))
962                try:
963                    self.manager.show_data(path, reset=True)
964                    self._on_pars_changed(None)
965               
966                    # Perform inversion
967                    if self.standalone == True:
968                        self._on_invert(None)
969                except:
970                    # Invalid data
971                    logging.error("InversionControl._change_file: %s" % sys.exc_value)                   
972
973class HelpDialog(wx.Dialog):
974    def __init__(self, parent, id):
975        from sans.pr.invertor import help
976        wx.Dialog.__init__(self, parent, id, size=(400, 420))
977        self.SetTitle("P(r) help") 
978       
979
980        vbox = wx.BoxSizer(wx.VERTICAL)
981
982        explanation = help()
983           
984        label_explain = wx.StaticText(self, -1, explanation, size=(350,320))
985           
986        vbox.Add(label_explain, 0, wx.ALL|wx.EXPAND, 15)
987
988
989        static_line = wx.StaticLine(self, -1)
990        vbox.Add(static_line, 0, wx.EXPAND, 0)
991       
992        button_OK = wx.Button(self, wx.ID_OK, "OK")
993        #button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
994       
995        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
996        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
997        sizer_button.Add(button_OK, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
998        #sizer_button.Add(button_Cancel, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)       
999        vbox.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
1000
1001        self.SetSizer(vbox)
1002        self.SetAutoLayout(True)
1003       
1004        self.Layout()
1005        self.Centre()
1006
1007class PrDistDialog(wx.Dialog):
1008    """
1009        Property dialog to let the user change the number
1010        of points on the P(r) plot.
1011    """
1012    def __init__(self, parent, id):
1013        from sans.pr.invertor import help
1014        wx.Dialog.__init__(self, parent, id, size=(250, 120))
1015        self.SetTitle("P(r) distribution") 
1016       
1017
1018        vbox = wx.BoxSizer(wx.VERTICAL)
1019       
1020        label_npts = wx.StaticText(self, -1, "Number of points")
1021        self.npts_ctl = wx.TextCtrl(self, -1, size=(100,20))
1022                 
1023        pars_sizer = wx.GridBagSizer(5,5)
1024        iy = 0
1025        pars_sizer.Add(label_npts,      (iy,0), (1,1), wx.LEFT, 15)
1026        pars_sizer.Add(self.npts_ctl,   (iy,1), (1,1), wx.RIGHT, 0)
1027       
1028        vbox.Add(pars_sizer, 0, wx.ALL|wx.EXPAND, 15)
1029
1030
1031        static_line = wx.StaticLine(self, -1)
1032        vbox.Add(static_line, 0, wx.EXPAND, 0)
1033       
1034        button_OK = wx.Button(self, wx.ID_OK, "OK")
1035        self.Bind(wx.EVT_BUTTON, self._checkValues, button_OK)
1036        button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
1037       
1038        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
1039        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1040        sizer_button.Add(button_OK, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
1041        sizer_button.Add(button_Cancel, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)       
1042        vbox.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
1043
1044        self.SetSizer(vbox)
1045        self.SetAutoLayout(True)
1046       
1047        self.Layout()
1048        self.Centre()
1049
1050    def _checkValues(self, event):
1051        """
1052            Check the dialog content.
1053        """
1054        flag = True
1055        try:
1056            int(self.npts_ctl.GetValue())
1057            self.npts_ctl.SetBackgroundColour(wx.WHITE)
1058            self.npts_ctl.Refresh()
1059        except:
1060            flag = False
1061            self.npts_ctl.SetBackgroundColour("pink")
1062            self.npts_ctl.Refresh()
1063        if flag:
1064            event.Skip(True)
1065
1066    def get_content(self):
1067        """
1068            Return the content of the dialog.
1069            At this point the values have already been
1070            checked.
1071        """
1072        value = int(self.npts_ctl.GetValue())
1073        return value
1074   
1075    def set_content(self, npts):
1076        """
1077            Initialize the content of the dialog.
1078        """
1079        self.npts_ctl.SetValue("%i" % npts)
1080
1081
1082class ParsDialog(wx.Panel):
1083    """
1084        Dialog box to let the user edit detector settings
1085    """
1086   
1087    def __init__(self, parent, id = id, file=True, **kwargs):
1088
1089        wx.Panel.__init__(self, parent, id = id, **kwargs)
1090        self.file = file
1091       
1092        self.label_nfunc = wx.StaticText(self, -1, "Number of terms")
1093        self.label_alpha = wx.StaticText(self, -1, "Regularization constant")
1094        self.label_dmax  = wx.StaticText(self, -1, "Max distance [A]")
1095       
1096        # Npts, q max
1097        self.nfunc_ctl = wx.TextCtrl(self, -1, size=(60,20))
1098        self.alpha_ctl = wx.TextCtrl(self, -1, size=(60,20))
1099        self.dmax_ctl  = wx.TextCtrl(self, -1, size=(60,20))
1100
1101        self.label_file = None
1102        self.file_ctl   = None
1103
1104        self.static_line_3 = wx.StaticLine(self, -1)
1105       
1106       
1107
1108        self.__do_layout()
1109
1110        self.Fit()
1111       
1112    def _load_file(self, evt):
1113        import os
1114        path = None
1115        dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.txt", wx.OPEN)
1116        if dlg.ShowModal() == wx.ID_OK:
1117            path = dlg.GetPath()
1118            mypath = os.path.basename(path)
1119        dlg.Destroy()
1120       
1121        if path and os.path.isfile(path):
1122            self.file_ctl.SetValue(str(path))
1123
1124       
1125    def checkValues(self, event):
1126        flag = True
1127        try:
1128            float(self.alpha_ctl.GetValue())
1129            self.alpha_ctl.SetBackgroundColour(wx.WHITE)
1130            self.alpha_ctl.Refresh()
1131        except:
1132            flag = False
1133            self.alpha_ctl.SetBackgroundColour("pink")
1134            self.alpha_ctl.Refresh()
1135           
1136        try:
1137            float(self.dmax_ctl.GetValue())
1138            self.dmax_ctl.SetBackgroundColour(wx.WHITE)
1139            self.dmax_ctl.Refresh()
1140        except:
1141            flag = False
1142            self.dmax_ctl.SetBackgroundColour("pink")
1143            self.dmax_ctl.Refresh()
1144           
1145        try:
1146            int(self.nfunc_ctl.GetValue())
1147            self.nfunc_ctl.SetBackgroundColour(wx.WHITE)
1148            self.nfunc_ctl.Refresh()
1149        except:
1150            flag = False
1151            self.nfunc_ctl.SetBackgroundColour("pink")
1152            self.nfunc_ctl.Refresh()
1153       
1154        if flag:
1155            event.Skip(True)
1156   
1157    def setContent(self, nfunc, alpha, dmax, file):
1158        self.nfunc_ctl.SetValue(str(nfunc))
1159        self.alpha_ctl.SetValue(str(alpha))
1160        self.dmax_ctl.SetValue(str(dmax))
1161        if self.file:
1162            self.file_ctl.SetValue(str(file))
1163
1164    def getContent(self):
1165        nfunc = int(self.nfunc_ctl.GetValue())
1166        alpha = float(self.alpha_ctl.GetValue())
1167        dmax = float(self.dmax_ctl.GetValue())
1168        file = None
1169        if self.file:
1170            file = self.file_ctl.GetValue()
1171        return nfunc, alpha, dmax, file
1172
1173
1174    def __do_layout(self):
1175        sizer_main = wx.BoxSizer(wx.VERTICAL)
1176        sizer_params = wx.GridBagSizer(5,5)
1177
1178        iy = 0
1179        sizer_params.Add(self.label_nfunc, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1180        sizer_params.Add(self.nfunc_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1181        iy += 1
1182        sizer_params.Add(self.label_alpha, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1183        sizer_params.Add(self.alpha_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1184        iy += 1
1185        sizer_params.Add(self.label_dmax, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1186        sizer_params.Add(self.dmax_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1187        iy += 1
1188        if self.file:
1189            self.label_file  = wx.StaticText(self, -1, "Input file")
1190            self.file_ctl  = wx.TextCtrl(self, -1, size=(120,20))
1191            sizer_params.Add(self.label_file, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1192            sizer_params.Add(self.file_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1193
1194        sizer_main.Add(sizer_params, 0, wx.EXPAND|wx.ALL, 10)
1195       
1196       
1197        if self.file:
1198            sizer_button = wx.BoxSizer(wx.HORIZONTAL)
1199            self.button_load = wx.Button(self, 1, "Choose file")
1200            self.Bind(wx.EVT_BUTTON, self._load_file, id = 1)       
1201            sizer_button.Add(self.button_load, 0, wx.LEFT|wx.ADJUST_MINSIZE, 10)
1202       
1203       
1204            sizer_main.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
1205        self.SetAutoLayout(True)
1206        self.SetSizer(sizer_main)
1207        self.Layout()
1208        self.Centre()
1209        # end wxGlade
1210
1211
1212# end of class DialogAbout
1213
1214##### testing code ############################################################
1215class TestPlot:
1216    def __init__(self, text):
1217        self.name = text
1218   
1219class MyApp(wx.App):
1220    def OnInit(self):
1221        wx.InitAllImageHandlers()
1222        dialog = PrDistDialog(None, -1)
1223        if dialog.ShowModal() == wx.ID_OK:
1224            pass
1225        dialog.Destroy()
1226       
1227        return 1
1228
1229# end of class MyApp
1230
1231if __name__ == "__main__":
1232    app = MyApp(0)
1233    app.MainLoop()
1234   
1235##### end of testing code #####################################################   
Note: See TracBrowser for help on using the repository browser.