source: sasview/sansview/perspectives/fitting/modelpage.py @ a90b37f

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

Fixed dispersion problems

  • Property mode set to 100644
File size: 39.6 KB
Line 
1import sys
2import wx
3import wx.lib
4import numpy
5import copy
6import math
7from sans.models.dispersion_models import ArrayDispersion, GaussianDispersion
8
9from sans.guicomm.events import StatusEvent   
10from sans.guiframe.utils import format_number
11(ModelEventbox, EVT_MODEL_BOX) = wx.lib.newevent.NewEvent()
12_BOX_WIDTH = 80
13
14
15
16
17class ModelPage(wx.ScrolledWindow):
18    """
19        FitPanel class contains fields allowing to display results when
20        fitting  a model and one data
21        @note: For Fit to be performed the user should check at least one parameter
22        on fit Panel window.
23 
24    """
25    ## Internal name for the AUI manager
26    window_name = "Fit page"
27    ## Title to appear on top of the window
28    window_caption = "Fit Page"
29    name=""
30    def __init__(self, parent,model,name, *args, **kwargs):
31        wx.ScrolledWindow.__init__(self, parent, *args, **kwargs)
32        """
33            Initialization of the Panel
34        """
35        # model on which the fit would be performed
36        self.model=model
37        # Data member to store the dispersion object created
38        self._disp_obj_dict = {}
39        self.back_up_model= model.clone()
40        #list of dispersion paramaters
41        self.disp_list=[]
42        try:
43            self.disp_list=self.model.getDispParamList()
44        except:
45            pass 
46        self.manager = None
47        self.parent  = parent
48        self.event_owner = None
49        # this panel does contain data .existing data allow a different drawing
50        #on set_model parameters
51        self.data=None
52        #panel interface
53        self.vbox  = wx.BoxSizer(wx.VERTICAL)
54        self.sizer11 = wx.BoxSizer(wx.HORIZONTAL)
55        #self.sizer10 = wx.GridBagSizer(5,5)
56        self.sizer9 = wx.GridBagSizer(5,5)
57        self.sizer8 = wx.GridBagSizer(5,5)
58        self.sizer7 = wx.GridBagSizer(5,5)
59        self.sizer6 = wx.GridBagSizer(5,5)
60        self.sizer5 = wx.GridBagSizer(5,5)
61        self.sizer4 = wx.GridBagSizer(5,5)
62       
63        #model selection
64        self.vbox.Add(wx.StaticLine(self, -1), 0, wx.EXPAND, 0)
65        self.vbox.Add(self.sizer4)
66        #model description
67        self.vbox.Add(self.sizer11)
68        #model paramaters layer
69        self.vbox.Add(self.sizer5)
70        #polydispersion selected
71        self.vbox.Add(wx.StaticLine(self, -1), 0, wx.EXPAND, 0)
72        self.vbox.Add(self.sizer6)
73        #combox box for type of dispersion
74        self.vbox.Add(self.sizer7)
75        #dispersion parameters layer
76        self.vbox.Add(self.sizer8)
77        # plotting range
78        self.vbox.Add(self.sizer9)
79        #close layer
80        #self.vbox.Add(wx.StaticLine(self, -1), 0, wx.EXPAND, 0)
81        #self.vbox.Add(self.sizer10)
82       
83     
84        #------------------ sizer 4  draw------------------------ 
85       
86       
87        # define combox box
88        self.modelbox = wx.ComboBox(self, -1)
89         # preview selected model name
90        self.prevmodel_name=name
91        #print "model view prev_model",name
92        self.modelbox.SetValue(self.prevmodel_name)
93        #enable model 2D draw
94        self.enable2D= False
95        #filling sizer2
96        ix = 0
97        iy = 1
98        self.sizer4.Add(wx.StaticText(self,-1,'Model'),(iy,ix),(1,1)\
99                  , wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
100        ix += 1
101        self.sizer4.Add(self.modelbox,(iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
102        ix += 1
103        id = wx.NewId()
104        self.model_view =wx.Button(self,id,'View 2D')
105        self.model_view.Bind(wx.EVT_BUTTON, self.onModel2D,id=id)
106        self.model_view.SetToolTipString("View model in 2D")
107       
108        self.sizer4.Add(self.model_view,(iy,ix),(1,1),\
109                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
110       
111        self.model_view.Enable()
112        self.model_view.SetFocus()
113       
114        ix = 0
115        iy += 1
116        self.sizer4.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
117
118        #----------sizer6-------------------------------------------------
119        self.disable_disp = wx.RadioButton(self, -1, 'No', (10, 10), style=wx.RB_GROUP)
120        self.enable_disp = wx.RadioButton(self, -1, 'Yes', (10, 30))
121        self.Bind(wx.EVT_RADIOBUTTON, self.Set_DipersParam, id=self.disable_disp.GetId())
122        self.Bind(wx.EVT_RADIOBUTTON, self.Set_DipersParam, id=self.enable_disp.GetId())
123        ix= 0
124        iy=1
125        self.sizer6.Add(wx.StaticText(self,-1,'Polydispersity: '),(iy,ix),(1,1)\
126                  , wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
127        ix += 1
128        self.sizer6.Add(self.enable_disp ,(iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
129        ix += 1
130        self.sizer6.Add(self.disable_disp ,(iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
131        ix =0
132        iy+=1
133        self.sizer6.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 
134
135       
136        #---------sizer 9 draw----------------------------------------
137       
138         ## Q range
139        self.qmin_x= 0.001
140        self.qmax_x= 0.1
141        self.num_points= 100
142       
143       
144        self.qmin    = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20))
145        self.qmin.SetValue(format_number(self.qmin_x))
146        self.qmin.SetToolTipString("Minimun value of Q in linear scale.")
147        self.qmin.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
148        self.qmin.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter)
149     
150        self.qmax    = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20))
151        self.qmax.SetValue(format_number(self.qmax_x))
152        self.qmax.SetToolTipString("Maximum value of Q in linear scale.")
153        self.qmax.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
154        self.qmax.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter)
155     
156
157        self.npts    = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20))
158        self.npts.SetValue(format_number(self.num_points))
159        self.npts.SetToolTipString("Number of point to plot.")
160        self.npts.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
161        self.npts.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter)
162       
163        ix = 0
164        iy = 1 
165        self.sizer9.Add(wx.StaticText(self, -1, 'Plotting Range'),(iy, ix),(1,1),\
166                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
167        ix += 1 
168        self.sizer9.Add(wx.StaticText(self, -1, 'Min'),(iy, ix),(1,1),\
169                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
170        ix += 1
171        self.sizer9.Add(wx.StaticText(self, -1, 'Max'),(iy, ix),(1,1),\
172                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
173        ix += 1
174        self.sizer9.Add(wx.StaticText(self, -1, 'Npts'),(iy, ix),(1,1),\
175                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
176        ix = 0
177        iy += 1
178        self.sizer9.Add(wx.StaticText(self, -1, 'Q range'),(iy, ix),(1,1),\
179                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
180        ix += 1
181        self.sizer9.Add(self.qmin,(iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
182        ix += 1
183        self.sizer9.Add(self.qmax,(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
184        ix += 1
185        self.sizer9.Add(self.npts,(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
186       
187        ix =0
188        iy+=1 
189        self.sizer9.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
190        #----------sizer 10 draw------------------------------------------------------
191        """
192        id = wx.NewId()
193        self.btClose =wx.Button(self,id,'Close')
194        self.btClose.Bind(wx.EVT_BUTTON, self.onClose,id=id)
195        self.btClose.SetToolTipString("Close page.")
196       
197        ix= 3
198        iy= 1
199        self.sizer10.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
200        ix +=1
201        self.sizer10.Add( self.btClose,(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
202        ix =0
203        iy+=1
204        self.sizer10.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
205        """
206        # contains link between  model ,all its parameters, and panel organization
207        self.parameters=[]
208        self.fixed_param=[]
209        self.fittable_param=[]
210        self.polydisp= {}
211        #contains link between a model and selected parameters to fit
212        self.param_toFit=[]
213       
214        #dictionary of model name and model class
215        self.model_list_box={}
216        #Draw initial panel
217         #-----sizer 11--------------------model description------
218        if self.model!=None:
219            self.set_panel(self.model)
220        self.theta_cb=None
221       
222       
223        self.vbox.Layout()
224        self.vbox.Fit(self) 
225        self.SetSizer(self.vbox)
226        self.SetScrollbars(20,20,55,40)
227       
228        self.Centre()
229        self.Layout()
230        self.parent.GetSizer().Layout()
231    def set_model_description(self, model):
232       
233        if model !=None and str(model.description)!=""and self.data==None:
234            self.sizer11.Clear(True)
235            self.box_description= wx.StaticBox(self, -1, 'Model Description')
236            boxsizer1 = wx.StaticBoxSizer(self.box_description, wx.VERTICAL)
237            boxsizer1.SetMinSize((320,20))
238            self.description = wx.StaticText(self,-1,str(model.description))
239            boxsizer1.Add(self.description, 0, wx.EXPAND) 
240            self.sizer11.Add(boxsizer1,1, wx.EXPAND | wx.ALL, 2)
241     
242       
243    def set_owner(self,owner):
244        """
245            set owner of fitpage
246            @param owner: the class responsible of plotting
247        """
248        self.event_owner=owner   
249   
250 
251    def set_manager(self, manager):
252        """
253             set panel manager
254             @param manager: instance of plugin fitting
255        """
256        self.manager = manager 
257       
258    def populate_box(self, dict):
259        """
260            Populate each combox box of each page
261            @param page: the page to populate
262        """
263        id=0
264        self.model_list_box=dict
265        list_name=[]
266        for item in  self.model_list_box.itervalues():
267            name = item.__name__
268            if hasattr(item, "name"):
269                name = item.name
270            list_name.append(name)
271        list_name.sort() 
272         
273        for name in list_name:
274            self.modelbox.Insert(name,int(id))
275            id+=1
276        wx.EVT_COMBOBOX(self.modelbox,-1, self._on_select_model) 
277        return 0
278   
279
280    def Set_DipersParam(self, event):
281        if self.enable_disp.GetValue():
282            if len(self.disp_list)==0:
283                ix=0
284                iy=1
285                self.fittable_param=[]
286                self.fixed_param=[]
287                self.sizer8.Clear(True)
288                model_disp = wx.StaticText(self, -1, 'No PolyDispersity for this model')
289                self.sizer7.Add(model_disp,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
290                self.vbox.Layout()
291                self.SetScrollbars(20,20,55,40)
292                self.Layout()
293                self.parent.GetSizer().Layout()
294                return 
295            else:
296                if self.data !=None and self.model !=None: # allow to recognize data panel from model panel
297                   
298               
299                    self.cb1.SetValue(False)
300                    self.select_all_param_helper()
301               
302                self.populate_disp_box()
303                self.set_panel_dispers(self.disp_list)
304               
305        else:
306            if self.data !=None and self.model!=None:
307                if self.cb1.GetValue():
308                    self.select_all_param_helper()
309           
310            if self.back_up_model!=None:
311                keys = self.back_up_model.getDispParamList()
312                keys.sort()
313                #disperse param into the initial state
314                for item in keys:
315                    value= self.back_up_model.getParam(item)
316                    self.model.setParam(item, value)
317                self._draw_model() 
318           
319               
320            self.fittable_param=[]       
321            self.fixed_param=[]
322            self.sizer7.Clear(True)
323            self.sizer8.Clear(True)
324            self.vbox.Layout()
325            self.SetScrollbars(20,20,55,40)
326            self.Layout()
327            self.parent.GetSizer().Layout()
328           
329    def populate_disp_box(self):
330        self.sizer7.Clear(True)
331        if len(self.disp_list)>0:
332            ix=0
333            iy=1
334            model_disp = wx.StaticText(self, -1, 'Model Disp')
335            self.sizer7.Add(model_disp,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
336            ix += 1 
337            # set up the combox box
338            id = 0
339            import sans.models.dispersion_models 
340            self.polydisp= sans.models.dispersion_models.models
341            self.disp_box = wx.ComboBox(self, -1)
342            self.disp_box.SetValue("GaussianModel")
343            for k,v in self.polydisp.iteritems():
344                if str(v)=="MyModel":
345                    self.disp_box.Insert("Select customized Model",id) 
346                else:
347                    self.disp_box.Insert(str(v),id) 
348                   
349                id+=1
350            wx.EVT_COMBOBOX(self.disp_box,-1, self._on_select_Disp) 
351            self.sizer7.Add(self.disp_box,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
352            self.vbox.Layout()
353            self.SetScrollbars(20,20,55,40)
354            self.Layout()
355            self.parent.GetSizer().Layout() 
356           
357           
358    def set_range(self, qmin_x, qmax_x, npts):
359        """
360            Set the range for the plotted models
361            @param qmin: minimum Q
362            @param qmax: maximum Q
363            @param npts: number of Q bins
364        """
365        # Set the data members
366        self.qmin_x = qmin_x
367        self.qmax_x = qmax_x
368        self.num_points = npts
369       
370        # Set the controls
371        self.qmin.SetValue(format_number(self.qmin_x))
372        self.qmax.SetValue(format_number(self.qmax_x))
373        self.npts.SetValue(format_number(self.num_points))
374    def checkFitRange(self):
375        """
376            Check the validity of fitting range
377            @note: qmin should always be less than qmax or else each control box
378            background is colored in pink.
379        """
380       
381        flag = True
382        valueMin = self.qmin.GetValue()
383        valueMax = self.qmax.GetValue()
384        # Check for possible values entered
385        #print "fitpage: checkfitrange:",valueMin,valueMax
386        try:
387            if (float(valueMax)> float(valueMin)):
388                self.qmax.SetBackgroundColour(wx.WHITE)
389                self.qmin.SetBackgroundColour(wx.WHITE)
390            else:
391                flag = False
392                self.qmin.SetBackgroundColour("pink")
393                self.qmax.SetBackgroundColour("pink")     
394        except:
395            flag = False
396            self.qmin.SetBackgroundColour("pink")
397            self.qmax.SetBackgroundColour("pink")
398           
399        self.qmin.Refresh()
400        self.qmax.Refresh()
401        return flag
402   
403
404       
405    def onClose(self,event):
406        """ close the page associated with this panel"""
407        self.parent.onClose()
408       
409 
410       
411    def onModel2D(self, event):
412        """
413         call manager to plot model in 2D
414        """
415        # If the 2D display is not currently enabled, plot the model in 2D
416        # and set the enable2D flag.
417        if self.enable2D==False:
418            self.enable2D=True
419            self._draw_model()
420            self.model_view.Disable()
421           
422   
423    def select_model(self, model, name):
424        """
425            Select a new model
426            @param model: model object
427        """
428        self.model = model
429        self.parent.model_page.name = name
430        self.parent.draw_model_name = name
431       
432        self.set_panel(model)
433        self._draw_model(name)
434       
435        # Select the model from the combo box
436        items = self.modelbox.GetItems()
437        for i in range(len(items)):
438            if items[i]==name:
439                self.modelbox.SetSelection(i)
440                self.model_view.SetFocus()
441               
442    def _on_select_Disp(self,event):
443        """
444             allow selecting different dispersion
445             self.disp_list should change type later .now only gaussian
446        """
447        type =event.GetString()
448        self.set_panel_dispers( self.disp_list,type )
449               
450    def _on_select_model(self,event):
451        """
452            react when a model is selected from page's combo box
453            post an event to its owner to draw an appropriate theory
454        """
455        self.disable_disp.SetValue(True)
456        self.sizer8.Clear(True)
457        self.sizer7.Clear(True)       
458        self.vbox.Layout()
459        self.SetScrollbars(20,20,55,40)
460        self.Layout()
461        self.parent.GetSizer().Layout()
462        for item in self.model_list_box.itervalues():
463            name = item.__name__
464            if hasattr(item, "name"):
465                name = item.name
466            if name ==event.GetString():
467                model=item()
468                self.model= model
469                self.set_panel(model)
470                self.name= name
471                self.model_view.SetFocus()
472                self.parent.model_page.name=name
473                self.parent.draw_model_name=name
474               
475                self._draw_model(name)
476           
477           
478    def get_model_box(self): 
479        """ return reference to combox box self.model"""
480        return self.modelbox
481
482   
483    def get_param_list(self):
484        """
485            @return self.param_toFit: list containing  references to TextCtrl
486            checked.Theses TextCtrl will allow reference to parameters to fit.
487            @raise: if return an empty list of parameter fit will nnote work
488            properly so raise ValueError,"missing parameter to fit"
489        """
490        if self.param_toFit !=[]:
491            return self.param_toFit
492        else:
493            raise ValueError,"missing parameter to fit"
494       
495       
496    def set_panel(self,model):
497        """
498            Build the panel from the model content
499            @param model: the model selected in combo box for fitting purpose
500        """
501       
502        self.sizer5.Clear(True)
503        self.parameters = []
504        self.param_toFit=[]
505        self.fixed_param=[]
506        self.model = model
507       
508        self.set_model_description( self.model) 
509       
510        keys = self.model.getParamList()
511        #list of dispersion paramaters
512        self.disp_list=self.model.getDispParamList()
513       
514        keys.sort()
515        ik=0
516        im=1
517       
518        iy = 1
519        ix = 0
520        self.cb1 = wx.CheckBox(self, -1,"Select all", (10, 10))
521        if self.data!=None:
522            wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param)
523            self.cb1.SetValue(False)
524        else:
525            self.cb1.Disable()
526            self.cb1.Hide()
527       
528        self.sizer5.Add(self.cb1,(iy, ix),(1,1),\
529                          wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
530        ix +=1
531        self.text2_2 = wx.StaticText(self, -1, 'Values')
532        self.sizer5.Add(self.text2_2,(iy, ix),(1,1),\
533                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
534        ix +=2
535        self.text2_3 = wx.StaticText(self, -1, 'Errors')
536        self.sizer5.Add(self.text2_3,(iy, ix),(1,1),\
537                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
538        self.text2_3.Hide() 
539       
540       
541        ix +=1
542        self.text2_4 = wx.StaticText(self, -1, 'Units')
543        self.sizer5.Add(self.text2_4,(iy, ix),(1,1),\
544                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
545        self.text2_4.Hide()
546        disp_list=self.model.getDispParamList()
547        for item in keys:
548            if not item in disp_list:
549                iy += 1
550                ix = 0
551   
552                cb = wx.CheckBox(self, -1, item, (10, 10))
553                if self.data!=None:
554                    cb.SetValue(False)
555                    wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
556                else:
557                    cb.Disable()
558                self.sizer5.Add( cb,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
559               
560                ix += 1
561                value= self.model.getParam(item)
562                ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
563                ctl1.SetValue(str (format_number(value)))
564                ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
565                ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
566                self.sizer5.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)
567               
568                ix += 1
569                text2=wx.StaticText(self, -1, '+/-')
570                self.sizer5.Add(text2,(iy, ix),(1,1),\
571                                wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
572                text2.Hide() 
573                ix += 1
574                ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
575                self.sizer5.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
576                ctl2.Hide()
577               
578                ix +=1
579                # Units
580                try:
581                    units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT)
582                except:
583                    units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT)
584                self.sizer5.Add(units, (iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
585           
586                self.parameters.append([cb,ctl1,text2,ctl2])
587               
588        iy+=1
589        self.sizer5.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
590       
591        #Display units text on panel
592        for item in keys:   
593            if self.model.details[item][0]!='':
594                self.text2_4.Show()
595                break
596            else:
597                self.text2_4.Hide()
598       
599        self.vbox.Layout()
600        self.SetScrollbars(20,20,55,40)
601        self.Layout()
602        self.parent.GetSizer().Layout()
603       
604       
605       
606    def _selectDlg(self):
607        import os
608        dlg = wx.FileDialog(self, "Choose a weight file", os.getcwd(), "", "*.*", wx.OPEN)
609        path = None
610        if dlg.ShowModal() == wx.ID_OK:
611            path = dlg.GetPath()
612        dlg.Destroy()
613        return path
614    def read_file(self, path):
615        try:
616            if path==None:
617                wx.PostEvent(self.parent.parent, StatusEvent(status=\
618                            " Selected Distribution was not loaded: %s"%path))
619                return None, None
620            input_f = open(path, 'r')
621            buff = input_f.read()
622            lines = buff.split('\n')
623           
624            angles = []
625            weights=[]
626            for line in lines:
627                toks = line.split()
628                if len(toks)==2:
629                    try:
630                        angle = float(toks[0])
631                        weight = float(toks[1])
632                    except:
633                        # Skip non-data lines
634                        pass
635                    angles.append(angle)
636                    weights.append(weight)
637            return numpy.array(angles), numpy.array(weights)
638        except:
639            raise 
640       
641         
642    def select_disp_angle(self, event): 
643        """
644            Event for when a user select a parameter to average over.
645            @param event: check box event
646        """
647       
648       
649        # Go through the list of dispersion check boxes to identify which one has changed
650        for p in self.disp_cb_dict:
651            # Catch which one of the box was just checked or unchecked.
652            if event.GetEventObject() == self.disp_cb_dict[p]:             
653
654               
655                if self.disp_cb_dict[p].GetValue() == True:
656                    # The user wants this parameter to be averaged.
657                    # Pop up the file selection dialog.
658                    path = self._selectDlg()
659                   
660                    # If nothing was selected, just return
661                    if path is None:
662                        self.disp_cb_dict[p].SetValue(False)
663                        return
664                   
665                    try:
666                        values,weights = self.read_file(path)
667                    except:
668                        wx.PostEvent(self.parent.parent, StatusEvent(status=\
669                            "Could not read input file"))
670                        return
671                   
672                    # If any of the two arrays is empty, notify the user that we won't
673                    # proceed
674                    if values is None or weights is None:
675                        wx.PostEvent(self.parent.parent, StatusEvent(status=\
676                            "The loaded %s distrubtion is corrupted or empty" % p))
677                        return
678                       
679                    # Tell the user that we are about to apply the distribution
680                    wx.PostEvent(self.parent.parent, StatusEvent(status=\
681                            "Applying loaded %s distribution: %s" % (p, path))) 
682                   
683                    # Create the dispersion objects
684                    disp_model = ArrayDispersion()
685                    disp_model.set_weights(values, weights)
686                    # Store the object to make it persist outside the scope of this method
687                    #TODO: refactor model to clean this up?
688                    self._disp_obj_dict[p] = disp_model
689                   
690                    # Set the new model as the dispersion object for the selected parameter
691                    self.model.set_dispersion(p, disp_model)
692                   
693                   
694                    # Redraw the model
695                    self._draw_model()
696                         
697                else:
698                    # The parameter was un-selected. Go back to Gaussian model (with 0 pts)
699                    disp_model = GaussianDispersion()
700                    # Store the object to make it persist outside the scope of this method
701                    #TODO: refactor model to clean this up?
702                    self._disp_obj_dict[p] = disp_model
703                   
704                    # Set the new model as the dispersion object for the selected parameter
705                    self.model.set_dispersion(p, disp_model)
706                   
707                    # Redraw the model
708                    self._draw_model()
709        return
710
711                     
712                     
713                     
714    def set_panel_dispers(self, disp_list, type="GaussianModel" ):
715        """
716        """
717       
718        self.fittable_param=[]
719        self.fixed_param=[]
720       
721        ix=0
722        iy=1
723                ### this will become a separate method
724        if type== "Select customized Model":
725            ix=0
726            iy=1
727            self.sizer8.Clear(True)       
728            disp1 = wx.StaticText(self, -1, 'Array Dispersion')
729            self.sizer8.Add(disp1,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
730           
731            # Look for model parameters to which we can apply an ArrayDispersion model
732            # Add a check box for each parameter.
733            self.disp_cb_dict = {}
734            for p in self.model.dispersion.keys():
735                ix+=1 
736                self.disp_cb_dict[p] = wx.CheckBox(self, -1, p, (10, 10))
737               
738                wx.EVT_CHECKBOX(self, self.disp_cb_dict[p].GetId(), self.select_disp_angle)
739                self.sizer8.Add(self.disp_cb_dict[p], (iy, ix), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
740           
741            ix =0
742            iy +=1 
743            self.sizer8.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)       
744            self.vbox.Layout()
745            self.SetScrollbars(20,20,55,40)
746            self.Layout()
747            self.parent.GetSizer().Layout() 
748           
749        if type== "GaussianModel" :
750
751            self.sizer8.Clear(True)
752            disp = wx.StaticText(self, -1, 'Dispersion')
753            self.sizer8.Add(disp,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
754            ix += 1 
755            values = wx.StaticText(self, -1, 'Values')
756            self.sizer8.Add(values,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
757            ix +=2
758            self.text2_3 = wx.StaticText(self, -1, 'Errors')
759            self.sizer8.Add(self.text2_3,(iy, ix),(1,1),\
760                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
761            self.text2_3.Hide() 
762           
763            ix += 1 
764            npts = wx.StaticText(self, -1, 'Npts')
765            self.sizer8.Add(npts,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
766            ix += 1 
767            nsigmas = wx.StaticText(self, -1, 'Nsigmas')
768            self.sizer8.Add(nsigmas,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
769           
770            disp_list.sort()
771            #print disp_list,self.model.dispersion
772            for item in self.model.dispersion.keys():
773                name1=item+".width"
774                name2=item+".npts"
775                name3=item+".nsigmas"
776                iy += 1
777                for p in self.model.dispersion[item].keys():
778                    #print "name 1 2 3", name1, name2, name3
779                    if p=="width":
780                        ix = 0
781                        cb = wx.CheckBox(self, -1, name1, (10, 10))
782                        if self.data !=None:
783                            cb.SetValue(False)
784                            wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
785                        else:
786                            cb.Disable()
787                        self.sizer8.Add( cb,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
788                        ix = 1
789                        value= self.model.getParam(name1)
790                        ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
791                        ctl1.SetValue(str (format_number(value)))
792                        ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
793                        ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
794                        self.sizer8.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)
795                       
796                        ix = 2
797                        text2=wx.StaticText(self, -1, '+/-')
798                        self.sizer8.Add(text2,(iy, ix),(1,1),\
799                                        wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
800                        text2.Hide() 
801                        ix = 3
802                        ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
803                        self.sizer8.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
804                        ctl2.Hide()
805                        self.fittable_param.append([cb,ctl1,text2,ctl2])
806                       
807                       
808                    elif p=="npts":
809                            ix =4 
810                            value= self.model.getParam(name2)
811                            Tctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER)
812                            Tctl.SetValue(str (format_number(value)))
813                            Tctl.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
814                            Tctl.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
815                            self.sizer8.Add(Tctl, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
816                            self.fixed_param.append([name2, Tctl])
817                    elif p=="nsigmas":
818                            ix =5 
819                            value= self.model.getParam(name3)
820                            Tctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER)
821                            Tctl.SetValue(str (format_number(value)))
822                            Tctl.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
823                            Tctl.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
824                            self.sizer8.Add(Tctl, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
825                            self.fixed_param.append([name3, Tctl])
826                wx.PostEvent(self.parent.parent, StatusEvent(status=\
827                            " Selected Distribution: Gaussian"))   
828            ix =0
829            iy +=1 
830            self.sizer8.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)       
831            self.vbox.Layout()
832            self.SetScrollbars(20,20,55,40)
833            self.Layout()
834            self.parent.GetSizer().Layout() 
835         
836    def checkFitValues(self,val_min, val_max):
837        """
838            Check the validity of input values
839        """
840        flag = True
841        min_value = val_min.GetValue()
842        max_value = val_max.GetValue()
843        # Check for possible values entered
844        if min_value.lstrip().rstrip() =="-inf":
845            min_value= -numpy.inf
846        if max_value.lstrip().rstrip() =="+inf":
847            max_value= numpy.inf
848        if  min_value==-numpy.inf and max_value== numpy.inf:
849            val_min.SetBackgroundColour(wx.WHITE)
850            val_min.Refresh()
851            val_max.SetBackgroundColour(wx.WHITE)
852            val_max.Refresh()
853            return flag
854        elif max_value== numpy.inf:
855            try:
856                float(min_value)
857                val_min.SetBackgroundColour(wx.WHITE)
858                val_min.Refresh()
859            except:
860                flag = False
861                val_min.SetBackgroundColour("pink")
862                val_min.Refresh()
863            return flag
864        elif min_value==-numpy.inf:
865            try:
866                float(max_value)
867                val_max.SetBackgroundColour(wx.WHITE)
868                val_max.Refresh()
869            except:
870                flag = False
871                val_max.SetBackgroundColour("pink")
872                val_max.Refresh()
873            return flag
874        else:   
875            if (float(min_value)< float(max_value)):
876                val_min.SetBackgroundColour(wx.WHITE)
877                val_min.Refresh()
878            else:
879                flag = False
880                val_min.SetBackgroundColour("pink")
881                val_min.Refresh()
882            return flag   
883           
884       
885    def _onparamEnter(self,event):
886        """
887            when enter value on panel redraw model according to changed
888        """
889        self.set_model_parameter()
890       
891    def set_model_parameter(self):
892        """
893        """
894        if len(self.parameters) !=0 and self.model !=None:
895            # Flag to register when a parameter has changed.
896            is_modified = False
897            for item in self.fittable_param:
898                try:
899                     name=str(item[0].GetLabelText())
900                     value= float(item[1].GetValue())
901                     # If the value of the parameter has changed,
902                     # update the model and set the is_modified flag
903                     if value != self.model.getParam(name):
904                         self.model.setParam(name,value)
905                         is_modified = True
906                         
907                except:
908                    #raise
909                    wx.PostEvent(self.parent.parent, StatusEvent(status=\
910                            "Model Drawing  Error:wrong value entered : %s"% sys.exc_value))
911                    return 
912               
913               
914            for item in self.fixed_param:
915                try:
916                     name=str(item[0])
917                     value= float(item[1].GetValue())
918                     # If the value of the parameter has changed,
919                     # update the model and set the is_modified flag
920                     if value != self.model.getParam(name):
921                         self.model.setParam(name,value)
922                         is_modified = True
923                         
924                except:
925                    raise
926                    wx.PostEvent(self.parent.parent, StatusEvent(status=\
927                            "Model Drawing  Error:wrong value entered : %s"% sys.exc_value))
928               
929            for item in self.parameters:
930                try:
931                     name=str(item[0].GetLabelText())
932                     value= float(item[1].GetValue())
933                     # If the value of the parameter has changed,
934                     # update the model and set the is_modified flag
935                     if value != self.model.getParam(name):
936                         self.model.setParam(name,value)
937                         is_modified = True
938                   
939                except:
940                    #raise
941                    wx.PostEvent(self.parent.parent, StatusEvent(status=\
942                           "Model Drawing  Error:wrong value entered : %s"% sys.exc_value))
943                    return
944               
945               
946            # Here we should check whether the boundaries have been modified.
947            # If qmin and qmax have been modified, update qmin and qmax and
948            # set the is_modified flag to True
949            if float(self.qmin.GetValue()) != self.qmin_x:
950                self.qmin_x = float(self.qmin.GetValue())
951                is_modified = True
952            if float(self.qmax.GetValue()) != self.qmax_x:
953                self.qmax_x = float(self.qmax.GetValue())
954                is_modified = True
955           
956            if float(self.npts.GetValue()) !=  self.num_points:
957                self.num_points = float(self.npts.GetValue())
958                is_modified = True
959         
960            if is_modified:
961                self._draw_model()           
962           
963    def _draw_model(self, name=None):
964        """
965            Method to draw or refresh a plotted model.
966            The method will use the data member from the model page
967            to build a call to the fitting perspective manager.
968           
969            [Note to coder: This way future changes will be done in only one place.]
970        """
971        if name==None:
972            name= self.model.name
973       
974        self.manager.draw_model(self.model, name, data=self.data,
975                                qmin=self.qmin_x, qmax=self.qmax_x,
976                                qstep= self.num_points,
977                                enable2D=self.enable2D)
978       
979    def select_param(self,event):
980        """
981       
982        """
983        pass
984    def select_all_param(self,event): 
985        """
986       
987        """
988        pass
989    def select_all_param_helper(self):
990        """
991             Allows selecting or delecting button
992        """
993        self.param_toFit=[]
994        if  self.parameters !=[]:
995            if  self.cb1.GetValue()==True:
996                for item in self.parameters:
997                    item[0].SetValue(True)
998                    list= [item[0],item[1],item[2],item[3]]
999                    self.param_toFit.append(list )
1000                if len(self.fittable_param)>0:
1001                    for item in self.fittable_param:
1002                        item[0].SetValue(True)
1003                        list= [item[0],item[1],item[2],item[3]]
1004                        self.param_toFit.append(list )
1005            else:
1006                for item in self.parameters:
1007                    item[0].SetValue(False)
1008                for item in self.fittable_param:
1009                    item[0].SetValue(False)
1010                self.param_toFit=[]
1011               
1012               
1013       
Note: See TracBrowser for help on using the repository browser.