source: sasview/prview/perspectives/pr/inversion_panel.py @ bd66af34

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 bd66af34 was 91128648, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

prview: extending the module to add flexibility necessary for SansView?. Adding compatibility with CanSAS format when saving a P(r) fit result to file.

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