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

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

prview: minor change to load saved inversions as a separate (time-stamped) problem and avoid confusion with data set that was previously loaded.

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