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

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 bf495e5 was 4c65725, checked in by Gervaise Alina <gervyh@…>, 13 years ago

remove unwanted space for Rg textctrl tested value

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