source: sasview/prview/perspectives/pr/inversion_panel.py @ 6f1f129

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 6f1f129 was 5d98370, checked in by Mathieu Doucet <doucetm@…>, 15 years ago

prview: allow to save/load a pr inversion state. removed the load button from the panel.

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