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

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 fbc3e04 was fbc3e04, checked in by Gervaise Alina <gervyh@…>, 15 years ago

go back to version 1617 for fitpage1D and modelpage.py

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