source: sasview/sansview/perspectives/fitting/modelpage.py @ 0b99881

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

working opn refactoring files

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