source: sasview/prview/perspectives/pr/inversion_panel.py @ 5cc847c

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

prview: slightly better error handling

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