source: sasview/sansview/perspectives/fitting/basepage.py @ 4a74847

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 4a74847 was 6d8053c, checked in by Jae Cho <jhjcho@…>, 14 years ago

fixed aminor plot problem and default NPTS

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