source: sasview/sansview/perspectives/fitting/basepage.py @ 376916c

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

resettting gaussian dispersity —fixed
reducing access to molde multplication —-done as request

  • Property mode set to 100644
File size: 39.7 KB
Line 
1
2import sys
3import wx
4import numpy
5
6from sans.guiframe.utils import format_number
7from sans.guicomm.events import StatusEvent   
8
9_BOX_WIDTH = 80
10
11class BasicPage(wx.ScrolledWindow):
12    """
13        This class provide general structure of  fitpanel page
14    """
15    ## Internal name for the AUI manager
16    window_name = "Fit page"
17    ## Title to appear on top of the window
18    window_caption = "Fit Page"
19   
20    name=""
21   
22    def __init__(self,parent, pageinfo, name):
23        wx.ScrolledWindow.__init__(self, parent)
24        ## store name
25        self.name = name
26        ## store info of panel
27        self.page_info= pageinfo
28        self.page_info.page_name = name
29        ## parent of the page
30        self.parent = parent
31        ## owner of the page (fitting plugin)
32        self.event_owner= None
33        ## create the basic structure of the panel with empty sizer
34        self.define_page_structure()
35        ## dictionary containing list of models
36        self.model_list_box={}
37        ## Data member to store the dispersion object created
38        self._disp_obj_dict = {}
39        self.disp_cb_dict ={}
40        ##list of model parameters. each item must have same length
41        ## each item related to a given parameters
42        ##[cb state, name, value, "+/-", error of fit, min, max , units]
43        self.parameters=[]
44        ## list of parameters to fit , must be like self.parameters
45        self.param_toFit=[]
46        ## list of looking like parameters but with non fittable parameters info
47        self.fixed_param=[]
48        ## list of looking like parameters but with  fittable parameters info
49        self.fittable_param=[]
50        ##list of dispersion parameters
51        self.disp_list=[]
52       
53        ##enable model 2D draw
54        self.enable2D= False
55        ## check that the fit range is correct to plot the model again
56        self.fitrange= True
57        ## current model
58        self.model= None
59        ## data
60        self.data=None
61        ## Q range
62        self.qmin_x= 0.001
63        self.qmax_x= 0.1
64        self.num_points= 100
65        ## changing initial values given page_info value
66        if self.page_info !=None and len(self.page_info.model_list_box) >0:
67            self.model_list_box = self.page_info.model_list_box
68            ## current model
69            self.model=self.page_info.model
70            self.data = self.page_info.data
71            self.event_owner = self.page_info.event_owner
72           
73            if self.model !=None:
74                self.disp_list= self.model.getDispParamList()
75        ## drawing Initial dispersion parameters sizer
76        self.set_dispers_sizer()
77        self._fill_save_sizer()
78        ## layout
79        self.set_layout()
80       
81       
82    def define_page_structure(self):
83        """
84            Create empty sizer for a panel
85        """
86        self.vbox  = wx.BoxSizer(wx.VERTICAL)
87        self.sizer0 = wx.BoxSizer(wx.VERTICAL)
88        self.sizer1 = wx.BoxSizer(wx.VERTICAL)
89        self.sizer2 = wx.BoxSizer(wx.VERTICAL)
90        self.sizer3 = wx.BoxSizer(wx.VERTICAL)
91        self.sizer4 = wx.BoxSizer(wx.VERTICAL)
92        self.sizer5 = wx.BoxSizer(wx.VERTICAL)
93        self.sizer6 = wx.BoxSizer(wx.VERTICAL)
94       
95        self.sizer0.SetMinSize((375,-1))
96        self.sizer1.SetMinSize((375,-1))
97        self.sizer2.SetMinSize((375,-1))
98        self.sizer3.SetMinSize((375,-1))
99        self.sizer4.SetMinSize((375,-1))
100        self.sizer5.SetMinSize((375,-1))
101        self.sizer6.SetMinSize((375,-1))
102       
103        self.vbox.Add(self.sizer0)
104        self.vbox.Add(self.sizer1)
105        self.vbox.Add(self.sizer2)
106        self.vbox.Add(self.sizer3)
107        self.vbox.Add(self.sizer4)
108        self.vbox.Add(self.sizer5)
109        self.vbox.Add(self.sizer6)
110       
111    def set_layout(self):
112        """
113             layout
114        """
115        self.vbox.Layout()
116        self.vbox.Fit(self) 
117        self.SetSizer(self.vbox)
118       
119        self.set_scroll()
120        self.Centre()
121       
122    def set_scroll(self):
123        self.SetScrollbars(20,20,200,100)
124        self.Layout()   
125        self.SetAutoLayout(True)
126         
127    def set_owner(self,owner):
128        """
129            set owner of fitpage
130            @param owner: the class responsible of plotting
131        """
132        self.event_owner = owner   
133        self.page_info.event_owner = owner
134 
135    def set_manager(self, manager):
136        """
137             set panel manager
138             @param manager: instance of plugin fitting
139        """
140        self.manager = manager 
141        self.page_info.manager = manager
142       
143    def populate_box(self, dict):
144        """
145             Store list of model
146             @param dict: dictionary containing list of models
147        """
148        self.model_list_box = dict
149        if self.page_info!=None:
150            self.page_info.model_list_box = self.model_list_box
151           
152   
153       
154    def set_dispers_sizer(self):
155        """
156            fill sizer containing dispersity info
157        """
158        self.sizer4.Clear(True)
159        box_description= wx.StaticBox(self, -1,"PolyDispersity")
160        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
161        #----------------------------------------------------
162        self.disable_disp = wx.RadioButton(self, -1, 'No', (10, 10), style=wx.RB_GROUP)
163        self.enable_disp = wx.RadioButton(self, -1, 'Yes', (10, 30))
164        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, id=self.disable_disp.GetId())
165        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, id=self.enable_disp.GetId())
166       
167        sizer_dispersion = wx.BoxSizer(wx.HORIZONTAL)
168        sizer_dispersion.Add((20,20))
169        sizer_dispersion.Add(wx.StaticText(self,-1,'Polydispersity: '))
170        sizer_dispersion.Add(self.enable_disp )
171        sizer_dispersion.Add((20,20))
172        sizer_dispersion.Add(self.disable_disp )
173        sizer_dispersion.Add((10,10))
174       
175        ## fill a sizer with the combobox to select dispersion type
176        sizer_select_dispers = wx.BoxSizer(wx.HORIZONTAL) 
177        self.model_disp = wx.StaticText(self, -1, 'Model Disp')
178           
179        import sans.models.dispersion_models 
180        self.polydisp= sans.models.dispersion_models.models
181        self.disp_box = wx.ComboBox(self, -1)
182        self.disp_box.SetValue("GaussianModel")
183       
184        for key in self.polydisp.iterkeys():
185            name = str(key.__name__)
186            if name=="ArrayDispersion":
187                # Remove the option until the rest of the code is ready for it
188                self.disp_box.Append("Select customized Model",key)
189                pass 
190            else:
191                self.disp_box.Append(name,key) 
192        wx.EVT_COMBOBOX(self.disp_box,-1, self._on_select_Disp) 
193             
194        sizer_select_dispers.Add((10,10)) 
195        sizer_select_dispers.Add(self.model_disp) 
196        sizer_select_dispers.Add(self.disp_box) 
197        sizer_select_dispers.Add((10,10)) 
198        self.model_disp.Hide()
199        self.disp_box.Hide()
200       
201        boxsizer1.Add( sizer_dispersion )
202        boxsizer1.Add( (10,10) )
203        boxsizer1.Add( sizer_select_dispers )
204        self.sizer4_4 = wx.GridBagSizer(5,5)
205        boxsizer1.Add( self.sizer4_4  )
206        #-----------------------------------------------------
207        self.sizer4.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
208        self.sizer4.Layout()
209       
210        self.SetScrollbars(20,20,200,100)
211       
212   
213    def select_disp_angle(self, event): 
214        """
215            Event for when a user select a parameter to average over.
216            @param event: check box event
217        """
218       
219       
220        # Go through the list of dispersion check boxes to identify which one has changed
221        for p in self.disp_cb_dict:
222            # Catch which one of the box was just checked or unchecked.
223            if event.GetEventObject() == self.disp_cb_dict[p]:             
224
225               
226                if self.disp_cb_dict[p].GetValue() == True:
227                    # The user wants this parameter to be averaged.
228                    # Pop up the file selection dialog.
229                    path = self._selectDlg()
230                   
231                    # If nothing was selected, just return
232                    if path is None:
233                        self.disp_cb_dict[p].SetValue(False)
234                        return
235                   
236                    try:
237                        values,weights = self.read_file(path)
238                    except:
239                        msg="Could not read input file"
240                        wx.PostEvent(self.parent.parent, StatusEvent(status= msg))
241                        return
242                   
243                    # If any of the two arrays is empty, notify the user that we won't
244                    # proceed
245                    if values is None or weights is None:
246                        wx.PostEvent(self.parent.parent, StatusEvent(status=\
247                            "The loaded %s distrubtion is corrupted or empty" % p))
248                        return
249                       
250                    # Tell the user that we are about to apply the distribution
251                    wx.PostEvent(self.parent.parent, StatusEvent(status=\
252                            "Applying loaded %s distribution: %s" % (p, path))) 
253                   
254                    # Create the dispersion objects
255                    from sans.models.dispersion_models import ArrayDispersion
256                    disp_model = ArrayDispersion()
257                    disp_model.set_weights(values, weights)
258                    # Store the object to make it persist outside the scope of this method
259                    #TODO: refactor model to clean this up?
260                    self._disp_obj_dict[p] = disp_model
261                   
262                    # Set the new model as the dispersion object for the selected parameter
263                    self.model.set_dispersion(p, disp_model)
264                         
265                else:
266                    # The parameter was un-selected. Go back to Gaussian model (with 0 pts)
267                    self._reset_dispersity()
268                   
269                ## Redraw the model
270                self._draw_model()
271        return
272   
273    def onSave(self, event):
274        """
275            save history of the data and model
276        """
277        self.page_info.model= self.model
278        self.page_info.data = self.data
279        import os
280                 
281           
282        path = None
283        dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.txt", wx.SAVE)
284        if dlg.ShowModal() == wx.ID_OK:
285            path = dlg.GetPath()
286            mypath = os.path.basename(path)
287           
288        dlg.Destroy()
289           
290        if not path == None:
291            out = open(path, 'w')
292            has_data = self.data !=None
293            has_model = self.model!=None
294            import time
295            year, month, day,hour,minute,second,tda,ty,tm_isdst= time.gmtime()
296            import os.path
297            out.write("Title: State for %s\n"%os.path.basename(path))
298            out.write("Date: %g\%g\%g \n"%(year, month, day))
299            out.write("GMT Time: %g:%g:%g \n\n"%(hour,minute, second))
300            # Sanity check
301            if has_data:
302                out.write("Fit Data name: %s\n\n"%self.data.name)
303   
304            if has_model:
305                out.write("Model name: %s\n"%self.model.name)
306                if len(self.parameters)>0: 
307                    out.write("Parameters Info:\n")
308                    msg= "Name\t\tValues\t\t+\-\tErrors\t\tMin\t\tMax\t\tUnits\t\tstate\n"
309                    out.write(msg)
310                    ##self.parameters=
311                    ##[cb state, name, value, "+/-", error of fit, min, max , units]
312                    for item in self.parameters:
313                        if item[1]!=None:
314                            name= item[1]
315                        else:
316                            name=""
317                        if item[2]!=None:
318                            value= str(item[2].GetValue().rstrip().lstrip())
319                        else:
320                            value=""
321                        if item[3]!=None:
322                            sign= str(item[3].GetLabelText().rstrip().lstrip())
323                        else:
324                            sign=""
325                        if item[4]!=None:
326                            error= str(item[4].GetValue().rstrip().lstrip())
327                        else:
328                            error=""
329                        if item[5]!=None:
330                            min= str(item[5].GetValue().rstrip().lstrip())
331                        else:
332                            min=""
333                        if item[6]!=None:
334                            max= str(item[6].GetValue().rstrip().lstrip())
335                        else:
336                            max=""
337                        if item[7]!=None:
338                            unit= str(item[7].GetLabelText().rstrip().lstrip())
339                        else:
340                            unit=""
341                        if item[0]!=None:
342                            if item[0].GetValue():
343                                state= "Fitted"
344                            else:
345                                state= "Not Fitted"
346                        else:
347                            state="Not Fitted"
348   
349                        msg= "%s\t\t%s\t\t%s\t%s\t\t%s\t\t%s\t\t%s\t\t%s\n"\
350                         %(name,value,sign,error,min,max,unit,state)
351                        out.write(msg)
352                       
353               
354            out.close()
355
356     
357    def onSetFocus(self, evt):
358        # Get a handle to the TextCtrl
359        widget = evt.GetEventObject()
360        # Select the whole control, after this event resolves
361        wx.CallAfter(widget.SetSelection, -1, -1)
362        return
363   
364    def read_file(self, path):
365        """
366            Read two columns file
367            @param path: the path to the file to read
368        """
369        try:
370            if path==None:
371                wx.PostEvent(self.parent.parent, StatusEvent(status=\
372                            " Selected Distribution was not loaded: %s"%path))
373                return None, None
374            input_f = open(path, 'r')
375            buff = input_f.read()
376            lines = buff.split('\n')
377           
378            angles = []
379            weights=[]
380            for line in lines:
381                toks = line.split()
382                if len(toks)==2:
383                    try:
384                        angle = float(toks[0])
385                        weight = float(toks[1])
386                    except:
387                        # Skip non-data lines
388                        pass
389                    angles.append(angle)
390                    weights.append(weight)
391            return numpy.array(angles), numpy.array(weights)
392        except:
393            raise 
394     
395   
396    def _selectDlg(self):
397        """
398            open a dialog file to selected the customized dispersity
399        """
400        import os
401        dlg = wx.FileDialog(self, "Choose a weight file", os.getcwd(), "", "*.*", wx.OPEN)
402        path = None
403        if dlg.ShowModal() == wx.ID_OK:
404            path = dlg.GetPath()
405        dlg.Destroy()
406        return path
407         
408   
409    def _onparamEnter_helper(self):
410        """
411             check if values entered by the user are changed and valid to replot
412             model
413             use : _check_value_enter
414        """
415        if self.model !=None:
416            # Flag to register when a parameter has changed.
417            is_modified = False
418            is_modified =self._check_value_enter( self.fittable_param ,is_modified)
419            is_modified =self._check_value_enter( self.fixed_param ,is_modified)
420            is_modified =self._check_value_enter( self.parameters ,is_modified)       
421           
422            self.Layout()
423            # Here we should check whether the boundaries have been modified.
424            # If qmin and qmax have been modified, update qmin and qmax and
425            # set the is_modified flag to True
426            from sans.guiframe.utils import check_value
427            if check_value( self.qmin, self.qmax):
428                if float(self.qmin.GetValue()) != self.qmin_x:
429                    self.qmin_x = float(self.qmin.GetValue())
430                    is_modified = True
431                if float(self.qmax.GetValue()) != self.qmax_x:
432                    self.qmax_x = float(self.qmax.GetValue())
433                    is_modified = True
434                self.fitrange = True
435            else:
436                self.fitrange = False
437            if self.npts != None:
438                if float(self.npts.GetValue()) !=  self.num_points:
439                    self.num_points = float(self.npts.GetValue())
440                    is_modified = True
441            ## if any value is modify draw model with new value
442            if is_modified:
443                self._draw_model() 
444               
445               
446    def _set_model_sizer_selection(self, model):
447        """
448            Display the sizer according to the type of the current model
449        """
450        if hasattr(model ,"model2"):
451           
452            class_name= model.model2.__class__
453            name= model.model2.name
454            flag= name != "NoStructure"
455            if flag and (class_name in self.model_list_box["Structure Factors"]):
456                self.structurebox.Show(True)
457                self.text2.Show(True)
458                self.multip_cb.SetValue(True)
459                items = self.structurebox.GetItems()
460                self.sizer1.Layout()
461                self.SetScrollbars(20,20,200,100)
462                for i in range(len(items)):
463                    if items[i]== str(name):
464                        self.structurebox.SetSelection(i)
465                        break
466                   
467        if hasattr(model ,"model1"):
468            class_name = model.model1.__class__
469            name = model.model1.name
470            self.formfactorbox.Clear()
471           
472            for k, list in self.model_list_box.iteritems():
473                if k in["P(Q)*S(Q)","Shapes" ] and class_name in self.model_list_box["Shapes"]:
474                    self.shape_rbutton.SetValue(True)
475                    ## fill the form factor list with new model
476                    self._populate_box(self.formfactorbox,self.model_list_box["Shapes"])
477                    items = self.formfactorbox.GetItems()
478                    ## set comboxbox to the selected item
479                    for i in range(len(items)):
480                        if items[i]== str(name):
481                            self.formfactorbox.SetSelection(i)
482                            break
483                    return
484                elif k == "Shape-Independent":
485                    self.shape_indep_rbutton.SetValue(True)
486                elif k == "Structure Factors":
487                     self.struct_rbutton.SetValue(True)
488                else:
489                    self.plugin_rbutton.SetValue(True)
490               
491                if class_name in list:
492                    ## fill the form factor list with new model
493                    self._populate_box(self.formfactorbox, list)
494                    items = self.formfactorbox.GetItems()
495                    ## set comboxbox to the selected item
496                    for i in range(len(items)):
497                        if items[i]== str(name):
498                            self.formfactorbox.SetSelection(i)
499                            break
500                    break
501        else:
502            ## Select the model from the combobox
503            class_name = model.__class__
504            name = model.name
505            self.formfactorbox.Clear()
506            items = self.formfactorbox.GetItems()
507   
508            for k, list in self.model_list_box.iteritems():
509                if k in["P(Q)*S(Q)","Shapes" ] and class_name in self.model_list_box["Shapes"]:
510                    self.shape_rbutton.SetValue(True)
511                    ## fill the form factor list with new model
512                    self._populate_box(self.formfactorbox,self.model_list_box["Shapes"])
513                    items = self.formfactorbox.GetItems()
514                    ## set comboxbox to the selected item
515                    for i in range(len(items)):
516                        if items[i]== str(name):
517                            self.formfactorbox.SetSelection(i)
518                            break
519                    return
520                elif k == "Shape-Independent":
521                    self.shape_indep_rbutton.SetValue(True)
522                elif k == "Structure Factors":
523                     self.struct_rbutton.SetValue(True)
524                else:
525                    self.plugin_rbutton.SetValue(True)
526                if class_name in list:
527                    ## fill the form factor list with new model
528                    self._populate_box(self.formfactorbox, list)
529                    items = self.formfactorbox.GetItems()
530                    ## set comboxbox to the selected item
531                    for i in range(len(items)):
532                        if items[i]== str(name):
533                            self.formfactorbox.SetSelection(i)
534                            break
535                    break
536                   
537       
538       
539    def _draw_model(self):
540        """
541            Method to draw or refresh a plotted model.
542            The method will use the data member from the model page
543            to build a call to the fitting perspective manager.
544           
545            [Note to coder: This way future changes will be done in only one place.]
546        """
547        if self.model !=None:
548            self.manager.draw_model(self.model, data=self.data,
549                                    qmin=float(self.qmin_x), qmax=float(self.qmax_x),
550                                    qstep= float(self.num_points),
551                                    enable2D=self.enable2D) 
552       
553    def _set_model_sizer(self, sizer, title="", object=None):
554        """
555            Use lists to fill a sizer for model info
556        """
557       
558        sizer.Clear(True)
559        box_description= wx.StaticBox(self, -1,str(title))
560        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
561        #--------------------------------------------------------
562        self.shape_rbutton = wx.RadioButton(self, -1, 'Shapes', style=wx.RB_GROUP)
563        self.shape_indep_rbutton = wx.RadioButton(self, -1, "Shape-Independent")
564        self.struct_rbutton = wx.RadioButton(self, -1, "Structure Factor ")
565        self.plugin_rbutton = wx.RadioButton(self, -1, "Customized Models")
566        self.multip_cb = wx.CheckBox(self, -1,"P(Q)*S(Q)")
567       
568       
569       
570        self.Bind( wx.EVT_RADIOBUTTON, self._show_combox,
571                            id= self.shape_rbutton.GetId() ) 
572        self.Bind( wx.EVT_RADIOBUTTON, self._show_combox,
573                            id= self.shape_indep_rbutton.GetId() ) 
574        self.Bind( wx.EVT_RADIOBUTTON, self._show_combox,
575                            id= self.struct_rbutton.GetId() ) 
576        self.Bind( wx.EVT_RADIOBUTTON, self._show_combox,
577                            id= self.plugin_rbutton.GetId() ) 
578        wx.EVT_CHECKBOX(self, self.multip_cb.GetId() , self._show_combox )             
579        ## store state
580        self.page_info.save_radiobox_state( self.shape_rbutton )
581        self.page_info.save_radiobox_state( self.shape_indep_rbutton )
582        self.page_info.save_radiobox_state( self.struct_rbutton )
583        self.page_info.save_radiobox_state( self.plugin_rbutton )
584       
585       
586        sizer_radiobutton = wx.GridSizer(3, 3,5, 5)
587        sizer_radiobutton.Add(self.shape_rbutton)
588        sizer_radiobutton.Add(self.shape_indep_rbutton)
589        sizer_radiobutton.Add(self.multip_cb)
590        sizer_radiobutton.Add(self.plugin_rbutton)
591        sizer_radiobutton.Add(self.struct_rbutton)
592       
593        sizer_selection = wx.BoxSizer(wx.HORIZONTAL)
594       
595        self.text1 = wx.StaticText( self,-1,"P(Q)" )
596        self.text2 = wx.StaticText( self,-1,"* S(Q)" )
597       
598        self.text2.Hide()
599       
600        self.formfactorbox = wx.ComboBox(self, -1,style=wx.CB_READONLY)
601        if self.model!=None:
602            self.formfactorbox.SetValue(self.model.name)
603           
604           
605        self.structurebox = wx.ComboBox(self, -1,style=wx.CB_READONLY)
606        wx.EVT_COMBOBOX(self.formfactorbox,-1, self._on_select_model)
607        wx.EVT_COMBOBOX(self.structurebox,-1, self._on_select_model)
608        self.structurebox.Hide()
609       
610        ## fill combox box
611        if len(self.model_list_box)>0:
612            self._populate_box( self.formfactorbox,self.model_list_box["Shapes"])
613       
614        if len(self.model_list_box)>0:
615            self._populate_box( self.structurebox,
616                                self.model_list_box["Structure Factors"])
617       
618        ## check model type to show sizer
619        if self.model !=None:
620            self._set_model_sizer_selection( self.model )
621       
622        sizer_selection.Add(self.text1)
623        sizer_selection.Add((5,5))
624        sizer_selection.Add(self.formfactorbox)
625        sizer_selection.Add((5,5))
626        sizer_selection.Add(self.text2)
627        sizer_selection.Add((5,5))
628        sizer_selection.Add(self.structurebox)
629        sizer_selection.Add((5,5))
630       
631        boxsizer1.Add( sizer_radiobutton )
632        boxsizer1.Add( (20,20))
633        boxsizer1.Add( sizer_selection )
634        if object !=None:
635            boxsizer1.Add( (20,20))
636            boxsizer1.Add( object )
637        #--------------------------------------------------------
638        sizer.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
639        sizer.Layout()
640        self.SetScrollbars(20,20,200,100)
641       
642       
643    def _show_combox(self, event):
644        """
645            Show combox box associate with type of model selected
646        """
647        self.page_info.save_radiobox_state( self.shape_rbutton )
648        self.page_info.save_radiobox_state( self.shape_indep_rbutton )
649        self.page_info.save_radiobox_state( self.struct_rbutton )
650        self.page_info.save_radiobox_state( self.plugin_rbutton )
651       
652        ## Don't want to populate combo box again if the event comes from check box
653        if self.shape_rbutton.GetValue()and\
654             event.GetEventObject()==self.shape_rbutton:
655            ##fill the combobox with form factor list
656            self.structurebox.Hide()
657            self.text2.Hide()
658            self.formfactorbox.Clear()
659            self._populate_box( self.formfactorbox,self.model_list_box["Shapes"])
660           
661        if self.shape_indep_rbutton.GetValue()and\
662             event.GetEventObject()==self.shape_indep_rbutton:
663            ##fill the combobox with shape independent  factor list
664            self.structurebox.Hide()
665            self.text2.Hide()
666            self.formfactorbox.Clear()
667            self._populate_box( self.formfactorbox,
668                                self.model_list_box["Shape-Independent"])
669           
670        if self.struct_rbutton.GetValue() and\
671             event.GetEventObject()==self.struct_rbutton:
672            ##fill the combobox with structure factor list
673            self.structurebox.Hide()
674            self.text2.Hide()
675            self.formfactorbox.Clear()
676            self._populate_box( self.formfactorbox,
677                                self.model_list_box["Structure Factors"])
678           
679        if self.plugin_rbutton.GetValue()and\
680             event.GetEventObject()==self.plugin_rbutton:
681           
682            ##fill the combobox with form factor list
683            self.structurebox.Hide()
684            self.text2.Hide()
685            self.formfactorbox.Clear()
686            self._populate_box( self.formfactorbox,
687                                self.model_list_box["Customized Models"])
688       
689        if not self.multip_cb.GetValue(): 
690            self.structurebox.Hide()
691            self.text2.Hide()
692            n = self.formfactorbox.GetCurrentSelection()
693            model = self.formfactorbox.GetClientData(n)
694            self.model = model()
695        ## user check multiplication option       
696        else:
697            ##for this release
698            flag1= self.plugin_rbutton.GetValue()or self.struct_rbutton.GetValue()\
699                    or self.shape_indep_rbutton.GetValue()
700            flag2= False   
701             
702            n = self.formfactorbox.GetCurrentSelection()
703            form_factor = self.formfactorbox.GetClientData(n)   
704            ## selecting only multiplication model
705            if self.shape_rbutton.GetValue():
706               if not form_factor in  self.model_list_box["multiplication"]:
707                   flag2 = True
708            ## multiplication not available for structure factor
709            if flag1 or  flag2:
710                self.multip_cb.SetValue(False)
711                self.structurebox.Hide()
712                self.text2.Hide()
713                return
714            ## allow only some to have multiplication
715           
716            self.structurebox.Show(True)
717            self.text2.Show(True)
718            ## draw multiplication  model
719            n = self.structurebox.GetCurrentSelection()
720            struct_factor = self.structurebox.GetClientData(n)
721           
722            from sans.models.MultiplicationModel import MultiplicationModel
723            self.model= MultiplicationModel(form_factor(),struct_factor())
724
725        self.set_model_param_sizer(self.model)
726        self.sizer4_4.Clear()
727        self.sizer4.Layout()
728           
729        self._draw_model()
730        self.set_scroll()
731       
732       
733   
734           
735    def _populate_box(self, combobox, list):
736        """
737            fill combox box with dict item
738            @param list: contains item to fill the combox
739            item must model class
740        """
741        for models in list:
742            model= models()
743            name = model.__class__.__name__
744            if models.__name__!="NoStructure":
745                if hasattr(model, "name"):
746                    name = model.name
747                combobox.Append(name,models)
748        try:
749
750            combobox.SetSelection(0)
751           
752        except:
753            pass
754        wx.EVT_COMBOBOX(combobox,-1, self._on_select_model) 
755        return 0
756   
757   
758    def _on_select_model_helper(self): 
759        """
760             call back for model selection
761        """
762        ## reset dictionary containing reference to dispersion
763        self._disp_obj_dict = {}
764        self.disp_cb_dict ={}
765       
766        f_id = self.formfactorbox.GetCurrentSelection()
767        s_id = self.structurebox.GetCurrentSelection()
768        form_factor = self.formfactorbox.GetClientData( f_id )
769        struct_factor = self.structurebox.GetClientData( s_id )
770       
771        if not form_factor in  self.model_list_box["multiplication"]:
772            self.multip_cb.SetValue(False)
773            self.structurebox.Hide()
774            self.text2.Hide()
775            self.sizer4_4.Clear()
776            self.sizer4.Layout()
777           
778        if self.multip_cb.GetValue():
779            from sans.models.MultiplicationModel import MultiplicationModel
780            self.model= MultiplicationModel(form_factor(),struct_factor())
781           
782        else:
783            self.model= form_factor()
784       
785       
786    def _onparamEnter(self,event):
787        """
788            when enter value on panel redraw model according to changed
789        """
790        self._onparamEnter_helper()
791       
792       
793    def _check_value_enter(self, list, modified):
794        """
795            @param list: model parameter and panel info
796            each item of the list should be as follow:
797            item=[cb state, name, value, "+/-", error of fit, min, max , units]
798        """ 
799        is_modified =  modified
800        if len(list)==0:
801            return is_modified
802        for item in list:
803            try:
804                if hasattr(self,"text2_3"):
805                    self.text2_3.Hide()
806                if item[3]!=None:
807                    item[3].Hide()
808                if item[4]!=None:
809                    item[4].Clear()
810                    item[4].Hide()
811                name = str(item[1])
812                value= float(item[2].GetValue())
813                # If the value of the parameter has changed,
814                # +update the model and set the is_modified flag
815                if value != self.model.getParam(name):
816                    self.model.setParam(name,value)
817                    is_modified = True   
818            except:
819                msg= "Model Drawing  Error:wrong value entered : %s"% sys.exc_value
820                wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
821                return 
822       
823        return is_modified
824       
825       
826 
827    def _set_dipers_Param(self, event):
828        """
829            Add more item to select user dispersity
830        """
831        if self.model == None:
832            msg= " Select non - model value:%s !"%self.model
833            wx.PostEvent(self.parent.parent, StatusEvent(status= msg))
834            return 
835        else:
836            if self.enable_disp.GetValue():
837                self.model_disp.Show(True)
838                self.disp_box.Show(True)
839                ## layout for model containing no dispersity parameters
840                if len(self.disp_list)==0:
841                    self._layout_sizer_noDipers() 
842                else:
843                    ## set gaussian sizer
844                    self._set_sizer_gaussian() 
845            else:
846                self.model_disp.Hide()
847                self.disp_box.Hide()
848                self.sizer4_4.Clear(True)
849                self._reset_dispersity()
850           
851            self.sizer4.Layout()
852            self.Layout()
853            self.SetScrollbars(20,20,200,100)
854           
855   
856       
857    def _layout_sizer_noDipers(self):
858        """
859            Draw a sizer with no dispersity info
860        """
861        ix=0
862        iy=1
863        self.fittable_param=[]
864        self.fixed_param=[]
865        self.model_disp.Hide()
866        self.disp_box.Hide()
867        self.sizer4_4.Clear(True)
868        model_disp = wx.StaticText(self, -1, 'No PolyDispersity for this model')
869        self.sizer4_4.Add(model_disp,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
870        self.sizer4.Layout()
871        self.SetScrollbars(20,20,200,100)
872        return 
873   
874 
875           
876    def _reset_dispersity(self):
877        """
878             put gaussian dispersity into current model
879        """
880        self.fittable_param=[]
881        self.fixed_param=[]
882       
883        from sans.models.dispersion_models import GaussianDispersion
884        if len(self.disp_cb_dict)==0:
885            return 
886       
887        for p in self.disp_cb_dict:
888            # The parameter was un-selected. Go back to Gaussian model (with 0 pts)
889            disp_model = GaussianDispersion()
890            # Store the object to make it persist outside the scope of this method
891            #TODO: refactor model to clean this up?
892            self._disp_obj_dict[p] = disp_model
893            # Set the new model as the dispersion object for the selected parameter
894            self.model.set_dispersion(p, disp_model)
895            # Redraw the model
896            self._draw_model()
897           
898           
899    def _on_select_Disp(self,event):
900        """
901             allow selecting different dispersion
902             self.disp_list should change type later .now only gaussian
903        """
904        dispersity  =event.GetClientData()
905        name= dispersity.__name__
906        if name == "GaussianDispersion":
907            self._set_sizer_gaussian()
908           
909        if  name=="ArrayDispersion":
910            self._set_sizer_arraydispersion()
911           
912           
913           
914   
915    def _set_sizer_arraydispersion(self):
916        """
917            draw sizer with array dispersity  parameters
918        """
919        self.sizer4_4.Clear(True) 
920        ix=0
921        iy=1     
922        disp1 = wx.StaticText(self, -1, 'Array Dispersion')
923        self.sizer4_4.Add(disp1,( iy, ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
924       
925        # Look for model parameters to which we can apply an ArrayDispersion model
926        # Add a check box for each parameter.
927        self.disp_cb_dict = {}
928        for p in self.model.dispersion.keys():
929            ix+=1 
930            self.disp_cb_dict[p] = wx.CheckBox(self, -1, p, (10, 10))
931           
932            wx.EVT_CHECKBOX(self, self.disp_cb_dict[p].GetId(), self.select_disp_angle)
933            self.sizer4_4.Add(self.disp_cb_dict[p], (iy, ix), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
934       
935        ix =0
936        iy +=1 
937        self.sizer4_4.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)       
938        self.sizer4_4.Layout()
939        self.sizer4.Layout()
940        self.SetScrollbars(20,20,200,100)
941       
942       
943    def _set_range_sizer(self, title, object1=None,object=None):
944        """
945            Fill the
946        """
947        self.sizer5.Clear(True)
948        box_description= wx.StaticBox(self, -1,str(title))
949        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
950        #--------------------------------------------------------------
951        self.qmin    = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20))
952        self.qmin.SetValue(format_number(self.qmin_x))
953        self.qmin.SetToolTipString("Minimun value of Q in linear scale.")
954        self.qmin.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
955        self.qmin.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter)
956     
957        self.qmax    = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20))
958        self.qmax.SetValue(format_number(self.qmax_x))
959        self.qmax.SetToolTipString("Maximum value of Q in linear scale.")
960        self.qmax.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
961        self.qmax.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter)
962     
963        sizer_horizontal=wx.BoxSizer(wx.HORIZONTAL)
964        sizer= wx.GridSizer(3, 3,5, 5)
965       
966        sizer.Add((5,5))
967        sizer.Add(wx.StaticText(self, -1, 'Min'))
968        sizer.Add(wx.StaticText(self, -1, 'Max'))
969        sizer.Add(wx.StaticText(self, -1, 'Q range'))
970             
971        sizer.Add(self.qmin)
972        sizer.Add(self.qmax)
973        sizer_horizontal.Add(sizer)
974        if object!=None:
975            sizer_horizontal.Add(object)
976       
977        if object1!=None:
978           boxsizer1.Add(object1) 
979           boxsizer1.Add((10,10))
980        boxsizer1.Add(sizer_horizontal)
981       
982        #----------------------------------------------------------------
983        self.sizer5.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
984        self.sizer5.Layout()
985        self.SetScrollbars(20,20,200,100)
986   
987    def _fill_save_sizer(self):
988        """
989            Draw the layout for saving option
990        """
991        self.sizer6.Clear(True)
992        box_description= wx.StaticBox(self, -1,"Save Options")
993        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
994        sizer_save = wx.BoxSizer(wx.HORIZONTAL)
995       
996        self.btSave = wx.Button(self,wx.NewId(),'Save')
997        self.btSave.Bind(wx.EVT_BUTTON, self.onSave,id= self.btSave.GetId())
998        self.btSave.SetToolTipString("Save current state")
999         
1000        sizer_save.Add((20,20),0, wx.LEFT|wx.RIGHT|wx.EXPAND,120)       
1001        sizer_save.Add(self.btSave)     
1002       
1003        boxsizer1.Add(sizer_save)
1004        self.sizer6.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
1005        self.sizer6.Layout()
1006        self.SetScrollbars(20,20,200,100)
1007       
1008       
1009               
Note: See TracBrowser for help on using the repository browser.