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

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

some changes of sansview review

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