source: sasview/sansview/perspectives/fitting/modelpage.py @ 07a93a1

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

sansview: fixed problem with switching back and forth between dispersity and no dispersity

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