source: sasview/sansview/perspectives/fitting/basepage.py @ 37e0e5d

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

removed setfocusignoringchild

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