source: sasview/sansview/perspectives/fitting/basepage.py @ 58c90ba

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 58c90ba was ce92ded, checked in by Jae Cho <jhjcho@…>, 13 years ago

still working on mac crash: disabled Hiding of errors on MAC

  • Property mode set to 100644
File size: 109.2 KB
Line 
1
2import sys
3import os
4import wx
5import numpy
6import time
7import copy 
8import math
9import string
10from sans.guiframe.panel_base import PanelBase
11from wx.lib.scrolledpanel import ScrolledPanel
12from sans.guiframe.utils import format_number,check_float
13from sans.guiframe.events import PanelOnFocusEvent
14from sans.guiframe.events import StatusEvent
15from sans.guiframe.events import AppendBookmarkEvent
16import pagestate
17from pagestate import PageState
18(PageInfoEvent, EVT_PAGE_INFO)   = wx.lib.newevent.NewEvent()
19(PreviousStateEvent, EVT_PREVIOUS_STATE)   = wx.lib.newevent.NewEvent()
20(NextStateEvent, EVT_NEXT_STATE)   = wx.lib.newevent.NewEvent()
21
22_BOX_WIDTH = 76
23_QMIN_DEFAULT = 0.0005
24_QMAX_DEFAULT = 0.5
25_NPTS_DEFAULT = 50
26#Control panel width
27if sys.platform.count("darwin")==0:
28    PANEL_WIDTH = 450
29    FONT_VARIANT = 0
30    ON_MAC = False
31else:
32    PANEL_WIDTH = 500
33    FONT_VARIANT = 1
34    ON_MAC = True
35
36
37
38class BasicPage(ScrolledPanel, PanelBase):
39    """
40    This class provide general structure of  fitpanel page
41    """
42     ## Internal name for the AUI manager
43    window_name = "Fit Page"
44    ## Title to appear on top of the window
45    window_caption = "Fit Page "
46   
47    def __init__(self, parent,color='blue', **kwargs):
48        """
49        """
50        ScrolledPanel.__init__(self, parent, **kwargs)
51        PanelBase.__init__(self, parent)
52        self.SetupScrolling()
53        #Set window's font size
54        self.SetWindowVariant(variant=FONT_VARIANT)
55     
56        self.SetBackgroundColour(color)
57        ## parent of the page
58        self.parent = parent
59        ## manager is the fitting plugin
60        ## owner of the page (fitting plugin)
61        self.event_owner = None
62         ## current model
63        self.model = None
64        ## data
65        self.data = None
66        self.mask = None
67        self.uid = None
68        ## Q range
69        self.qmin = None
70        self.qmax = None
71        self.qmax_x = _QMAX_DEFAULT
72        self.qmin_x = _QMIN_DEFAULT
73        self.npts_x = _NPTS_DEFAULT
74        ## total number of point: float
75        self.npts = None
76        ## default fitengine type
77        self.engine_type = 'scipy'
78        ## smear default
79        self.smearer = None
80        self.current_smearer = None
81        ## 2D smear accuracy default
82        self.smear2d_accuracy = 'Low'
83        ## slit smear:
84        self.dxl = None
85        self.dxw = None
86        ## pinhole smear
87        self.dx_min = None
88        self.dx_max = None
89       
90        self.disp_cb_dict = {}
91   
92        self.state = PageState(parent=parent)
93        ## dictionary containing list of models
94        self.model_list_box = {}
95       
96        ## Data member to store the dispersion object created
97        self._disp_obj_dict = {}
98        ## selected parameters to apply dispersion
99        self.disp_cb_dict ={}
100
101        ## smearer object
102        self.smearer = None
103        self.enable2D = False
104        self.is_mac = ON_MAC
105       
106        ##list of model parameters. each item must have same length
107        ## each item related to a given parameters
108        ##[cb state, name, value, "+/-", error of fit, min, max , units]
109        self.parameters = []
110        # non-fittable parameter whose value is astring
111        self.str_parameters = []
112        ## list of parameters to fit , must be like self.parameters
113        self.param_toFit = []
114        ## list of looking like parameters but with non fittable parameters info
115        self.fixed_param = []
116        ## list of looking like parameters but with  fittable parameters info
117        self.fittable_param = []
118        ##list of dispersion parameters
119        self.disp_list = []
120        self.disp_name = ""
121       
122        ## list of orientation parameters
123        self.orientation_params = []
124        self.orientation_params_disp = []
125        if self.model != None:
126            self.disp_list = self.model.getDispParamList()
127        self.temp_multi_functional = False
128        ##enable model 2D draw
129        self.enable2D = False
130        ## check that the fit range is correct to plot the model again
131        self.fitrange = True
132        ## Create memento to save the current state
133        self.state = PageState(parent=self.parent,
134                               model=self.model, data=self.data)
135        ## flag to determine if state has change
136        self.state_change = False
137        ## save customized array
138        self.values = []
139        self.weights = []
140        ## retrieve saved state
141        self.number_saved_state = 0
142        ## dictionary of saved state
143        self.saved_states = {} 
144        ## Create context menu for page
145        self.popUpMenu = wx.Menu()
146   
147        id = wx.NewId()
148        self._keep = wx.MenuItem(self.popUpMenu,id,"Add bookmark",
149                                 " Keep the panel status to recall it later")
150        self.popUpMenu.AppendItem(self._keep)
151        self._keep.Enable(False)
152        self._set_bookmark_flag(False)
153        self._set_save_flag(False)
154        wx.EVT_MENU(self, id, self.on_bookmark)
155        self.popUpMenu.AppendSeparator()
156   
157        ## Default locations
158        self._default_save_location = os.getcwd()     
159        ## save initial state on context menu
160        #self.onSave(event=None)
161        self.Bind(wx.EVT_CONTEXT_MENU, self.onContextMenu)
162       
163        # bind key event
164        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
165
166        ## create the basic structure of the panel with empty sizer
167        self.define_page_structure()
168        ## drawing Initial dispersion parameters sizer
169        self.set_dispers_sizer()
170       
171        ## layout
172        self.set_layout()
173       
174   
175       
176    def on_set_focus(self, event):
177        """
178        """
179        if self._manager is not None:
180            wx.PostEvent(self._manager.parent, PanelOnFocusEvent(panel=self))
181       
182    class ModelTextCtrl(wx.TextCtrl):
183        """
184        Text control for model and fit parameters.
185        Binds the appropriate events for user interactions.
186        Default callback methods can be overwritten on initialization
187       
188        :param kill_focus_callback: callback method for EVT_KILL_FOCUS event
189        :param set_focus_callback:  callback method for EVT_SET_FOCUS event
190        :param mouse_up_callback:   callback method for EVT_LEFT_UP event
191        :param text_enter_callback: callback method for EVT_TEXT_ENTER event
192       
193        """
194        ## Set to True when the mouse is clicked while the whole string is selected
195        full_selection = False
196        ## Call back for EVT_SET_FOCUS events
197        _on_set_focus_callback = None
198       
199        def __init__(self, parent, id=-1, 
200                     value=wx.EmptyString, 
201                     pos=wx.DefaultPosition, 
202                     size=wx.DefaultSize,
203                     style=0, 
204                     validator=wx.DefaultValidator,
205                     name=wx.TextCtrlNameStr,
206                     kill_focus_callback=None,
207                     set_focus_callback=None,
208                     mouse_up_callback=None,
209                     text_enter_callback = None):
210             
211            wx.TextCtrl.__init__(self, parent, id, value, pos,
212                                  size, style, validator, name)
213           
214            # Bind appropriate events
215            self._on_set_focus_callback = parent.onSetFocus \
216                      if set_focus_callback is None else set_focus_callback
217            self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus)
218            self.Bind(wx.EVT_KILL_FOCUS, self._silent_kill_focus \
219                      if kill_focus_callback is None else kill_focus_callback)               
220            self.Bind(wx.EVT_TEXT_ENTER, parent._onparamEnter \
221                      if text_enter_callback is None else text_enter_callback)
222            if not ON_MAC :
223                self.Bind(wx.EVT_LEFT_UP,    self._highlight_text \
224                          if mouse_up_callback is None else mouse_up_callback)
225           
226        def _on_set_focus(self, event):
227            """
228            Catch when the text control is set in focus to highlight the whole
229            text if necessary
230           
231            :param event: mouse event
232           
233            """
234            event.Skip()
235            self.full_selection = True
236            return self._on_set_focus_callback(event)
237       
238 
239           
240        def _highlight_text(self, event):
241            """
242            Highlight text of a TextCtrl only of no text has be selected
243           
244            :param event: mouse event
245           
246            """
247            # Make sure the mouse event is available to other listeners
248            event.Skip()
249            control  = event.GetEventObject()
250            if self.full_selection:
251                self.full_selection = False
252                # Check that we have a TextCtrl
253                if issubclass(control.__class__, wx.TextCtrl):
254                    # Check whether text has been selected,
255                    # if not, select the whole string
256                    (start, end) = control.GetSelection()
257                    if start==end:
258                        control.SetSelection(-1,-1)
259                       
260        def _silent_kill_focus(self,event):
261            """
262            Save the state of the page
263            """
264           
265            event.Skip()
266            pass
267   
268    def set_page_info(self, page_info):
269        """
270        set some page important information at once
271        """
272       ##window_name
273        self.window_name = page_info.window_name
274        ##window_caption
275        self.window_caption = page_info.window_caption
276        ## manager is the fitting plugin
277        self._manager= page_info.manager
278        ## owner of the page (fitting plugin)
279        self.event_owner= page_info.event_owner
280         ## current model
281        self.model = page_info.model
282        ## data
283        self.data = page_info.data
284        ## dictionary containing list of models
285        self.model_list_box = page_info.model_list_box
286        ## Data member to store the dispersion object created
287        self.populate_box(dict=self.model_list_box)
288       
289    def onContextMenu(self, event): 
290        """
291        Retrieve the state selected state
292        """
293        # Skipping the save state functionality for release 0.9.0
294        #return
295   
296        pos = event.GetPosition()
297        pos = self.ScreenToClient(pos)
298       
299        self.PopupMenu(self.popUpMenu, pos) 
300     
301       
302    def onUndo(self, event):
303        """
304        Cancel the previous action
305        """
306        event = PreviousStateEvent(page = self)
307        wx.PostEvent(self.parent, event)
308       
309    def onRedo(self, event):
310        """
311        Restore the previous action cancelled
312        """
313        event = NextStateEvent(page= self)
314        wx.PostEvent(self.parent, event)
315   
316    def define_page_structure(self):
317        """
318        Create empty sizer for a panel
319        """
320        self.vbox  = wx.BoxSizer(wx.VERTICAL)
321        self.sizer0 = wx.BoxSizer(wx.VERTICAL)
322        self.sizer1 = wx.BoxSizer(wx.VERTICAL)
323        self.sizer2 = wx.BoxSizer(wx.VERTICAL)
324        self.sizer3 = wx.BoxSizer(wx.VERTICAL)
325        self.sizer4 = wx.BoxSizer(wx.VERTICAL)
326        self.sizer5 = wx.BoxSizer(wx.VERTICAL)
327        self.sizer6 = wx.BoxSizer(wx.VERTICAL)
328       
329        self.sizer0.SetMinSize((PANEL_WIDTH,-1))
330        self.sizer1.SetMinSize((PANEL_WIDTH,-1))
331        self.sizer2.SetMinSize((PANEL_WIDTH,-1))
332        self.sizer3.SetMinSize((PANEL_WIDTH,-1))
333        self.sizer4.SetMinSize((PANEL_WIDTH,-1))
334        self.sizer5.SetMinSize((PANEL_WIDTH,-1))
335        self.sizer6.SetMinSize((PANEL_WIDTH,-1))
336       
337        self.vbox.Add(self.sizer0)
338        self.vbox.Add(self.sizer1)
339        self.vbox.Add(self.sizer2)
340        self.vbox.Add(self.sizer3)
341        self.vbox.Add(self.sizer4)
342        self.vbox.Add(self.sizer5)
343        self.vbox.Add(self.sizer6)
344       
345    def set_layout(self):
346        """
347        layout
348        """
349        self.vbox.Layout()
350        self.vbox.Fit(self) 
351        self.SetSizer(self.vbox)
352        self.Centre()
353 
354    def set_owner(self,owner):
355        """
356        set owner of fitpage
357       
358        :param owner: the class responsible of plotting
359       
360        """
361        self.event_owner = owner   
362        self.state.event_owner = owner
363       
364    def get_state(self):
365        """
366        """
367        return self.state
368    def get_data(self):
369        """
370        return the current data
371        """
372        return self.data 
373   
374    def set_manager(self, manager):
375        """
376        set panel manager
377       
378        :param manager: instance of plugin fitting
379       
380        """
381        self._manager = manager 
382        self.state.manager = manager
383       
384    def populate_box(self, dict):
385        """
386        Store list of model
387       
388        :param dict: dictionary containing list of models
389       
390        """
391        self.model_list_box = dict
392        self.state.model_list_box = self.model_list_box
393        self.initialize_combox()
394       
395    def initialize_combox(self): 
396        """
397        put default value in the combobox
398        """ 
399        ## fill combox box
400        if self.model_list_box is None:
401            return
402        if len(self.model_list_box) > 0:
403            self._populate_box(self.formfactorbox,
404                               self.model_list_box["Shapes"])
405       
406        if len(self.model_list_box) > 0:
407            self._populate_box(self.structurebox,
408                                self.model_list_box["Structure Factors"])
409            self.structurebox.Insert("None", 0, None)
410            self.structurebox.SetSelection(0)
411            self.structurebox.Hide()
412            self.text2.Hide()
413            self.structurebox.Disable()
414            self.text2.Disable()
415             
416            if self.model.__class__ in self.model_list_box["P(Q)*S(Q)"]:
417                self.structurebox.Show()
418                self.text2.Show()
419                self.structurebox.Enable()
420                self.text2.Enable()           
421               
422    def set_dispers_sizer(self):
423        """
424        fill sizer containing dispersity info
425        """
426        self.sizer4.Clear(True)
427        name="Polydispersity and Orientational Distribution"
428        box_description= wx.StaticBox(self, -1,name)
429        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
430        #----------------------------------------------------
431        self.disable_disp = wx.RadioButton(self, -1, 'Off', (10, 10),
432                                            style=wx.RB_GROUP)
433        self.enable_disp = wx.RadioButton(self, -1, 'On', (10, 30))
434        # best size for MAC and PC
435        if ON_MAC:
436            size_q = (30, 20)     
437        else:
438            size_q = (20, 15)   
439        self.disp_help_bt = wx.Button(self,wx.NewId(),'?', 
440                                      style = wx.BU_EXACTFIT,
441                                      size=size_q)
442        self.disp_help_bt.Bind(wx.EVT_BUTTON, 
443                        self.on_pd_help_clicked,id= self.disp_help_bt.GetId())
444        self.disp_help_bt.SetToolTipString("Helps for Polydispersion.")       
445       
446        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param,
447                     id=self.disable_disp.GetId())
448        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param,
449                   id=self.enable_disp.GetId())
450        #MAC needs SetValue
451        self.disable_disp.SetValue(True)
452        sizer_dispersion = wx.BoxSizer(wx.HORIZONTAL)
453        sizer_dispersion.Add((20,20))
454        name=""#Polydispersity and \nOrientational Distribution "
455        sizer_dispersion.Add(wx.StaticText(self,-1,name))
456        sizer_dispersion.Add(self.enable_disp )
457        sizer_dispersion.Add((20,20))
458        sizer_dispersion.Add(self.disable_disp )
459        sizer_dispersion.Add((25,20))
460        sizer_dispersion.Add(self.disp_help_bt)
461       
462        ## fill a sizer for dispersion         
463        boxsizer1.Add( sizer_dispersion,0,
464                wx.TOP|wx.BOTTOM|wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE,border=5)
465        #boxsizer1.Add( (10,10) )
466        #boxsizer1.Add( sizer_select_dispers )
467        self.sizer4_4 = wx.GridBagSizer(6,5)
468
469        boxsizer1.Add( self.sizer4_4  )
470        #-----------------------------------------------------
471        self.sizer4.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
472        self.sizer4_4.Layout()
473        self.sizer4.Layout()
474        self.Layout()
475     
476        self.Refresh()
477        ## saving the state of enable dispersity button
478        self.state.enable_disp= self.enable_disp.GetValue()
479        self.state.disable_disp= self.disable_disp.GetValue()
480        self.SetupScrolling()
481
482   
483    def onResetModel(self, event):
484        """
485        Reset model state
486        """
487        menu = event.GetEventObject()
488        ## post help message for the selected model
489        msg = menu.GetHelpString(event.GetId())
490        msg +=" reloaded"
491        wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
492       
493        name = menu.GetLabel(event.GetId())
494        self._on_select_model_helper()
495       
496        if name in self.saved_states.keys():
497            previous_state = self.saved_states[name]
498            ## reset state of checkbox,textcrtl  and  regular parameters value
499            self.reset_page(previous_state)   
500       
501               
502    def on_preview(self, event):
503        """
504        Report the current fit results
505        """   
506        # Get plot image from plotpanel
507        images, canvases = self.get_images()
508        # get the report dialog
509        self.state.report(images, canvases)
510       
511         
512    def on_save(self, event):   
513        """
514        Save the current state into file
515        """ 
516        self.save_current_state()
517        new_state = self.state.clone()
518        # Ask the user the location of the file to write to.
519        path = None
520        dlg = wx.FileDialog(self, "Choose a file", self._default_save_location,
521                                                 "", "*.fitv", wx.SAVE)
522        if dlg.ShowModal() == wx.ID_OK:
523            path = dlg.GetPath()
524            self._default_save_location = os.path.dirname(path)
525        else:
526            return None
527        # MAC always needs the extension for saving
528        extens = ".fitv"
529        # Make sure the ext included in the file name
530        fName = os.path.splitext(path)[0] + extens
531        #the manager write the state into file
532        self._manager.save_fit_state(filepath=fName, fitstate=new_state)
533        return new_state 
534   
535    def _get_time_stamp(self):
536        """
537        return time and date stings
538        """
539        # date and time
540        year, month, day,hour,minute,second,tda,ty,tm_isdst= time.localtime()
541        current_time= str(hour)+":"+str(minute)+":"+str(second)
542        current_date= str( month)+"/"+str(day)+"/"+str(year)
543        return current_time, current_date
544     
545    def on_bookmark(self, event):
546        """
547        save history of the data and model
548        """
549        if self.model==None:
550            msg="Can not bookmark; Please select Data and Model first..."
551            wx.MessageBox(msg, 'Info')
552            return 
553        self.save_current_state()
554        new_state = self.state.clone()
555        ##Add model state on context menu
556        self.number_saved_state += 1
557        current_time, current_date = self._get_time_stamp()
558        #name= self.model.name+"[%g]"%self.number_saved_state
559        name = "Fitting: %g]" % self.number_saved_state
560        name += self.model.__class__.__name__
561        name += "bookmarked at %s on %s" % (current_time, current_date)
562        self.saved_states[name]= new_state
563       
564        ## Add item in the context menu
565        msg =  "Model saved at %s on %s"%(current_time, current_date)
566         ## post help message for the selected model
567        msg +=" Saved! right click on this page to retrieve this model"
568        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
569       
570        id = wx.NewId()
571        self.popUpMenu.Append(id,name,str(msg))
572        wx.EVT_MENU(self, id, self.onResetModel)
573        wx.PostEvent(self.parent.parent, 
574                     AppendBookmarkEvent(title=name, 
575                                         hint=str(msg), handler=self._back_to_bookmark))
576    def _back_to_bookmark(self, event): 
577        """
578        Back to bookmark
579        """
580        self._manager.on_perspective(event)
581        self.onResetModel(event)
582    def old_on_bookmark(self, event):
583        """
584        save history of the data and model
585        """
586        if self.model==None:
587            msg="Can not bookmark; Please select Data and Model first..."
588            wx.MessageBox(msg, 'Info')
589            return 
590        if hasattr(self,"enable_disp"):
591            self.state.enable_disp = copy.deepcopy(self.enable_disp.GetValue())
592        if hasattr(self, "disp_box"):
593            self.state.disp_box = copy.deepcopy(self.disp_box.GetSelection())
594
595        self.state.model.name= self.model.name
596       
597        #Remember fit engine_type for fit panel
598        if self.engine_type == None: 
599            self.engine_type = "scipy"
600        if self._manager !=None:
601            self._manager._on_change_engine(engine=self.engine_type)
602       
603            self.state.engine_type = self.engine_type
604
605        new_state = self.state.clone()
606        new_state.model.name = self.state.model.name
607       
608        new_state.enable2D = copy.deepcopy(self.enable2D)
609        ##Add model state on context menu
610        self.number_saved_state += 1
611        #name= self.model.name+"[%g]"%self.number_saved_state
612        name= self.model.__class__.__name__+"[%g]"%self.number_saved_state
613        self.saved_states[name]= new_state
614       
615        ## Add item in the context menu
616       
617        year, month, day,hour,minute,second,tda,ty,tm_isdst= time.localtime()
618        my_time= str(hour)+" : "+str(minute)+" : "+str(second)+" "
619        date= str( month)+"|"+str(day)+"|"+str(year)
620        msg=  "Model saved at %s on %s"%(my_time, date)
621         ## post help message for the selected model
622        msg +=" Saved! right click on this page to retrieve this model"
623        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
624       
625        id = wx.NewId()
626        self.popUpMenu.Append(id,name,str(msg))
627        wx.EVT_MENU(self, id, self.onResetModel)
628       
629    def onSetFocus(self, evt):
630        """
631        highlight the current textcrtl and hide the error text control shown
632        after fitting
633        """
634        return
635   
636    def read_file(self, path):
637        """
638        Read two columns file
639       
640        :param path: the path to the file to read
641       
642        """
643        try:
644            if path==None:
645                wx.PostEvent(self.parent.parent, StatusEvent(status=\
646                            " Selected Distribution was not loaded: %s"%path))
647                return None, None
648            input_f = open(path, 'r')
649            buff = input_f.read()
650            lines = buff.split('\n')
651           
652            angles = []
653            weights=[]
654            for line in lines:
655                toks = line.split()
656                try:
657                    angle = float(toks[0])
658                    weight = float(toks[1])
659                except:
660                    # Skip non-data lines
661                    pass
662                angles.append(angle)
663                weights.append(weight)
664            return numpy.array(angles), numpy.array(weights)
665        except:
666            raise 
667
668    def createMemento(self):
669        """
670        return the current state of the page
671        """
672        return self.state.clone()
673   
674   
675    def save_current_state(self):
676        """
677        Store current state
678        """
679        self.state.engine_type = copy.deepcopy(self.engine_type)
680        ## save model option
681        if self.model!= None:
682            self.disp_list= self.model.getDispParamList()
683            self.state.disp_list= copy.deepcopy(self.disp_list)
684            self.state.model = self.model.clone()
685        #save radiobutton state for model selection
686        self.state.shape_rbutton = self.shape_rbutton.GetValue()
687        self.state.shape_indep_rbutton = self.shape_indep_rbutton.GetValue()
688        self.state.struct_rbutton = self.struct_rbutton.GetValue()
689        self.state.plugin_rbutton = self.plugin_rbutton.GetValue()
690        #model combobox
691        self.state.structurebox = self.structurebox.GetSelection()
692        self.state.formfactorbox = self.formfactorbox.GetSelection()
693       
694        self.state.enable2D = copy.deepcopy(self.enable2D)
695        self.state.values= copy.deepcopy(self.values)
696        self.state.weights = copy.deepcopy( self.weights)
697        ## save data   
698        self.state.data= copy.deepcopy(self.data)
699        self.state.qmax_x = self.qmax_x
700        self.state.qmin_x = self.qmin_x
701     
702        if hasattr(self,"enable_disp"):
703            self.state.enable_disp= self.enable_disp.GetValue()
704            self.state.disable_disp = self.disable_disp.GetValue()
705           
706        self.state.smearer = copy.deepcopy(self.smearer)
707        if hasattr(self,"enable_smearer"):
708            self.state.enable_smearer = \
709                                copy.deepcopy(self.enable_smearer.GetValue())
710            self.state.disable_smearer = \
711                                copy.deepcopy(self.disable_smearer.GetValue())
712
713        self.state.pinhole_smearer = \
714                                copy.deepcopy(self.pinhole_smearer.GetValue())
715        self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue()) 
716                 
717        if len(self._disp_obj_dict)>0:
718            for k , v in self._disp_obj_dict.iteritems():
719                self.state._disp_obj_dict[k]= v
720                       
721           
722            self.state.values = copy.deepcopy(self.values)
723            self.state.weights = copy.deepcopy(self.weights)
724        ## save plotting range
725        self._save_plotting_range()
726       
727        self.state.orientation_params = []
728        self.state.orientation_params_disp = []
729        self.state.parameters = []
730        self.state.fittable_param = []
731        self.state.fixed_param = []
732        self.state.str_parameters = []
733
734       
735        ## save checkbutton state and txtcrtl values
736        self._copy_parameters_state(self.str_parameters, 
737                                    self.state.str_parameters)
738        self._copy_parameters_state(self.orientation_params,
739                                     self.state.orientation_params)
740        self._copy_parameters_state(self.orientation_params_disp,
741                                     self.state.orientation_params_disp)
742       
743        self._copy_parameters_state(self.parameters, self.state.parameters)
744        self._copy_parameters_state(self.fittable_param,
745                                     self.state.fittable_param)
746        self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
747        #save chisqr
748        self.state.tcChi = self.tcChi.GetValue()
749       
750    def save_current_state_fit(self):
751        """
752        Store current state for fit_page
753        """
754        ## save model option
755        if self.model!= None:
756            self.disp_list= self.model.getDispParamList()
757            self.state.disp_list= copy.deepcopy(self.disp_list)
758            self.state.model = self.model.clone()
759        if hasattr(self, "engine_type"):
760            self.state.engine_type = copy.deepcopy(self.engine_type)
761           
762        self.state.enable2D = copy.deepcopy(self.enable2D)
763        self.state.values= copy.deepcopy(self.values)
764        self.state.weights = copy.deepcopy( self.weights)
765        ## save data   
766        self.state.data= copy.deepcopy(self.data)
767       
768        if hasattr(self,"enable_disp"):
769            self.state.enable_disp= self.enable_disp.GetValue()
770            self.state.disable_disp = self.disable_disp.GetValue()
771           
772        self.state.smearer = copy.deepcopy(self.smearer)
773        if hasattr(self,"enable_smearer"):
774            self.state.enable_smearer = \
775                                copy.deepcopy(self.enable_smearer.GetValue())
776            self.state.disable_smearer = \
777                                copy.deepcopy(self.disable_smearer.GetValue())
778           
779        self.state.pinhole_smearer = \
780                                copy.deepcopy(self.pinhole_smearer.GetValue())
781        self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue()) 
782           
783        if hasattr(self,"disp_box"):
784            self.state.disp_box = self.disp_box.GetCurrentSelection()
785
786            if len(self.disp_cb_dict) > 0:
787                for k, v in self.disp_cb_dict.iteritems():
788         
789                    if v == None :
790                        self.state.disp_cb_dict[k] = v
791                    else:
792                        try:
793                            self.state.disp_cb_dict[k] = v.GetValue()
794                        except:
795                            self.state.disp_cb_dict[k] = None
796           
797            if len(self._disp_obj_dict) > 0:
798                for k , v in self._disp_obj_dict.iteritems():
799     
800                    self.state._disp_obj_dict[k] = v
801                       
802           
803            self.state.values = copy.deepcopy(self.values)
804            self.state.weights = copy.deepcopy(self.weights)
805           
806        ## save plotting range
807        self._save_plotting_range()
808       
809        ## save checkbutton state and txtcrtl values
810        self._copy_parameters_state(self.orientation_params,
811                                     self.state.orientation_params)
812        self._copy_parameters_state(self.orientation_params_disp,
813                                     self.state.orientation_params_disp)
814        self._copy_parameters_state(self.parameters, self.state.parameters)
815        self._copy_parameters_state(self.fittable_param,
816                                             self.state.fittable_param)
817        self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
818   
819         
820    def check_invalid_panel(self): 
821        """
822        check if the user can already perform some action with this panel
823        """ 
824        flag = False
825        if self.data is None:
826            self.disable_smearer.SetValue(True)
827            self.disable_disp.SetValue(True)
828            msg = "Please load Data and select Model to start..."
829            wx.MessageBox(msg, 'Info')
830            return  True
831       
832    def set_model_state(self, state):
833        """
834        reset page given a model state
835        """
836        self.disp_cb_dict = state.disp_cb_dict
837        self.disp_list = state.disp_list
838     
839        ## set the state of the radio box
840        self.shape_rbutton.SetValue(state.shape_rbutton )
841        self.shape_indep_rbutton.SetValue(state.shape_indep_rbutton)
842        self.struct_rbutton.SetValue(state.struct_rbutton)
843        self.plugin_rbutton.SetValue(state.plugin_rbutton)
844       
845        ## fill model combobox
846        self._show_combox_helper()
847        #select the current model
848        self.formfactorbox.Select(int(state.formfactorcombobox))
849        self.structurebox.SetSelection(state.structurecombobox )
850        if state.multi_factor != None:
851            self.multifactorbox.SetSelection(state.multi_factor)
852           
853         ## reset state of checkbox,textcrtl  and  regular parameters value
854        self._reset_parameters_state(self.orientation_params_disp,
855                                     state.orientation_params_disp)
856        self._reset_parameters_state(self.orientation_params,
857                                     state.orientation_params)
858        self._reset_parameters_state(self.str_parameters,
859                                     state.str_parameters)
860        self._reset_parameters_state(self.parameters,state.parameters)
861         ## display dispersion info layer       
862        self.enable_disp.SetValue(state.enable_disp)
863        self.disable_disp.SetValue(state.disable_disp)
864       
865        if hasattr(self, "disp_box"):
866           
867            self.disp_box.SetSelection(state.disp_box) 
868            n= self.disp_box.GetCurrentSelection()
869            dispersity= self.disp_box.GetClientData(n)
870            name = dispersity.__name__     
871
872            self._set_dipers_Param(event=None)
873       
874            if name == "ArrayDispersion":
875               
876                for item in self.disp_cb_dict.keys():
877                   
878                    if hasattr(self.disp_cb_dict[item], "SetValue") :
879                        self.disp_cb_dict[item].SetValue(\
880                                                    state.disp_cb_dict[item])
881                        # Create the dispersion objects
882                        from sans.models.dispersion_models import ArrayDispersion
883                        disp_model = ArrayDispersion()
884                        if hasattr(state,"values")and\
885                                 self.disp_cb_dict[item].GetValue() == True:
886                            if len(state.values)>0:
887                                self.values=state.values
888                                self.weights=state.weights
889                                disp_model.set_weights(self.values,
890                                                        state.weights)
891                            else:
892                                self._reset_dispersity()
893                       
894                        self._disp_obj_dict[item] = disp_model
895                        # Set the new model as the dispersion object
896                        #for the selected parameter
897                        self.model.set_dispersion(item, disp_model)
898                   
899                        self.model._persistency_dict[item] = \
900                                                [state.values, state.weights]
901                   
902            else:
903                keys = self.model.getParamList()
904                for item in keys:
905                    if item in self.disp_list and \
906                        not self.model.details.has_key(item):
907                        self.model.details[item] = ["", None, None]
908                for k,v in self.state.disp_cb_dict.iteritems():
909                    self.disp_cb_dict = copy.deepcopy(state.disp_cb_dict) 
910                    self.state.disp_cb_dict = copy.deepcopy(state.disp_cb_dict)
911         ## smearing info  restore
912        if hasattr(self, "enable_smearer"):
913            ## set smearing value whether or not the data
914            #contain the smearing info
915            self.enable_smearer.SetValue(state.enable_smearer)
916            self.disable_smearer.SetValue(state.disable_smearer)
917            self.onSmear(event=None)           
918        self.pinhole_smearer.SetValue(state.pinhole_smearer)
919        self.slit_smearer.SetValue(state.slit_smearer)
920        ## we have two more options for smearing
921        if self.pinhole_smearer.GetValue(): self.onPinholeSmear(event=None)
922        elif self.slit_smearer.GetValue(): self.onSlitSmear(event=None)
923       
924        ## reset state of checkbox,textcrtl  and dispersity parameters value
925        self._reset_parameters_state(self.fittable_param,state.fittable_param)
926        self._reset_parameters_state(self.fixed_param,state.fixed_param)
927       
928        ## draw the model with previous parameters value
929        self._onparamEnter_helper()
930        self.select_param(event=None) 
931        #Save state_fit
932        self.save_current_state_fit()
933        self._lay_out()
934        self.Refresh()
935       
936    def reset_page_helper(self, state):
937        """
938        Use page_state and change the state of existing page
939       
940        :precondition: the page is already drawn or created
941       
942        :postcondition: the state of the underlying data change as well as the
943            state of the graphic interface
944        """
945        if state == None:
946            #self._undo.Enable(False)
947            return 
948        # set data, etc. from the state
949        # reset page between theory and fitting from bookmarking
950        #if state.data == None:
951        #    data = None
952        #else:
953        data = state.data
954
955        #if data != None:
956       
957        if data == None:
958            data_min = state.qmin
959            data_max = state.qmax
960            self.qmin_x = data_min
961            self.qmax_x = data_max
962            #self.minimum_q.SetValue(str(data_min))
963            #self.maximum_q.SetValue(str(data_max))
964            self.qmin.SetValue(str(data_min))
965            self.qmax.SetValue(str(data_max))
966
967            self.state.data = data
968            self.state.qmin = self.qmin_x
969            self.state.qmax = self.qmax_x
970        else:
971            self.set_data(data)
972           
973        self.enable2D= state.enable2D
974        self.engine_type = state.engine_type
975
976        self.disp_cb_dict = state.disp_cb_dict
977        self.disp_list = state.disp_list
978     
979        ## set the state of the radio box
980        self.shape_rbutton.SetValue(state.shape_rbutton )
981        self.shape_indep_rbutton.SetValue(state.shape_indep_rbutton)
982        self.struct_rbutton.SetValue(state.struct_rbutton)
983        self.plugin_rbutton.SetValue(state.plugin_rbutton)
984       
985        ## fill model combobox
986        self._show_combox_helper()
987        #select the current model
988        self.formfactorbox.Select(int(state.formfactorcombobox))
989        self.structurebox.SetSelection(state.structurecombobox )
990        if state.multi_factor != None:
991            self.multifactorbox.SetSelection(state.multi_factor)
992
993        #reset the fitting engine type
994        self.engine_type = state.engine_type
995        #draw the pnael according to the new model parameter
996        self._on_select_model(event=None)
997        # take care of 2D button
998        if data == None and self.model_view.IsEnabled():
999            if self.enable2D:
1000                self.model_view.SetLabel("2D Mode")
1001            else:
1002                self.model_view.SetLabel("1D Mode")
1003        # else:
1004               
1005        if self._manager !=None:
1006            self._manager._on_change_engine(engine=self.engine_type)
1007        ## set the select all check box to the a given state
1008        self.cb1.SetValue(state.cb1)
1009     
1010        ## reset state of checkbox,textcrtl  and  regular parameters value
1011        self._reset_parameters_state(self.orientation_params_disp,
1012                                     state.orientation_params_disp)
1013        self._reset_parameters_state(self.orientation_params,
1014                                     state.orientation_params)
1015        self._reset_parameters_state(self.str_parameters,
1016                                     state.str_parameters)
1017        self._reset_parameters_state(self.parameters,state.parameters)   
1018         ## display dispersion info layer       
1019        self.enable_disp.SetValue(state.enable_disp)
1020        self.disable_disp.SetValue(state.disable_disp)
1021        # If the polydispersion is ON
1022        if state.enable_disp:
1023            # reset dispersion according the state
1024            self._set_dipers_Param(event=None)
1025            self._reset_page_disp_helper(state)
1026        ##plotting range restore   
1027        self._reset_plotting_range(state)
1028        ## smearing info  restore
1029        if hasattr(self, "enable_smearer"):
1030            ## set smearing value whether or not the data
1031            #contain the smearing info
1032            self.enable_smearer.SetValue(state.enable_smearer)
1033            self.disable_smearer.SetValue(state.disable_smearer)
1034            self.onSmear(event=None)           
1035        self.pinhole_smearer.SetValue(state.pinhole_smearer)
1036        self.slit_smearer.SetValue(state.slit_smearer)
1037        ## we have two more options for smearing
1038        if self.pinhole_smearer.GetValue(): self.onPinholeSmear(event=None)
1039        elif self.slit_smearer.GetValue(): self.onSlitSmear(event=None)
1040       
1041        ## reset state of checkbox,textcrtl  and dispersity parameters value
1042        self._reset_parameters_state(self.fittable_param,state.fittable_param)
1043        self._reset_parameters_state(self.fixed_param,state.fixed_param)
1044       
1045        ## draw the model with previous parameters value
1046        self._onparamEnter_helper()
1047        #reset the value of chisqr when not consistent with the value computed
1048        self.tcChi.SetValue(str(self.state.tcChi))
1049        ## reset context menu items
1050        self._reset_context_menu()
1051       
1052        ## set the value of the current state to the state given as parameter
1053        self.state = state.clone() 
1054   
1055    def _reset_page_disp_helper(self, state):
1056        """
1057        Help to rest page for dispersions
1058        """
1059        keys = self.model.getParamList()
1060        for item in keys:
1061            if item in self.disp_list and \
1062                not self.model.details.has_key(item):
1063                self.model.details[item] = ["", None, None]
1064        #for k,v in self.state.disp_cb_dict.iteritems():
1065        self.disp_cb_dict = copy.deepcopy(state.disp_cb_dict) 
1066        self.state.disp_cb_dict = copy.deepcopy(state.disp_cb_dict)
1067        self.values = copy.deepcopy(state.values)
1068        self.weights = copy.deepcopy(state.weights)
1069       
1070        for key, disp in state._disp_obj_dict.iteritems():
1071            # From saved file, disp_model can not be sent in model obj.
1072            # it will be sent as a string here, then converted to model object.
1073            if disp.__class__.__name__ == 'str':
1074                com_str  = "from sans.models.dispersion_models "
1075                com_str += "import %s as disp_func"
1076                exec com_str % disp
1077                disp_model = disp_func()
1078            else:
1079                disp_model = disp
1080
1081            self._disp_obj_dict[key] = disp_model
1082            param_name = key.split('.')[0]
1083            # Try to set dispersion only when available
1084            # for eg., pass the orient. angles for 1D Cal
1085            try:
1086                self.model.set_dispersion(param_name, disp_model)
1087                self.model._persistency_dict[key] = \
1088                                 [state.values, state.weights]
1089            except:
1090                pass
1091            selection = self._find_polyfunc_selection(disp_model)
1092            for list in self.fittable_param:
1093                if list[1] == key and list[7] != None:
1094                    list[7].SetSelection(selection)
1095                    # For the array disp_model, set the values and weights
1096                    if selection == 1:
1097                        disp_model.set_weights(self.values[key], 
1098                                              self.weights[key])
1099                        try:
1100                            # Diables all fittable params for array
1101                            list[0].SetValue(False)
1102                            list[0].Disable()
1103                            list[2].Disable()
1104                            list[5].Disable()
1105                            list[6].Disable()
1106                        except:
1107                            pass
1108            # For array, disable all fixed params
1109            if selection == 1:
1110                for item in self.fixed_param:
1111                    if item[1].split(".")[0] == key.split(".")[0]:
1112                        # try it and pass it for the orientation for 1D
1113                        try:
1114                            item[2].Disable()
1115                        except:
1116                            pass
1117   
1118        # Make sure the check box updated when all checked
1119        if self.cb1.GetValue():
1120            self.select_all_param(None)       
1121     
1122    def _selectDlg(self):
1123        """
1124        open a dialog file to selected the customized dispersity
1125        """
1126        import os
1127        dlg = wx.FileDialog(self, "Choose a weight file",
1128                                self._default_save_location , "", 
1129                                "*.*", wx.OPEN)
1130        path = None
1131        if dlg.ShowModal() == wx.ID_OK:
1132            path = dlg.GetPath()
1133        dlg.Destroy()
1134        return path
1135
1136    def _reset_context_menu(self):
1137        """
1138        reset the context menu
1139        """
1140        for name, state in self.state.saved_states.iteritems():
1141            self.number_saved_state += 1
1142            ## Add item in the context menu
1143            id = wx.NewId()
1144            msg = 'Save model and state %g' % self.number_saved_state
1145            self.popUpMenu.Append(id, name, msg)
1146            wx.EVT_MENU(self, id, self.onResetModel)
1147   
1148    def _reset_plotting_range(self, state):
1149        """
1150        Reset the plotting range to a given state
1151        """
1152        # if self.check_invalid_panel():
1153        #    return
1154        self.qmin.SetValue(str(state.qmin))
1155        self.qmax.SetValue(str(state.qmax)) 
1156
1157    def _save_typeOfmodel(self):
1158        """
1159        save radiobutton containing the type model that can be selected
1160        """
1161        self.state.shape_rbutton = self.shape_rbutton.GetValue()
1162        self.state.shape_indep_rbutton = self.shape_indep_rbutton.GetValue()
1163        self.state.struct_rbutton = self.struct_rbutton.GetValue()
1164        self.state.plugin_rbutton = self.plugin_rbutton.GetValue()
1165        self.state.structurebox= self.structurebox.GetCurrentSelection()
1166        self.state.formfactorbox = self.formfactorbox.GetCurrentSelection()
1167       
1168        #self._undo.Enable(True)
1169        ## post state to fit panel
1170        event = PageInfoEvent(page = self)
1171        wx.PostEvent(self.parent, event)
1172       
1173    def _save_plotting_range(self ):
1174        """
1175        save the state of plotting range
1176        """
1177        self.state.qmin = self.qmin_x
1178        self.state.qmax = self.qmax_x
1179        self.state.npts = self.npts_x
1180           
1181    def _onparamEnter_helper(self):
1182        """
1183        check if values entered by the user are changed and valid to replot
1184        model
1185        """
1186        # Flag to register when a parameter has changed.   
1187        is_modified = False
1188        self.fitrange = True
1189        is_2Ddata = False
1190        #self._undo.Enable(True)
1191        # check if 2d data
1192        if self.data.__class__.__name__ == "Data2D":
1193            is_2Ddata = True
1194        if self.model !=None:
1195            try:
1196                is_modified = self._check_value_enter(self.fittable_param,
1197                                                     is_modified)
1198                is_modified = self._check_value_enter(self.fixed_param,
1199                                                      is_modified)
1200                is_modified = self._check_value_enter(self.parameters,
1201                                                      is_modified) 
1202            except:
1203                pass
1204            #if is_modified:
1205
1206            # Here we should check whether the boundaries have been modified.
1207            # If qmin and qmax have been modified, update qmin and qmax and
1208            # set the is_modified flag to True
1209            if self._validate_qrange(self.qmin, self.qmax):
1210                tempmin = float(self.qmin.GetValue())
1211                if tempmin != self.qmin_x:
1212                    self.qmin_x = tempmin
1213                    is_modified = True
1214                tempmax = float(self.qmax.GetValue())
1215                if tempmax != self.qmax_x:
1216                    self.qmax_x = tempmax
1217                    is_modified = True
1218           
1219                if is_2Ddata:
1220                    # set mask   
1221                    is_modified = self._validate_Npts()
1222                   
1223            else:
1224                self.fitrange = False   
1225           
1226            ## if any value is modify draw model with new value
1227            if not self.fitrange:
1228                #self.btFit.Disable()
1229                if is_2Ddata: self.btEditMask.Disable()
1230            else:
1231                #self.btFit.Enable(True)
1232                if is_2Ddata: self.btEditMask.Enable(True)
1233            if is_modified and self.fitrange:
1234                if self.data == None:
1235                    # Theory case: need to get npts value to draw
1236                    self.npts_x = float(self.Npts_total.GetValue())
1237                self.state_change= True
1238                self._draw_model() 
1239                self.Refresh()
1240        return is_modified
1241   
1242    def _update_paramv_on_fit(self):
1243        """
1244        make sure that update param values just before the fitting
1245        """
1246        #flag for qmin qmax check values
1247        flag = True
1248        self.fitrange = True
1249        is_modified = False
1250
1251        #wx.PostEvent(self._manager.parent, StatusEvent(status=" \
1252        #updating ... ",type="update"))
1253
1254        ##So make sure that update param values on_Fit.
1255        #self._undo.Enable(True)
1256        if self.model !=None:           
1257            ##Check the values
1258            self._check_value_enter( self.fittable_param ,is_modified)
1259            self._check_value_enter( self.fixed_param ,is_modified)
1260            self._check_value_enter( self.parameters ,is_modified)
1261
1262            # If qmin and qmax have been modified, update qmin and qmax and
1263             # Here we should check whether the boundaries have been modified.
1264            # If qmin and qmax have been modified, update qmin and qmax and
1265            # set the is_modified flag to True
1266            self.fitrange = self._validate_qrange(self.qmin, self.qmax)
1267            if self.fitrange:
1268                tempmin = float(self.qmin.GetValue())
1269                if tempmin != self.qmin_x:
1270                    self.qmin_x = tempmin
1271                tempmax = float(self.qmax.GetValue())
1272                if tempmax != self.qmax_x:
1273                    self.qmax_x = tempmax
1274                if tempmax == tempmin:
1275                    flag = False   
1276                temp_smearer = None
1277                if not self.disable_smearer.GetValue():
1278                    temp_smearer= self.current_smearer
1279                    if self.slit_smearer.GetValue():
1280                        flag = self.update_slit_smear()
1281                    elif self.pinhole_smearer.GetValue():
1282                        flag = self.update_pinhole_smear()
1283                    else:
1284                        self._manager.set_smearer(smearer=temp_smearer,
1285                                                  uid=self.uid,
1286                                                     qmin=float(self.qmin_x),
1287                                                      qmax=float(self.qmax_x),
1288                                                      draw=False)
1289                elif not self._is_2D():
1290                    self._manager.set_smearer(smearer=temp_smearer,
1291                                              qmin=float(self.qmin_x),
1292                                              uid=self.uid, 
1293                                                 qmax= float(self.qmax_x),
1294                                                 draw=False)
1295                    if self.data != None:
1296                        index_data = ((self.qmin_x <= self.data.x)&\
1297                                      (self.data.x <= self.qmax_x))
1298                        val = str(len(self.data.x[index_data==True]))
1299                        self.Npts_fit.SetValue(val)
1300                    else:
1301                        # No data in the panel
1302                        try:
1303                            self.npts_x = float(self.Npts_total.GetValue())
1304                        except:
1305                            flag = False
1306                            return flag
1307                    flag = True
1308                if self._is_2D():
1309                    # only 2D case set mask 
1310                    flag = self._validate_Npts()
1311                    if not flag:
1312                        return flag
1313            else: flag = False
1314        else: 
1315            flag = False
1316
1317        #For invalid q range, disable the mask editor and fit button, vs.   
1318        if not self.fitrange:
1319            #self.btFit.Disable()
1320            if self._is_2D():
1321                self.btEditMask.Disable()
1322        else:
1323            #self.btFit.Enable(True)
1324            if self._is_2D() and  self.data != None:
1325                self.btEditMask.Enable(True)
1326
1327        if not flag:
1328            msg = "Cannot Plot or Fit :Must select a "
1329            msg += " model or Fitting range is not valid!!!  "
1330            wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
1331       
1332        self.save_current_state()
1333   
1334        return flag                           
1335               
1336    def _is_modified(self, is_modified):
1337        """
1338        return to self._is_modified
1339        """
1340        return is_modified
1341                       
1342    def _reset_parameters_state(self, listtorestore, statelist):
1343        """
1344        Reset the parameters at the given state
1345        """
1346        if len(statelist) == 0 or len(listtorestore) == 0:
1347            return
1348        if len(statelist) !=  len(listtorestore):
1349            return
1350
1351        for j in range(len(listtorestore)):
1352            item_page = listtorestore[j]
1353            item_page_info = statelist[j]
1354            ##change the state of the check box for simple parameters
1355            if item_page[0]!=None:   
1356                item_page[0].SetValue(item_page_info[0])
1357            if item_page[2]!=None:
1358                item_page[2].SetValue(item_page_info[2])
1359                if item_page[2].__class__.__name__ == "ComboBox":
1360                   if self.model.fun_list.has_key(item_page_info[2]):
1361                       fun_val = self.model.fun_list[item_page_info[2]]
1362                       self.model.setParam(item_page_info[1],fun_val)
1363            if item_page[3]!=None:
1364                ## show or hide text +/-
1365                if item_page_info[2]:
1366                    item_page[3].Show(True)
1367                else:
1368                    item_page[3].Hide()
1369            if item_page[4]!=None:
1370                ## show of hide the text crtl for fitting error
1371                if item_page_info[4][0]:
1372                    item_page[4].Show(True)
1373                    item_page[4].SetValue(item_page_info[4][1])
1374                else:
1375                    item_page[3].Hide()
1376            if item_page[5]!=None:
1377                ## show of hide the text crtl for fitting error
1378                item_page[5].Show(item_page_info[5][0])
1379                item_page[5].SetValue(item_page_info[5][1])
1380               
1381            if item_page[6]!=None:
1382                ## show of hide the text crtl for fitting error
1383                item_page[6].Show(item_page_info[6][0])
1384                item_page[6].SetValue(item_page_info[6][1])
1385
1386                   
1387    def _reset_strparam_state(self, listtorestore, statelist):
1388        """
1389        Reset the string parameters at the given state
1390        """
1391        if len(statelist) == 0:
1392            return
1393
1394        listtorestore = copy.deepcopy(statelist)
1395       
1396        for j in range(len(listtorestore)):
1397            item_page = listtorestore[j]
1398            item_page_info = statelist[j]
1399            ##change the state of the check box for simple parameters
1400           
1401            if item_page[0] != None:   
1402                item_page[0].SetValue(format_number(item_page_info[0], True))
1403
1404            if item_page[2] != None:
1405                param_name = item_page_info[1]
1406                value = item_page_info[2]
1407                selection = value
1408                if self.model.fun_list.has_key(value):
1409                    selection = self.model.fun_list[value]
1410                item_page[2].SetValue(selection)
1411                self.model.setParam(param_name, selection)
1412                                     
1413    def _copy_parameters_state(self, listtocopy, statelist):
1414        """
1415        copy the state of button
1416       
1417        :param listtocopy: the list of check button to copy
1418        :param statelist: list of state object to store the current state
1419       
1420        """
1421        if len(listtocopy)==0:
1422            return
1423       
1424        for item in listtocopy:
1425 
1426            checkbox_state = None
1427            if item[0]!= None:
1428                checkbox_state= item[0].GetValue()
1429            parameter_name = item[1]
1430            parameter_value = None
1431            if item[2]!=None:
1432                parameter_value = item[2].GetValue()
1433            static_text = None
1434            if item[3]!=None:
1435                static_text = item[3].IsShown()
1436            error_value = None
1437            error_state = None
1438            if item[4]!= None:
1439                error_value = item[4].GetValue()
1440                error_state = item[4].IsShown()
1441               
1442            min_value = None
1443            min_state = None
1444            if item[5]!= None:
1445                min_value = item[5].GetValue()
1446                min_state = item[5].IsShown()
1447               
1448            max_value = None
1449            max_state = None
1450            if item[6]!= None:
1451                max_value = item[6].GetValue()
1452                max_state = item[6].IsShown()
1453            unit=None
1454            if item[7]!=None:
1455                unit = item[7].GetLabel()
1456               
1457            statelist.append([checkbox_state, parameter_name, parameter_value,
1458                              static_text ,[error_state, error_value],
1459                                [min_state, min_value],
1460                                [max_state, max_value], unit])
1461           
1462    def _set_model_sizer_selection(self, model):
1463        """
1464        Display the sizer according to the type of the current model
1465        """
1466        if model == None:
1467            return
1468        if hasattr(model ,"s_model"):
1469           
1470            class_name = model.s_model.__class__
1471            name = model.s_model.name
1472            flag = (name != "NoStructure")
1473            if flag and \
1474                (class_name in self.model_list_box["Structure Factors"]):
1475                self.structurebox.Show()
1476                self.text2.Show()               
1477                self.structurebox.Enable()
1478                self.text2.Enable()
1479                items = self.structurebox.GetItems()
1480                self.sizer1.Layout()
1481               
1482                for i in range(len(items)):
1483                    if items[i]== str(name):
1484                        self.structurebox.SetSelection(i)
1485                        break
1486                   
1487        if hasattr(model ,"p_model"):
1488            class_name = model.p_model.__class__
1489            name = model.p_model.name
1490            self.formfactorbox.Clear()
1491           
1492            for k, list in self.model_list_box.iteritems():
1493                if k in["P(Q)*S(Q)","Shapes" ] and class_name in self.model_list_box["Shapes"]:
1494                    self.shape_rbutton.SetValue(True)
1495                    ## fill the form factor list with new model
1496                    self._populate_box(self.formfactorbox,self.model_list_box["Shapes"])
1497                    items = self.formfactorbox.GetItems()
1498                    ## set comboxbox to the selected item
1499                    for i in range(len(items)):
1500                        if items[i]== str(name):
1501                            self.formfactorbox.SetSelection(i)
1502                            break
1503                    return
1504                elif k == "Shape-Independent":
1505                    self.shape_indep_rbutton.SetValue(True)
1506                elif k == "Structure Factors":
1507                     self.struct_rbutton.SetValue(True)
1508                elif  k == "Multi-Functions":
1509                    continue
1510                else:
1511                    self.plugin_rbutton.SetValue(True)
1512               
1513                if class_name in list:
1514                    ## fill the form factor list with new model
1515                    self._populate_box(self.formfactorbox, list)
1516                    items = self.formfactorbox.GetItems()
1517                    ## set comboxbox to the selected item
1518                    for i in range(len(items)):
1519                        if items[i]== str(name):
1520                            self.formfactorbox.SetSelection(i)
1521                            break
1522                    break
1523        else:
1524
1525            ## Select the model from the menu
1526            class_name = model.__class__
1527            name = model.name
1528            self.formfactorbox.Clear()
1529            items = self.formfactorbox.GetItems()
1530   
1531            for k, list in self.model_list_box.iteritems():         
1532                if k in["P(Q)*S(Q)","Shapes" ] and class_name in self.model_list_box["Shapes"]:
1533                    if class_name in self.model_list_box["P(Q)*S(Q)"]:
1534                        self.structurebox.Show()
1535                        self.text2.Show()
1536                        self.structurebox.Enable()
1537                        self.structurebox.SetSelection(0)
1538                        self.text2.Enable()
1539                    else:
1540                        self.structurebox.Hide()
1541                        self.text2.Hide()
1542                        self.structurebox.Disable()
1543                        self.structurebox.SetSelection(0)
1544                        self.text2.Disable()
1545                       
1546                    self.shape_rbutton.SetValue(True)
1547                    ## fill the form factor list with new model
1548                    self._populate_box(self.formfactorbox,self.model_list_box["Shapes"])
1549                    items = self.formfactorbox.GetItems()
1550                    ## set comboxbox to the selected item
1551                    for i in range(len(items)):
1552                        if items[i]== str(name):
1553                            self.formfactorbox.SetSelection(i)
1554                            break
1555                    return
1556                elif k == "Shape-Independent":
1557                    self.shape_indep_rbutton.SetValue(True)
1558                elif k == "Structure Factors":
1559                    self.struct_rbutton.SetValue(True)
1560                elif  k == "Multi-Functions":
1561                    continue
1562                else:
1563                    self.plugin_rbutton.SetValue(True)
1564                if class_name in list:
1565                    self.structurebox.SetSelection(0)
1566                    self.structurebox.Disable()
1567                    self.text2.Disable()                   
1568                    ## fill the form factor list with new model
1569                    self._populate_box(self.formfactorbox, list)
1570                    items = self.formfactorbox.GetItems()
1571                    ## set comboxbox to the selected item
1572                    for i in range(len(items)):
1573                        if items[i]== str(name):
1574                            self.formfactorbox.SetSelection(i)
1575                            break
1576                    break
1577   
1578    def _draw_model(self, update_chisqr=True):
1579        """
1580        Method to draw or refresh a plotted model.
1581        The method will use the data member from the model page
1582        to build a call to the fitting perspective manager.
1583       
1584        :param chisqr: update chisqr value [bool]
1585        """
1586        #if self.check_invalid_panel():
1587        #    return
1588        if self.model !=None:
1589            temp_smear=None
1590            if hasattr(self, "enable_smearer"):
1591                if not self.disable_smearer.GetValue():
1592                    temp_smear= self.current_smearer
1593            toggle_mode_on = self.model_view.IsEnabled()
1594            self._manager.draw_model(self.model, 
1595                                    data=self.data,
1596                                    smearer= temp_smear,
1597                                    qmin=float(self.qmin_x), 
1598                                    qmax=float(self.qmax_x),
1599                                    qstep= float(self.npts_x),
1600                                    page_id=self.uid,
1601                                    toggle_mode_on=toggle_mode_on, 
1602                                    state = self.state,
1603                                    enable2D=self.enable2D,
1604                                    update_chisqr=update_chisqr)
1605       
1606       
1607    def _on_show_sld(self, event=None):
1608        """
1609        Plot SLD profile
1610        """
1611        # get profile data
1612        x,y=self.model.getProfile()
1613
1614        from danse.common.plottools import Data1D
1615        #from sans.perspectives.theory.profile_dialog import SLDPanel
1616        from sans.guiframe.local_perspectives.plotting.profile_dialog \
1617        import SLDPanel
1618        sld_data = Data1D(x,y)
1619        sld_data.name = 'SLD'
1620        sld_data.axes = self.sld_axes
1621        self.panel = SLDPanel(self, data=sld_data,axes =self.sld_axes,id =-1 )
1622        self.panel.ShowModal()   
1623       
1624    def _set_multfactor_combobox(self, multiplicity=10):   
1625        """
1626        Set comboBox for muitfactor of CoreMultiShellModel
1627        :param multiplicit: no. of multi-functionality
1628        """
1629        # build content of the combobox
1630        for idx in range(0,multiplicity):
1631            self.multifactorbox.Append(str(idx),int(idx))
1632            #self.multifactorbox.SetSelection(1)
1633        self._hide_multfactor_combobox()
1634       
1635    def _show_multfactor_combobox(self):   
1636        """
1637        Show the comboBox of muitfactor of CoreMultiShellModel
1638        """ 
1639        if not self.mutifactor_text.IsShown():
1640            self.mutifactor_text.Show(True)
1641            self.mutifactor_text1.Show(True)
1642        if not self.multifactorbox.IsShown():
1643            self.multifactorbox.Show(True) 
1644             
1645    def _hide_multfactor_combobox(self):   
1646        """
1647        Hide the comboBox of muitfactor of CoreMultiShellModel
1648        """ 
1649        if self.mutifactor_text.IsShown():
1650            self.mutifactor_text.Hide()
1651            self.mutifactor_text1.Hide()
1652        if self.multifactorbox.IsShown():
1653            self.multifactorbox.Hide()   
1654
1655       
1656    def _show_combox_helper(self):
1657        """
1658        Fill panel's combo box according to the type of model selected
1659        """
1660        if self.shape_rbutton.GetValue():
1661            ##fill the combobox with form factor list
1662            self.structurebox.SetSelection(0)
1663            self.structurebox.Disable()
1664            self.formfactorbox.Clear()
1665            self._populate_box( self.formfactorbox,self.model_list_box["Shapes"])
1666        if self.shape_indep_rbutton.GetValue():
1667            ##fill the combobox with shape independent  factor list
1668            self.structurebox.SetSelection(0)
1669            self.structurebox.Disable()
1670            self.formfactorbox.Clear()
1671            self._populate_box( self.formfactorbox,
1672                                self.model_list_box["Shape-Independent"])
1673        if self.struct_rbutton.GetValue():
1674            ##fill the combobox with structure factor list
1675            self.structurebox.SetSelection(0)
1676            self.structurebox.Disable()
1677            self.formfactorbox.Clear()
1678            self._populate_box( self.formfactorbox,
1679                                self.model_list_box["Structure Factors"])
1680        if self.plugin_rbutton.GetValue():
1681            ##fill the combobox with form factor list
1682            self.structurebox.Disable()
1683            self.formfactorbox.Clear()
1684            self._populate_box( self.formfactorbox,
1685                                self.model_list_box["Customized Models"])
1686       
1687    def _show_combox(self, event=None):
1688        """
1689        Show combox box associate with type of model selected
1690        """
1691        #if self.check_invalid_panel():
1692        #    self.shape_rbutton.SetValue(True)
1693        #    return
1694
1695        self._show_combox_helper()
1696        self._on_select_model(event=None)
1697        self._save_typeOfmodel()
1698        self.sizer4_4.Layout()
1699        self.sizer4.Layout()
1700        self.Layout()
1701        self.Refresh()
1702 
1703    def _populate_box(self, combobox, list):
1704        """
1705        fill combox box with dict item
1706       
1707        :param list: contains item to fill the combox
1708            item must model class
1709        """
1710        for models in list:
1711            model= models()
1712            name = model.__class__.__name__
1713            if models.__name__!="NoStructure":
1714                if hasattr(model, "name"):
1715                    name = model.name
1716                combobox.Append(name,models)
1717        return 0
1718   
1719    def _onQrangeEnter(self, event):
1720        """
1721        Check validity of value enter in the Q range field
1722       
1723        """
1724        tcrtl = event.GetEventObject()
1725        #Clear msg if previously shown.
1726        msg = ""
1727        wx.PostEvent(self.parent, StatusEvent(status=msg))
1728        # Flag to register when a parameter has changed.
1729        is_modified = False
1730        if tcrtl.GetValue().lstrip().rstrip() != "":
1731            try:
1732                value = float(tcrtl.GetValue())
1733                tcrtl.SetBackgroundColour(wx.WHITE)
1734                # If qmin and qmax have been modified, update qmin and qmax
1735                if self._validate_qrange(self.qmin, self.qmax):
1736                    tempmin = float(self.qmin.GetValue())
1737                    if tempmin != self.qmin_x:
1738                        self.qmin_x = tempmin
1739                    tempmax = float(self.qmax.GetValue())
1740                    if tempmax != self.qmax_x:
1741                        self.qmax_x = tempmax
1742                else:
1743                    tcrtl.SetBackgroundColour("pink")
1744                    msg = "Model Error:wrong value entered : %s" % sys.exc_value
1745                    wx.PostEvent(self.parent, StatusEvent(status=msg))
1746                    return 
1747            except:
1748                tcrtl.SetBackgroundColour("pink")
1749                msg = "Model Error:wrong value entered : %s" % sys.exc_value
1750                wx.PostEvent(self.parent, StatusEvent(status=msg))
1751                return 
1752            #Check if # of points for theory model are valid(>0).
1753            if self.npts != None:
1754                if check_float(self.npts):
1755                    temp_npts = float(self.npts.GetValue())
1756                    if temp_npts !=  self.num_points:
1757                        self.num_points = temp_npts
1758                        is_modified = True
1759                else:
1760                    msg = "Cannot Plot :No npts in that Qrange!!!  "
1761                    wx.PostEvent(self.parent, StatusEvent(status=msg))
1762        else:
1763           tcrtl.SetBackgroundColour("pink")
1764           msg = "Model Error:wrong value entered!!!"
1765           wx.PostEvent(self.parent, StatusEvent(status=msg))
1766        #self._undo.Enable(True)
1767        self.save_current_state()
1768        event = PageInfoEvent(page=self)
1769        wx.PostEvent(self.parent, event)
1770        self.state_change = False
1771        #Draw the model for a different range
1772        self._draw_model()
1773                   
1774    def _theory_qrange_enter(self, event):
1775        """
1776        Check validity of value enter in the Q range field
1777        """
1778       
1779        tcrtl= event.GetEventObject()
1780        #Clear msg if previously shown.
1781        msg= ""
1782        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
1783        # Flag to register when a parameter has changed.
1784        is_modified = False
1785        if tcrtl.GetValue().lstrip().rstrip()!="":
1786            try:
1787                value = float(tcrtl.GetValue())
1788                tcrtl.SetBackgroundColour(wx.WHITE)
1789
1790                # If qmin and qmax have been modified, update qmin and qmax
1791                if self._validate_qrange(self.theory_qmin, self.theory_qmax):
1792                    tempmin = float(self.theory_qmin.GetValue())
1793                    if tempmin != self.theory_qmin_x:
1794                        self.theory_qmin_x = tempmin
1795                    tempmax = float(self.theory_qmax.GetValue())
1796                    if tempmax != self.qmax_x:
1797                        self.theory_qmax_x = tempmax
1798                else:
1799                    tcrtl.SetBackgroundColour("pink")
1800                    msg= "Model Error:wrong value entered : %s"% sys.exc_value
1801                    wx.PostEvent(self._manager.parent, StatusEvent(status = msg ))
1802                    return 
1803            except:
1804                tcrtl.SetBackgroundColour("pink")
1805                msg= "Model Error:wrong value entered : %s"% sys.exc_value
1806                wx.PostEvent(self._manager.parent, StatusEvent(status = msg ))
1807                return 
1808            #Check if # of points for theory model are valid(>0).
1809            if self.Npts_total.IsEditable() :
1810                if check_float(self.Npts_total):
1811                    temp_npts = float(self.Npts_total.GetValue())
1812                    if temp_npts !=  self.num_points:
1813                        self.num_points = temp_npts
1814                        is_modified = True
1815                else:
1816                    msg= "Cannot Plot :No npts in that Qrange!!!  "
1817                    wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
1818        else:
1819           tcrtl.SetBackgroundColour("pink")
1820           msg = "Model Error:wrong value entered!!!"
1821           wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
1822        #self._undo.Enable(True)
1823        self.save_current_state()
1824        event = PageInfoEvent(page = self)
1825        wx.PostEvent(self.parent, event)
1826        self.state_change= False
1827        #Draw the model for a different range
1828        self._draw_model()
1829                   
1830    def _on_select_model_helper(self): 
1831        """
1832        call back for model selection
1833        """
1834        ## reset dictionary containing reference to dispersion
1835        self._disp_obj_dict = {}
1836        self.disp_cb_dict ={}
1837        self.temp_multi_functional = False
1838        f_id = self.formfactorbox.GetCurrentSelection()
1839        #For MAC
1840        form_factor = None
1841        if f_id >= 0:
1842            form_factor = self.formfactorbox.GetClientData(f_id)
1843
1844        if not form_factor in  self.model_list_box["multiplication"]:
1845            self.structurebox.Hide()
1846            self.text2.Hide()           
1847            self.structurebox.Disable()
1848            self.structurebox.SetSelection(0)
1849            self.text2.Disable()
1850        else:
1851            self.structurebox.Show()
1852            self.text2.Show()
1853            self.structurebox.Enable()
1854            self.text2.Enable()
1855           
1856        if form_factor != None:   
1857            # set multifactor for Mutifunctional models   
1858            if form_factor().__class__ in self.model_list_box["Multi-Functions"]:
1859                m_id = self.multifactorbox.GetCurrentSelection()
1860                multiplicity = form_factor().multiplicity_info[0]
1861                self.multifactorbox.Clear()
1862                #self.mutifactor_text.SetLabel(form_factor().details[])
1863                self._set_multfactor_combobox(multiplicity)
1864                self._show_multfactor_combobox()
1865                #ToDo:  this info should be called directly from the model
1866                text = form_factor().multiplicity_info[1]#'No. of Shells: '
1867
1868                #self.mutifactor_text.Clear()
1869                self.mutifactor_text.SetLabel(text)
1870                if m_id > multiplicity -1:
1871                    # default value
1872                    m_id = 1
1873                   
1874                self.multi_factor = self.multifactorbox.GetClientData(m_id)
1875                if self.multi_factor == None: self.multi_factor =0
1876                form_factor = form_factor(int(self.multi_factor))
1877                self.multifactorbox.SetSelection(m_id)
1878                # Check len of the text1 and max_multiplicity
1879                text = ''
1880                if form_factor.multiplicity_info[0] == len(form_factor.multiplicity_info[2]):
1881                    text = form_factor.multiplicity_info[2][self.multi_factor]
1882                self.mutifactor_text1.SetLabel(text)
1883                # Check if model has  get sld profile.
1884                if len(form_factor.multiplicity_info[3]) > 0:
1885                    self.sld_axes = form_factor.multiplicity_info[3]
1886                    self.show_sld_button.Show(True)
1887                else:
1888                    self.sld_axes = ""
1889
1890            else:
1891                self._hide_multfactor_combobox()
1892                self.show_sld_button.Hide()
1893                form_factor = form_factor()
1894                self.multi_factor = None
1895        else:
1896            self._hide_multfactor_combobox()
1897            self.show_sld_button.Hide()
1898            self.multi_factor = None 
1899             
1900        s_id = self.structurebox.GetCurrentSelection()
1901        struct_factor = self.structurebox.GetClientData( s_id )
1902       
1903        if  struct_factor !=None:
1904            from sans.models.MultiplicationModel import MultiplicationModel
1905            self.model= MultiplicationModel(form_factor,struct_factor())
1906            # multifunctional form factor
1907            if len(form_factor.non_fittable) > 0:
1908                self.temp_multi_functional = True
1909        else:
1910            if form_factor != None:
1911                self.model= form_factor
1912            else:
1913                self.model = None
1914                return self.model
1915           
1916
1917        ## post state to fit panel
1918        self.state.parameters =[]
1919        self.state.model =self.model
1920        self.state.qmin = self.qmin_x
1921        self.state.multi_factor = self.multi_factor
1922        self.disp_list =self.model.getDispParamList()
1923        self.state.disp_list = self.disp_list
1924        self.on_set_focus(None)
1925        self.Layout()     
1926       
1927    def _validate_qrange(self, qmin_ctrl, qmax_ctrl):
1928        """
1929        Verify that the Q range controls have valid values
1930        and that Qmin < Qmax.
1931       
1932        :param qmin_ctrl: text control for Qmin
1933        :param qmax_ctrl: text control for Qmax
1934       
1935        :return: True is the Q range is value, False otherwise
1936       
1937        """
1938        qmin_validity = check_float(qmin_ctrl)
1939        qmax_validity = check_float(qmax_ctrl)
1940        if not (qmin_validity and qmax_validity):
1941            return False
1942        else:
1943            qmin = float(qmin_ctrl.GetValue())
1944            qmax = float(qmax_ctrl.GetValue())
1945            if qmin < qmax:
1946                #Make sure to set both colours white. 
1947                qmin_ctrl.SetBackgroundColour(wx.WHITE)
1948                qmin_ctrl.Refresh()
1949                qmax_ctrl.SetBackgroundColour(wx.WHITE)
1950                qmax_ctrl.Refresh()
1951            else:
1952                qmin_ctrl.SetBackgroundColour("pink")
1953                qmin_ctrl.Refresh()
1954                qmax_ctrl.SetBackgroundColour("pink")
1955                qmax_ctrl.Refresh()
1956                msg= "Invalid Q range: Q min must be smaller than Q max"
1957                wx.PostEvent(self.parent.parent, StatusEvent(status = msg))
1958                return False
1959        return True
1960   
1961    def _validate_Npts(self): 
1962        """
1963        Validate the number of points for fitting is more than 10 points.
1964        If valid, setvalues Npts_fit otherwise post msg.
1965        """
1966        #default flag
1967        flag = True
1968        # Theory
1969        if self.data == None and self.enable2D:
1970            return flag
1971
1972        # q value from qx and qy
1973        radius= numpy.sqrt( self.data.qx_data * self.data.qx_data + 
1974                            self.data.qy_data * self.data.qy_data )
1975        #get unmasked index
1976        index_data = (float(self.qmin.GetValue()) <= radius) & \
1977                        (radius <= float(self.qmax.GetValue()))
1978        index_data = (index_data) & (self.data.mask) 
1979        index_data = (index_data) & (numpy.isfinite(self.data.data))
1980
1981        if len(index_data[index_data]) < 10:
1982            # change the color pink.
1983            self.qmin.SetBackgroundColour("pink")
1984            self.qmin.Refresh()
1985            self.qmax.SetBackgroundColour("pink")
1986            self.qmax.Refresh()
1987            msg= "Cannot Plot :No or too little npts in that data range!!!  "
1988            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
1989            self.fitrange = False
1990            flag = False
1991        else:
1992            self.Npts_fit.SetValue(str(len(self.data.mask[index_data==True])))
1993            self.fitrange = True
1994           
1995        return flag
1996   
1997    def _check_value_enter(self, list, modified):
1998        """
1999        :param list: model parameter and panel info
2000        :Note: each item of the list should be as follow:
2001            item=[check button state, parameter's name,
2002                paramater's value, string="+/-",
2003                parameter's error of fit,
2004                parameter's minimum value,
2005                parrameter's maximum value ,
2006                parameter's units]
2007        """ 
2008        is_modified =  modified
2009        if len(list)==0:
2010            return is_modified
2011        for item in list:
2012            #skip angle parameters for 1D
2013            if not self.enable2D:#self.data.__class__.__name__ !="Data2D":
2014                if item in self.orientation_params:
2015                    continue
2016            #try:
2017            name = str(item[1])
2018           
2019            if string.find(name,".npts") ==-1 and \
2020                                        string.find(name,".nsigmas")==-1:     
2021                ## check model parameters range             
2022                param_min= None
2023                param_max= None
2024               
2025                ## check minimun value
2026                if item[5]!= None and item[5]!= "":
2027                    if item[5].GetValue().lstrip().rstrip()!="":
2028                        try:
2029                           
2030                            param_min = float(item[5].GetValue())
2031                            if not self._validate_qrange(item[5],item[2]):
2032                                if numpy.isfinite(param_min):
2033                                    item[2].SetValue(format_number(param_min))
2034                           
2035                            item[5].SetBackgroundColour(wx.WHITE)
2036                            item[2].SetBackgroundColour(wx.WHITE)
2037                                           
2038                        except:
2039                            msg = "Wrong Fit parameter range entered "
2040                            wx.PostEvent(self.parent.parent, 
2041                                         StatusEvent(status = msg))
2042                            raise ValueError, msg
2043                        is_modified = True
2044                ## check maximum value
2045                if item[6]!= None and item[6]!= "":
2046                    if item[6].GetValue().lstrip().rstrip()!="":
2047                        try:                         
2048                            param_max = float(item[6].GetValue())
2049                            if not self._validate_qrange(item[2],item[6]):
2050                                if numpy.isfinite(param_max):
2051                                    item[2].SetValue(format_number(param_max)) 
2052                           
2053                            item[6].SetBackgroundColour(wx.WHITE)
2054                            item[2].SetBackgroundColour(wx.WHITE)
2055                        except:
2056                            msg = "Wrong Fit parameter range entered "
2057                            wx.PostEvent(self.parent.parent, 
2058                                         StatusEvent(status = msg))
2059                            raise ValueError, msg
2060                        is_modified = True
2061               
2062
2063                if param_min != None and param_max !=None:
2064                    if not self._validate_qrange(item[5], item[6]):
2065                        msg= "Wrong Fit range entered for parameter "
2066                        msg+= "name %s of model %s "%(name, self.model.name)
2067                        wx.PostEvent(self.parent.parent, 
2068                                     StatusEvent(status = msg))
2069               
2070                if name in self.model.details.keys():   
2071                        self.model.details[name][1:3] = param_min, param_max
2072                        is_modified = True
2073             
2074                else:
2075                        self.model.details [name] = ["", param_min, param_max] 
2076                        is_modified = True
2077            try:   
2078                # Check if the textctr is enabled
2079                if item[2].IsEnabled():
2080                    value= float(item[2].GetValue())
2081                    item[2].SetBackgroundColour("white")
2082                    # If the value of the parameter has changed,
2083                    # +update the model and set the is_modified flag
2084                    if value != self.model.getParam(name) and \
2085                                                numpy.isfinite(value):
2086                        self.model.setParam(name, value)
2087                       
2088            except:
2089                item[2].SetBackgroundColour("pink")
2090                msg = "Wrong Fit parameter value entered "
2091                wx.PostEvent(self.parent.parent, StatusEvent(status = msg))
2092               
2093        return is_modified
2094       
2095 
2096    def _set_dipers_Param(self, event):
2097        """
2098        respond to self.enable_disp and self.disable_disp radio box.
2099        The dispersity object is reset inside the model into Gaussian.
2100        When the user select yes , this method display a combo box for more selection
2101        when the user selects No,the combo box disappears.
2102        Redraw the model with the default dispersity (Gaussian)
2103        """
2104        #if self.check_invalid_panel():
2105        #    return
2106        ## On selction if no model exists.
2107        if self.model ==None:
2108            self.disable_disp.SetValue(True)
2109            msg="Please select a Model first..."
2110            wx.MessageBox(msg, 'Info')
2111            wx.PostEvent(self._manager.parent, StatusEvent(status=\
2112                            "Polydispersion: %s"%msg))
2113            return
2114
2115        self._reset_dispersity()
2116   
2117        if self.model ==None:
2118            self.model_disp.Hide()
2119            self.sizer4_4.Clear(True)
2120            return
2121
2122        if self.enable_disp.GetValue():
2123            ## layout for model containing no dispersity parameters
2124           
2125            self.disp_list= self.model.getDispParamList()
2126             
2127            if len(self.disp_list)==0 and len(self.disp_cb_dict)==0:
2128                self._layout_sizer_noDipers() 
2129            else:
2130                ## set gaussian sizer
2131                self._on_select_Disp(event=None)
2132        else:
2133            self.sizer4_4.Clear(True)
2134           
2135        ## post state to fit panel
2136        self.save_current_state()
2137        if event !=None:
2138            #self._undo.Enable(True)
2139            event = PageInfoEvent(page = self)
2140            wx.PostEvent(self.parent, event)
2141        #draw the model with the current dispersity
2142        self._draw_model()
2143        self.sizer4_4.Layout()
2144        self.sizer5.Layout()
2145        self.Layout()
2146        self.Refresh()     
2147         
2148       
2149    def _layout_sizer_noDipers(self):
2150        """
2151        Draw a sizer with no dispersity info
2152        """
2153        ix=0
2154        iy=1
2155        self.fittable_param=[]
2156        self.fixed_param=[]
2157        self.orientation_params_disp=[]
2158       
2159        self.sizer4_4.Clear(True)
2160        text = "No polydispersity available for this model"
2161        text = "No polydispersity available for this model"
2162        model_disp = wx.StaticText(self, -1, text)
2163        self.sizer4_4.Add(model_disp,( iy, ix),(1,1), 
2164                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)
2165        self.sizer4_4.Layout()
2166        self.sizer4.Layout()
2167   
2168    def _reset_dispersity(self):
2169        """
2170        put gaussian dispersity into current model
2171        """
2172        if len(self.param_toFit)>0:
2173            for item in self.fittable_param:
2174                if item in self.param_toFit:
2175                    self.param_toFit.remove(item)
2176
2177            for item in self.orientation_params_disp:
2178                if item in self.param_toFit:
2179                    self.param_toFit.remove(item)
2180         
2181        self.fittable_param=[]
2182        self.fixed_param=[]
2183        self.orientation_params_disp=[]
2184        self.values={}
2185        self.weights={}
2186     
2187        from sans.models.dispersion_models import GaussianDispersion, ArrayDispersion
2188        if len(self.disp_cb_dict)==0:
2189            self.save_current_state()
2190            self.sizer4_4.Clear(True)
2191            self.Layout()
2192 
2193            return 
2194        if (len(self.disp_cb_dict)>0) :
2195            for p in self.disp_cb_dict:
2196                # The parameter was un-selected. Go back to Gaussian model (with 0 pts)                   
2197                disp_model = GaussianDispersion()
2198               
2199                self._disp_obj_dict[p] = disp_model
2200                # Set the new model as the dispersion object for the selected parameter
2201                try:
2202                   self.model.set_dispersion(p, disp_model)
2203                except:
2204
2205                    pass
2206
2207        ## save state into
2208        self.save_current_state()
2209        self.Layout() 
2210        self.Refresh()
2211                 
2212    def _on_select_Disp(self,event):
2213        """
2214        allow selecting different dispersion
2215        self.disp_list should change type later .now only gaussian
2216        """
2217        self._set_sizer_dispersion()
2218
2219        ## Redraw the model
2220        self._draw_model() 
2221        #self._undo.Enable(True)
2222        event = PageInfoEvent(page = self)
2223        wx.PostEvent(self.parent, event)
2224       
2225        self.sizer4_4.Layout()
2226        self.sizer4.Layout()
2227        self.SetupScrolling()
2228   
2229    def _on_disp_func(self, event=None): 
2230        """
2231        Select a distribution function for the polydispersion
2232       
2233        :Param event: ComboBox event
2234        """
2235        # get ready for new event
2236        if event != None:
2237            event.Skip()
2238        # Get event object
2239        disp_box =  event.GetEventObject() 
2240
2241        # Try to select a Distr. function
2242        try:   
2243            disp_box.SetBackgroundColour("white")
2244            selection = disp_box.GetCurrentSelection()
2245            param_name = disp_box.Name.split('.')[0]
2246            disp_name = disp_box.GetValue()
2247            dispersity= disp_box.GetClientData(selection)
2248   
2249            #disp_model =  GaussianDispersion()
2250            disp_model = dispersity()
2251            # Get param names to reset the values of the param
2252            name1 = param_name + ".width"
2253            name2 = param_name + ".npts"
2254            name3 = param_name + ".nsigmas"
2255            # Check Disp. function whether or not it is 'array'
2256            if disp_name.lower() == "array":
2257                value2= ""
2258                value3= ""
2259                value1 = self._set_array_disp(name=name1, disp=disp_model)
2260            else:
2261                self._del_array_values(name1)
2262                #self._reset_array_disp(param_name)
2263                self._disp_obj_dict[name1] = disp_model
2264                self.model.set_dispersion(param_name, disp_model)
2265                self.state._disp_obj_dict[name1]= disp_model
2266 
2267                value1= str(format_number(self.model.getParam(name1), True))
2268                value2= str(format_number(self.model.getParam(name2)))
2269                value3= str(format_number(self.model.getParam(name3)))
2270            # Reset fittable polydispersin parameter value
2271            for item in self.fittable_param:
2272                 if item[1] == name1:
2273                    item[2].SetValue(value1) 
2274                    item[5].SetValue("")
2275                    item[6].SetValue("")
2276                    # Disable for array
2277                    if disp_name.lower() == "array":
2278                        item[0].SetValue(False)
2279                        item[0].Disable()
2280                        item[2].Disable()
2281                        item[5].Disable()
2282                        item[6].Disable()
2283                    else:
2284                        item[0].Enable()
2285                        item[2].Enable()
2286                        item[5].Enable()
2287                        item[6].Enable()                       
2288                    break
2289            # Reset fixed polydispersion params
2290            for item in self.fixed_param:
2291                if item[1] == name2:
2292                    item[2].SetValue(value2) 
2293                    # Disable Npts for array
2294                    if disp_name.lower() == "array":
2295                        item[2].Disable()
2296                    else:
2297                        item[2].Enable()
2298                if item[1] == name3:
2299                    item[2].SetValue(value3) 
2300                    # Disable Nsigs for array
2301                    if disp_name.lower() == "array":
2302                        item[2].Disable()
2303                    else:
2304                        item[2].Enable()
2305               
2306            # Make sure the check box updated when all checked
2307            if self.cb1.GetValue():
2308                self.select_all_param(None)
2309
2310            # update params
2311            self._update_paramv_on_fit() 
2312            # draw
2313            self._draw_model()
2314            self.Refresh()
2315        except:
2316            # Error msg
2317            msg = "Error occurred:"
2318            msg += " Could not select the distribution function..."
2319            msg += " Please select another distribution function."
2320            disp_box.SetBackgroundColour("pink")
2321            # Focus on Fit button so that users can see the pinky box
2322            self.btFit.SetFocus()
2323            wx.PostEvent(self.parent.parent, 
2324                         StatusEvent(status=msg, info="error"))
2325       
2326       
2327    def _set_array_disp(self, name=None, disp=None):
2328        """
2329        Set array dispersion
2330       
2331        :param name: name of the parameter for the dispersion to be set
2332        :param disp: the polydisperion object
2333        """
2334        # The user wants this parameter to be averaged.
2335        # Pop up the file selection dialog.
2336        path = self._selectDlg()
2337        # Array data
2338        values = []
2339        weights = []
2340        # If nothing was selected, just return
2341        if path is None:
2342            self.disp_cb_dict[name].SetValue(False)
2343            #self.noDisper_rbox.SetValue(True)
2344            return
2345        self._default_save_location = os.path.dirname(path)
2346
2347        basename  = os.path.basename(path)
2348        values,weights = self.read_file(path)
2349       
2350        # If any of the two arrays is empty, notify the user that we won't
2351        # proceed
2352        if len(self.param_toFit)>0:
2353            if name in self.param_toFit:
2354                self.param_toFit.remove(name)
2355
2356        # Tell the user that we are about to apply the distribution
2357        msg = "Applying loaded %s distribution: %s" % (name, path)
2358        wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
2359
2360        disp.set_weights(values, weights)
2361        self._disp_obj_dict[name] = disp
2362        self.model.set_dispersion(name.split('.')[0], disp)
2363        self.state._disp_obj_dict[name]= disp
2364        self.values[name] = values
2365        self.weights[name] = weights
2366        # Store the object to make it persist outside the
2367        # scope of this method
2368        #TODO: refactor model to clean this up?
2369        self.state.values = {}
2370        self.state.weights = {}
2371        self.state.values = copy.deepcopy(self.values)
2372        self.state.weights = copy.deepcopy(self.weights)
2373
2374        # Set the new model as the dispersion object for the
2375        #selected parameter
2376        #self.model.set_dispersion(p, disp_model)
2377        # Store a reference to the weights in the model object
2378        #so that
2379        # it's not lost when we use the model within another thread.
2380        #TODO: total hack - fix this
2381        self.state.model= self.model.clone()
2382        self.model._persistency_dict[name.split('.')[0]] = \
2383                                        [values, weights]
2384        self.state.model._persistency_dict[name.split('.')[0]] = \
2385                                        [values,weights]
2386        return basename
2387   
2388    def _del_array_values(self, name=None): 
2389        """
2390        Reset array dispersion
2391       
2392        :param name: name of the parameter for the dispersion to be set
2393        """
2394        # Try to delete values and weight of the names array dic if exists
2395        try:
2396            del self.values[name]
2397            del self.weights[name]
2398            # delete all other dic
2399            del self.state.values[name]
2400            del self.state.weights[name]
2401            del self.model._persistency_dict[name.split('.')[0]] 
2402            del self.state.model._persistency_dict[name.split('.')[0]]
2403        except:
2404            pass
2405                                           
2406    def _lay_out(self):
2407        """
2408        returns self.Layout
2409       
2410        :Note: Mac seems to like this better when self.
2411            Layout is called after fitting.
2412        """
2413        self._sleep4sec()
2414        self.Layout()
2415        return 
2416   
2417    def _sleep4sec(self):
2418        """
2419            sleep for 1 sec only applied on Mac
2420            Note: This 1sec helps for Mac not to crash on self.:ayout after self._draw_model
2421        """
2422        if ON_MAC == True:
2423            time.sleep(1)
2424           
2425    def _find_polyfunc_selection(self, disp_func = None):
2426        """
2427        FInd Comboox selection from disp_func
2428       
2429        :param disp_function: dispersion distr. function
2430        """
2431        # List of the poly_model name in the combobox
2432        list = ["RectangleDispersion", "ArrayDispersion", 
2433                    "LogNormalDispersion", "GaussianDispersion", 
2434                    "SchulzDispersion"]
2435
2436        # Find the selection
2437        try:
2438            selection = list.index(disp_func.__class__.__name__)
2439            return selection
2440        except:
2441             return 3
2442                           
2443    def on_reset_clicked(self,event):
2444        """
2445        On 'Reset' button  for Q range clicked
2446        """
2447        flag = True
2448        #if self.check_invalid_panel():
2449        #    return
2450        ##For 3 different cases: Data2D, Data1D, and theory
2451        if self.model == None:
2452            msg="Please select a model first..."
2453            wx.MessageBox(msg, 'Info')
2454            flag = False
2455            return
2456           
2457        elif self.data.__class__.__name__ == "Data2D":
2458            data_min= 0
2459            x= max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
2460            y= max(math.fabs(self.data.ymin), math.fabs(self.data.ymax))
2461            self.qmin_x = data_min
2462            self.qmax_x = math.sqrt(x*x + y*y)
2463            # check smearing
2464            if not self.disable_smearer.GetValue():
2465                temp_smearer= self.current_smearer
2466                ## set smearing value whether or not the data contain the smearing info
2467                if self.pinhole_smearer.GetValue():
2468                    flag = self.update_pinhole_smear()
2469                else:
2470                    flag = True
2471                   
2472        elif self.data == None:
2473            self.qmin_x = _QMIN_DEFAULT
2474            self.qmax_x = _QMAX_DEFAULT
2475            self.num_points = _NPTS_DEFAULT           
2476            self.state.npts = self.num_points
2477           
2478        elif self.data.__class__.__name__ != "Data2D":
2479            self.qmin_x = min(self.data.x)
2480            self.qmax_x = max(self.data.x)
2481            # check smearing
2482            if not self.disable_smearer.GetValue():
2483                temp_smearer= self.current_smearer
2484                ## set smearing value whether or not the data contain the smearing info
2485                if self.slit_smearer.GetValue():
2486                    flag = self.update_slit_smear()
2487                elif self.pinhole_smearer.GetValue():
2488                    flag = self.update_pinhole_smear()
2489                else:
2490                    flag = True
2491        else:
2492            flag = False
2493           
2494        if flag == False:
2495            msg= "Cannot Plot :Must enter a number!!!  "
2496            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
2497        else:
2498            # set relative text ctrs.
2499            self.qmin.SetValue(str(self.qmin_x))
2500            self.qmax.SetValue(str(self.qmax_x))
2501            self.set_npts2fit()
2502            # At this point, some button and variables satatus (disabled?) should be checked
2503            # such as color that should be reset to white in case that it was pink.
2504            self._onparamEnter_helper()
2505
2506        self.save_current_state()
2507        self.state.qmin = self.qmin_x
2508        self.state.qmax = self.qmax_x
2509       
2510        #reset the q range values
2511        self._reset_plotting_range(self.state)
2512        #self.compute_chisqr(smearer=self.current_smearer)
2513        #Re draw plot
2514        self._draw_model()
2515       
2516    def get_images(self):
2517        """
2518        Get the images of the plots corresponding this panel for report
2519       
2520        : return graphs: list of figures
2521        : TODO: Move to guiframe
2522        """
2523        # set list of graphs
2524        graphs = []
2525        canvases = []
2526        # call gui_manager
2527        gui_manager = self.parent.parent
2528        # loops through the panels [dic]
2529        for item1, item2 in gui_manager.panels.iteritems():
2530             data_title = self.data.group_id
2531             data_name = str(self.data.name).split(" [")[0]
2532            # try to get all plots belonging to this control panel
2533             try:
2534                 title = ''
2535                 # check titles (main plot)
2536                 if hasattr(item2,"data2D"):
2537                     title = item2.data2D.title
2538                 # and data_names (model plot[2D], and residuals)
2539                 if item2.group_id == data_title or \
2540                                title.count(data_name) or \
2541                                item2.window_name.count(data_name) or \
2542                                item2.window_caption.count(data_name):
2543                     #panel = gui_manager._mgr.GetPane(item2.window_name)
2544                     # append to the list
2545                     graphs.append(item2.figure) 
2546                     canvases.append(item2.canvas)     
2547             except:
2548                 # Not for control panels
2549                 pass
2550        # return the list of graphs
2551        return graphs, canvases
2552
2553    def on_model_help_clicked(self,event):
2554        """
2555        on 'More details' button
2556        """
2557        from help_panel import  HelpWindow
2558        import sans.models as models 
2559       
2560        # Get models help model_function path
2561        path = models.get_data_path(media='media')
2562        model_path = os.path.join(path,"model_functions.html")
2563        if self.model == None:
2564            name = 'FuncHelp'
2565        else:
2566            name = self.formfactorbox.GetValue()
2567            #name = self.model.__class__.__name__
2568        frame = HelpWindow(None, -1,  pageToOpen=model_path)   
2569        frame.Show(True)
2570        if frame.rhelp.HasAnchor(name):
2571            frame.rhelp.ScrollToAnchor(name)
2572        else:
2573           msg= "Model does not contains an available description "
2574           msg +="Please try searching in the Help window"
2575           wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))     
2576   
2577    def on_pd_help_clicked(self, event):
2578        """
2579        Button event for PD help
2580        """
2581        from help_panel import  HelpWindow
2582        import sans.models as models 
2583       
2584        # Get models help model_function path
2585        path = models.get_data_path(media='media')
2586        pd_path = os.path.join(path,"pd_help.html")
2587
2588        frame = HelpWindow(None, -1,  pageToOpen=pd_path)   
2589        frame.Show(True)
2590       
2591    def on_left_down(self, event):
2592        """
2593        Get key stroke event
2594        """
2595        # Figuring out key combo: Cmd for copy, Alt for paste
2596        if event.CmdDown() and event.ShiftDown():
2597            flag = self.get_paste()
2598        elif event.CmdDown():
2599            flag = self.get_copy()
2600        else:
2601            event.Skip()
2602            return
2603        # make event free
2604        event.Skip()
2605        # messages depending on the flag
2606        if flag == None:
2607            msg = " Parameter values are copied to the clipboard..."
2608            infor = 'warning'
2609        elif flag:
2610            msg = " Parameter values are pasted from the clipboad..."
2611            infor = "warning"
2612        else:
2613            msg = "Error was occured during pasting the parameter values "
2614            msg += "from the clipboard..."
2615            infor = "error"
2616        # inform msg to wx
2617        wx.PostEvent( self.parent.parent, 
2618                      StatusEvent(status= msg, info=infor))
2619       
2620           
2621    def get_copy(self): 
2622        """
2623        Get the string copies of the param names and values in the tap
2624        """ 
2625        content = 'sansview_parameter_values:'
2626        # Do it if params exist       
2627        if  self.parameters !=[]:
2628           
2629            # go through the parameters
2630            string = self._get_copy_helper(self.parameters, 
2631                                           self.orientation_params)
2632            content += string
2633           
2634            # go through the fittables
2635            string = self._get_copy_helper(self.fittable_param, 
2636                                           self.orientation_params_disp)
2637            content += string
2638
2639            # go through the fixed params
2640            string = self._get_copy_helper(self.fixed_param, 
2641                                           self.orientation_params_disp)
2642            content += string
2643               
2644            # go through the str params
2645            string = self._get_copy_helper(self.str_parameters, 
2646                                           self.orientation_params)
2647            content += string
2648
2649        if wx.TheClipboard.Open():
2650            wx.TheClipboard.SetData(wx.TextDataObject(str(content)))
2651            data = wx.TextDataObject()
2652            success = wx.TheClipboard.GetData(data)
2653            text = data.GetText()
2654            wx.TheClipboard.Close()
2655           
2656        return None
2657   
2658    def _get_copy_helper(self, param, orient_param):
2659        """
2660        Helping get value and name of the params
2661       
2662        : param param:  parameters
2663        : param orient_param = oritational params
2664        : return content: strings [list] [name,value:....]
2665        """
2666        content = ''
2667        # go through the str params
2668        for item in param: 
2669            # 2D
2670            if self.data.__class__.__name__== "Data2D":
2671                name = item[1]
2672                value = item[2].GetValue()
2673            # 1D
2674            else:
2675                ## for 1D all parameters except orientation
2676                if not item[1] in orient_param:
2677                    name = item[1]
2678                    value = item[2].GetValue()
2679            # add to the content
2680            content += name + ',' + value + ':'
2681           
2682        return content
2683   
2684    def get_paste(self): 
2685        """
2686        Get the string copies of the param names and values in the tap
2687        """ 
2688        context = {}
2689        text = ""
2690       
2691        # Get text from the clip board       
2692        if wx.TheClipboard.Open():
2693            if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)):
2694                data = wx.TextDataObject()
2695                # get wx dataobject
2696                success = wx.TheClipboard.GetData(data)
2697                # get text
2698                text = data.GetText()
2699            # close clipboard
2700            wx.TheClipboard.Close()
2701           
2702        # put the text into dictionary   
2703        lines = text.split(':')
2704        if lines[0] != 'sansview_parameter_values':
2705            return False
2706        for line in lines[1:-1]:
2707            if len(line) != 0:
2708                item =line.split(',')
2709                name = item[0]
2710                value = item[1]
2711                # Transfer the text to content[dictionary]
2712                context[name] = value
2713       
2714        # Do it if params exist       
2715        if  self.parameters != []:
2716            # go through the parameters 
2717            self._get_paste_helper(self.parameters, 
2718                                   self.orientation_params, context)
2719
2720            # go through the fittables
2721            self._get_paste_helper(self.fittable_param, 
2722                                   self.orientation_params_disp, context)
2723
2724            # go through the fixed params
2725            self._get_paste_helper(self.fixed_param, 
2726                                   self.orientation_params_disp, context)
2727           
2728            # go through the str params
2729            self._get_paste_helper(self.str_parameters, 
2730                                   self.orientation_params, context)
2731           
2732        return True
2733   
2734    def _get_paste_helper(self, param, orient_param, content):
2735        """
2736        Helping set values of the params
2737       
2738        : param param:  parameters
2739        : param orient_param: oritational params
2740        : param content: dictionary [ name, value: name1.value1,...]
2741        """
2742        # go through the str params
2743        for item in param: 
2744            # 2D
2745            if self.data.__class__.__name__== "Data2D":
2746                name = item[1]
2747                if name in content.keys():
2748                    item[2].SetValue(content[name])
2749            # 1D
2750            else:
2751                ## for 1D all parameters except orientation
2752                if not item[1] in orient_param:
2753                    name = item[1]
2754                    if name in content.keys():
2755                        # Avoid changing combox content which needs special care
2756                        if item[2].__class__.__name__ != "ComboBox":
2757                            item[2].SetValue(content[name])
2758                           
2759               
Note: See TracBrowser for help on using the repository browser.