source: sasview/prview/perspectives/pr/inversion_panel.py @ 1c8015f

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 1c8015f was d2ee6f6, checked in by Mathieu Doucet <doucetm@…>, 15 years ago

prview: added setup script to install pr perspective as module. Modified perspective for use in SansView? (see standalone mode).

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