source: sasview/prview/perspectives/pr/inversion_panel.py @ 675e0ab

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

prview: completed first cut of functionality to save a P(r) inversion. Need to iron out the file format.

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