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

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 ae61fa5 was 047ed70, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

Remove the dispersioon option until the rest of the code is ready

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