source: sasview/prview/perspectives/pr/inversion_panel.py @ 4318af7f

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

Improvements for Mac

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