source: sasview/sansview/perspectives/fitting/fitpage.py @ 328c328

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 328c328 was d493f66, checked in by Jae Cho <jhjcho@…>, 15 years ago

found and fixed minor bugs: 1)remaining unchanged the smearer option checked if already checked on the empty fit panel before data for fitting selected, 2) Error on resetting the page from bookmark

  • Property mode set to 100644
File size: 90.5 KB
RevLine 
[d1e0473]1
2
[c77d859]3import sys
4import wx
5import wx.lib.newevent
6import numpy
7import copy
8import math
[7975f2b]9import time
[c77d859]10from sans.models.dispersion_models import ArrayDispersion, GaussianDispersion
[7609f1a]11from DataLoader.data_info import Data1D
[c77d859]12from sans.guicomm.events import StatusEvent   
[85b3971]13from sans.guiframe.utils import format_number,check_float
[7609f1a]14
[b787e68c]15## event to post model to fit to fitting plugins
[c77d859]16(ModelEventbox, EVT_MODEL_BOX) = wx.lib.newevent.NewEvent()
[b787e68c]17
18## event to know the selected fit engine
[77e23a2]19(FitterTypeEvent, EVT_FITTER_TYPE)   = wx.lib.newevent.NewEvent()
[34a0c17]20(FitStopEvent, EVT_FIT_STOP)   = wx.lib.newevent.NewEvent()
[eda428b]21_BOX_WIDTH = 76
[9237df4]22_DATA_BOX_WIDTH = 300
[7609f1a]23SMEAR_SIZE_L = 0.005
24SMEAR_SIZE_H = 0.01
25
[c77d859]26import basepage
27from basepage import BasicPage
[b787e68c]28from basepage import PageInfoEvent
[997131a]29from DataLoader.qsmearing import smear_selection
[c77d859]30
31class FitPage(BasicPage):
32    """
33        FitPanel class contains fields allowing to display results when
34        fitting  a model and one data
35        @note: For Fit to be performed the user should check at least one parameter
36        on fit Panel window.
37 
38    """
[7975f2b]39   
[cfc0913]40    def __init__(self,parent, page_info):
41        BasicPage.__init__(self, parent, page_info)
[7975f2b]42
[c77d859]43        """
44            Initialization of the Panel
45        """
46        ## fit page does not content npts txtcrtl
47        self.npts=None
[2b63df0]48        ## thread for compute Chisqr
49        self.calc_Chisqr=None
[dcf29d7]50        ## default fitengine type
[707436d]51        self.engine_type = None
[7609f1a]52        ## smear default
53        self.smearer = None
54        self.current_smearer = None
55        self.dxl = None
56        self.dxw = None
57        self.dx_min = None
58        self.dx_max = None
[edd166b]59       
[b787e68c]60        ## draw sizer
[c77d859]61        self._fill_datainfo_sizer()
[7609f1a]62       
63        # get smear info from data
64        self._get_smear_info()
65       
[c77d859]66        self._fill_model_sizer( self.sizer1)
[7609f1a]67       
68        self._get_defult_custom_smear()
69       
[cfc0913]70        self._fill_range_sizer() 
[7609f1a]71       
[ffa69b6]72        if self.data is None:
73            self.formfactorbox.Disable()
74            self.structurebox.Disable()
75        else:
[7609f1a]76            self.smearer = smear_selection( self.data )
[847091f]77            if self.smearer ==None:
78                self.enable_smearer.Disable()
[7609f1a]79                #self.disable_smearer.Disable()
80
[edd166b]81        self.disp_cb_dict = {}
[cfc0913]82        ## to update the panel according to the fit engine type selected
[77e23a2]83        self.Bind(EVT_FITTER_TYPE,self._on_engine_change)
[34a0c17]84        self.Bind(EVT_FIT_STOP,self._on_fit_complete)
[ffa69b6]85       
[c69b6d5]86
[34a0c17]87    def _on_fit_complete(self, event):
88        """
89            When fit is complete ,reset the fit button label.
90        """
91        #self.btFit.SetLabel("Fit")
92        #self.btFit.Unbind(event=wx.EVT_BUTTON, id=self.btFit.GetId())
93        #self.btFit.Bind(event=wx.EVT_BUTTON, handler=self._onFit,id=self.btFit.GetId())
94        pass
95       
96       
[77e23a2]97    def _on_engine_change(self, event):
98        """
99            get an event containing the current name of the fit engine type
100            @param event: FitterTypeEvent containing  the name of the current engine
101        """
[dcf29d7]102        self.engine_type = event.type
[77e23a2]103        if len(self.parameters)==0:
[edd166b]104            self.Layout()
[77e23a2]105            return
[ad6dd4c]106        if event.type =="park":
107            self.btFit.SetLabel("Fit")
[6d91073]108
[77e23a2]109        for item in self.parameters:
[920a6e5]110            if event.type =="scipy" :
[60132ef]111                item[5].SetValue("")
[77e23a2]112                item[5].Hide()
[60132ef]113                item[6].SetValue("")
[77e23a2]114                item[6].Hide()
115                self.text2_min.Hide()
116                self.text2_max.Hide()
[7975f2b]117
[77e23a2]118            else:
119                item[5].Show(True)
120                item[6].Show(True)
121                self.text2_min.Show(True)
122                self.text2_max.Show(True)
[920a6e5]123        for item in self.fittable_param:
124            if item[5]!=None and item[6]!=None and not item in self.orientation_params_disp:
125                if event.type =="scipy" and not item in self.orientation_params:
[c5cd3b9]126                    item[5].SetValue("")
127                    item[5].Hide()
128                    item[6].SetValue("")
129                    item[6].Hide()
130                    self.text2_min.Hide()
131                    self.text2_max.Hide()
[920a6e5]132                    self.text_disp_min.Hide()
133                    self.text_disp_max.Hide()
[c5cd3b9]134                else:
135                    item[5].Show(True)
136                    item[6].Show(True)
137                    self.text2_min.Show(True)
138                    self.text2_max.Show(True)
[920a6e5]139                    self.text_disp_min.Show(True)
140                    self.text_disp_max.Show(True)
[c5cd3b9]141           
[920a6e5]142        for item in self.orientation_params:
[c5cd3b9]143            if item[5]!=None and item[6]!=None:
144                if event.type =="scipy" or self.data.__class__.__name__ !="Data2D":
145                    item[5].SetValue("")
146                    item[5].Hide()
147                    item[6].SetValue("")
148                    item[6].Hide()
149                else:
150                    item[5].Show(True)
151                    item[6].Show(True)
[920a6e5]152                   
153        for item in self.orientation_params_disp:         
154            if item[5]!=None and item[6]!=None:
155                if event.type =="scipy" or self.data.__class__.__name__ !="Data2D":
156                    item[5].SetValue("")
157                    item[5].Hide()
158                    item[6].SetValue("")
159                    item[6].Hide()
160                else:
161                    item[5].Show(True)
162                    item[6].Show(True)
[6d91073]163        self.Layout()
[7975f2b]164        self.Refresh()
165
[c77d859]166    def _fill_range_sizer(self):
167        """
168            Fill the sizer containing the plotting range
169            add  access to npts
170        """
[ff8f99b]171        title = "Fitting"
[7609f1a]172        #smear messages & titles
173        smear_message_none  =  "No smearing is selected..."
174        smear_message_dqdata  =  "The dQ data is being used for smearing..."
175        smear_message_2d  =  "No smearing is supported for 2D model fitting..."
176        smear_message_new_ssmear  =  "Please enter only the value of interest to customize smearing..."
177        smear_message_new_psmear  =  "Please enter both; the dQ will be generated by interpolation..."
178        smear_message_pinhole_min_title = "dQ_min[1/A]:"
179        smear_message_pinhole_max_title = "dQ_max[1/A]:"
180        smear_message_slit_height_title = "Slit height[1/A]:"
181        smear_message_slit_width_title = "Slit width[1/A]:"
182       
183        self._get_smear_info()
184
[ff8f99b]185        box_description_range = wx.StaticBox(self, -1,str(title))
186        boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL)
187
[1ae3fe1]188        sizer_fit = wx.GridSizer(1, 1,0, 0)
[c77d859]189   
[e3a76c8]190        self.btFit = wx.Button(self,wx.NewId(),'Fit', size=(80,23))
[c77d859]191        self.btFit.Bind(wx.EVT_BUTTON, self._onFit,id= self.btFit.GetId())
192        self.btFit.SetToolTipString("Perform fit.")
[2d5f7a1]193     
[c77d859]194       
[d493f66]195
[7609f1a]196        self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL)
[c77d859]197        sizer_smearer = wx.BoxSizer(wx.HORIZONTAL)
[7609f1a]198        self.sizer_new_smear= wx.BoxSizer(wx.HORIZONTAL)
199        self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL)
200        sizer_chi2 = wx.BoxSizer(wx.VERTICAL)
201        smear_set_box= wx.StaticBox(self, -1,'Set Instrumental Smearing')
202        sizer_smearer_box = wx.StaticBoxSizer(smear_set_box, wx.HORIZONTAL)
203        sizer_smearer_box.SetMinSize((_DATA_BOX_WIDTH,85))
204       
205        #textcntrl for new resolution
206        self.smear_pinhole_max = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
207                                            text_enter_callback = self.onPinholeSmear)
208        self.smear_pinhole_min = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
209                                            text_enter_callback = self.onPinholeSmear)
210        self.smear_slit_height= self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
211                                            text_enter_callback = self.onSlitSmear)
212        self.smear_slit_width = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
213                                            text_enter_callback = self.onSlitSmear)
214        self.smear_data_left= BGTextCtrl(self, -1, size=(_BOX_WIDTH-20,20), style=0)
215        self.smear_data_left.SetValue(str(self.dq_l))
216        self.smear_data_right = BGTextCtrl(self, -1, size=(_BOX_WIDTH-20,20), style=0)
217        self.smear_data_right.SetValue(str(self.dq_r))
218
219        #set default values
220        self.smear_pinhole_max.SetValue(str(self.dx_max))
221        self.smear_pinhole_min.SetValue(str(self.dx_min))
222        self.smear_slit_height.SetValue(str(self.dxl))
223        self.smear_slit_width.SetValue(str(self.dxw))
224
[c77d859]225        #Filling the sizer containing instruments smearing info.
[7609f1a]226        self.disable_smearer = wx.RadioButton(self, -1, 'None', style=wx.RB_GROUP)
227        self.enable_smearer = wx.RadioButton(self, -1, 'Use dQ Data')
228        #self.enable_smearer.SetToolTipString("Click to use the loaded dQ data for smearing.")
229        self.pinhole_smearer = wx.RadioButton(self, -1, 'Custom Pinhole Smear')
230        #self.pinhole_smearer.SetToolTipString("Click to input custom resolution for pinhole smearing.")
231        self.slit_smearer = wx.RadioButton(self, -1, 'Custom Slit Smear')
232        #self.slit_smearer.SetToolTipString("Click to input custom resolution for slit smearing.")
[c77d859]233        self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.disable_smearer.GetId())
234        self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.enable_smearer.GetId())
[7609f1a]235        self.Bind(wx.EVT_RADIOBUTTON, self.onPinholeSmear, id=self.pinhole_smearer.GetId())
236        self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, id=self.slit_smearer.GetId())
[ff8f99b]237        self.disable_smearer.SetValue(True)
[c77d859]238       
[7609f1a]239        # add 4 types of smearing to the sizer
240        sizer_smearer.Add( self.disable_smearer,0, wx.LEFT, 10)
[c77d859]241        sizer_smearer.Add((10,10))
[7609f1a]242        sizer_smearer.Add( self.enable_smearer)
243        sizer_smearer.Add((10,10))
244        sizer_smearer.Add( self.pinhole_smearer ) 
245        sizer_smearer.Add((10,10))
246        sizer_smearer.Add( self.slit_smearer ) 
247        sizer_smearer.Add((10,10))       
248       
249        # static box for chi2
[7b0fd65]250        box_description= wx.StaticBox(self, -1,'Chi2/dof')
251        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
[7609f1a]252        boxsizer1.SetMinSize((70,40))
253       
[2b63df0]254       
[7609f1a]255       
256        # StaticText for chi2 and smear
[2b63df0]257        self.tcChi    =  wx.StaticText(self, -1, "-", style=wx.ALIGN_LEFT)
[7609f1a]258        self.smear_description_none    =  wx.StaticText(self, -1, smear_message_none , style=wx.ALIGN_LEFT)
259        self.smear_description_dqdata    =  wx.StaticText(self, -1, smear_message_dqdata , style=wx.ALIGN_LEFT)
260        self.smear_description_type    =  wx.StaticText(self, -1, "Type:" , style=wx.ALIGN_LEFT)
261        self.smear_description_smear_type    =  BGTextCtrl(self, -1, size=(45,20), style=0)
262        self.smear_description_smear_type.SetValue(str(self.dq_l))
263        self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
264        self.smear_description_2d     =  wx.StaticText(self, -1, smear_message_2d  , style=wx.ALIGN_LEFT)
265        self.smear_message_new_s = wx.StaticText(self, -1, smear_message_new_ssmear  , style=wx.ALIGN_LEFT)
266        self.smear_message_new_p = wx.StaticText(self, -1, smear_message_new_psmear  , style=wx.ALIGN_LEFT)
267        self.smear_description_pin_min     =  wx.StaticText(self, -1, smear_message_pinhole_min_title  , style=wx.ALIGN_LEFT)
268        self.smear_description_pin_max     =  wx.StaticText(self, -1, smear_message_pinhole_max_title  , style=wx.ALIGN_LEFT)
269        self.smear_description_slit_height    =  wx.StaticText(self, -1, smear_message_slit_height_title   , style=wx.ALIGN_LEFT)
270        self.smear_description_slit_width    =  wx.StaticText(self, -1, smear_message_slit_width_title   , style=wx.ALIGN_LEFT)
271       
272        #arrange sizers
273        boxsizer1.Add( self.tcChi ) 
274        self.sizer_set_smearer.Add(sizer_smearer )
275        self.sizer_set_smearer.Add((10,10))
276        self.sizer_set_smearer.Add( self.smear_description_none,0, wx.CENTER, 10 ) 
277        self.sizer_set_smearer.Add( self.smear_description_dqdata,0, wx.CENTER, 10 )
278        self.sizer_set_smearer.Add( self.smear_description_2d,0, wx.CENTER, 10 )
279        self.sizer_new_smear.Add( self.smear_description_type,0, wx.CENTER, 10 )
280        self.sizer_new_smear.Add( self.smear_description_smear_type,0, wx.CENTER, 10 )
281        self.sizer_new_smear.Add((15,-1))
282        self.sizer_new_smear.Add( self.smear_description_pin_min,0, wx.CENTER, 10 )
283        self.sizer_new_smear.Add( self.smear_description_slit_height,0, wx.CENTER, 10 )
284        self.sizer_new_smear.Add( self.smear_pinhole_min,0, wx.CENTER, 10 )
285        self.sizer_new_smear.Add( self.smear_slit_height,0, wx.CENTER, 10 )
286        self.sizer_new_smear.Add( self.smear_data_left,0, wx.CENTER, 10 )
287        self.sizer_new_smear.Add((20,-1))
288        self.sizer_new_smear.Add( self.smear_description_pin_max,0, wx.CENTER, 10 )
289        self.sizer_new_smear.Add( self.smear_description_slit_width,0, wx.CENTER, 10 )
290        self.sizer_new_smear.Add( self.smear_pinhole_max,0, wx.CENTER, 10 )
291        self.sizer_new_smear.Add( self.smear_slit_width,0, wx.CENTER, 10 )
292        self.sizer_new_smear.Add( self.smear_data_right,0, wx.CENTER, 10 )
293           
294        self.sizer_set_smearer.Add( self.smear_message_new_s,0, wx.CENTER, 10)
295        self.sizer_set_smearer.Add( self.smear_message_new_p,0, wx.CENTER, 10)
296        self.sizer_set_smearer.Add((5,2))
297        self.sizer_set_smearer.Add( self.sizer_new_smear,0, wx.CENTER, 10 )
298       
299        # add all to chi2 sizer
300       
301        sizer_smearer_box.Add(self.sizer_set_smearer) 
302       
303        sizer_chi2.Add(sizer_smearer_box)
304        sizer_chi2.Add((-1,5))
305        self.sizer_set_masking.Add((305,-1))
[d493f66]306        #self.sizer_set_masking.Add(boxsizer1,0, wx.RIGHT, 10)
[7609f1a]307        sizer_chi2.Add(self.sizer_set_masking )
[d493f66]308         
309        sizer_fit.Add(boxsizer1,0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 63)
310        #sizer_fit.Add((-1,1),0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 1)
311        sizer_fit.Add(self.btFit,0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 63) 
312        sizer_fit.Layout()
[7609f1a]313        #sizer_smearer_box.Add(sizer_chi2)
314        # hide all smear messages and textctrl
315        self._hide_all_smear_info()
316       
317        # get smear_selection
318        self.current_smearer= smear_selection( self.data )
[83ad478]319
[7609f1a]320        # Show only the relevant smear messages, etc
321        if self.current_smearer == None:
322            if self.data.__class__.__name__ != 'Data2D':
323                self.smear_description_none.Show(True)
324                self.enable_smearer.Disable() 
325            else:
326                self.smear_description_2d.Show(True) 
327                self.pinhole_smearer.Disable() 
328                self.slit_smearer.Disable()   
329                self.enable_smearer.Disable() 
330        else: self._show_smear_sizer()
331 
332           
333        #Set sizer for Fitting section
334        self._set_range_sizer( title=title,box_sizer=boxsizer_range, object1=sizer_chi2, object= sizer_fit)
335       
[c77d859]336    def _fill_datainfo_sizer(self):
337        """
338            fill sizer 0 with data info
339        """
340        ## no loaded data , don't fill the sizer
[9237df4]341        if self.data is None:
342            data_min = ""
343            data_max = ""
344            data_name = ""
345        else:
346            data_name = self.data.name
347            #set maximum range for x in linear scale
348            if not hasattr(self.data,"data"): #Display only for 1D data fit
349                # Minimum value of data   
350                data_min = min(self.data.x)
351                # Maximum value of data 
352                data_max = max(self.data.x)
353            else:
354                ## Minimum value of data
355                data_min = 0
356                x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
357                y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax))
358                ## Maximum value of data 
359                data_max = math.sqrt(x*x + y*y)
[c77d859]360       
[fa58441]361        box_description= wx.StaticBox(self, -1, 'Data')
[c77d859]362        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
363        #----------------------------------------------------------
[9237df4]364        sizer_data = wx.BoxSizer(wx.HORIZONTAL)
[c77d859]365        #Filling the sizer containing data related fields
[9237df4]366        #self.dataSource = wx.StaticText(self, -1,str(self.data.name))
[7609f1a]367        self.dataSource = BGTextCtrl(self, -1)
[9237df4]368        self.dataSource.SetValue(str(data_name))
[7609f1a]369        #self.dataSource.SetEditable(False)
[9237df4]370        self.dataSource.SetMinSize((_DATA_BOX_WIDTH, -1))
[fa58441]371        sizer_data.Add(wx.StaticText(self, -1, 'Source Name : '))
[9237df4]372        sizer_data.Add(self.dataSource )
[2a5bba7]373        sizer_data.Add( (0,5) )
[c77d859]374       
375        #---------sizer 2 draw--------------------------------
[9237df4]376        text4_3 = wx.StaticText(self, -1, 'Total Q Range (1/A)',
377                                 style=wx.ALIGN_LEFT)
378        sizer_range = wx.BoxSizer(wx.HORIZONTAL)
379        sizer_range.Add( text4_3 ,0, wx.RIGHT, 10)
[7609f1a]380        self.minimum_q = BGTextCtrl(self, -1, size=(_BOX_WIDTH,20))
[9237df4]381        self.minimum_q.SetValue(str(data_min))
[7609f1a]382        #self.minimum_q.SetEditable(False)
383        self.maximum_q = BGTextCtrl(self, -1,size=(_BOX_WIDTH,20))
[9237df4]384        self.maximum_q.SetValue(str(data_max))
[7609f1a]385        #self.maximum_q.SetEditable(False)
[9237df4]386        sizer_range.Add(wx.StaticText(self, -1, "Min: "),0, wx.LEFT, 10)
387        sizer_range.Add(self.minimum_q,0, wx.LEFT, 10)
388        sizer_range.Add(wx.StaticText(self, -1, "Max: "),0, wx.LEFT, 10)
389        sizer_range.Add(self.maximum_q,0, wx.LEFT, 10)
390
[813334e]391        ## set q range to plot
[9237df4]392        self.qmin_x = data_min
393        self.qmax_x = data_max
[813334e]394
[9237df4]395        boxsizer1.Add(sizer_data,0, wx.ALL, 10)
396        boxsizer1.Add(sizer_range, 0 , wx.LEFT, 10)
[c77d859]397        #------------------------------------------------------------
398        self.sizer0.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
399        self.sizer0.Layout()
[813334e]400       
[c77d859]401    def _fill_model_sizer(self, sizer):
402        """
403            fill sizer containing model info
404        """
[7ad6ff5]405        ##Add model function Details button in fitpanel.
[ff8f99b]406        ##The following 3 lines are for Mac. Let JHC know before modifying...
407        title = "Model"
408        box_description= wx.StaticBox(self, -1,str(title))
409        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
410         
[7ad6ff5]411        id = wx.NewId()
[e3a76c8]412        self.model_help =wx.Button(self,id,'Details', size=(80,23))
[7ad6ff5]413        self.model_help.Bind(wx.EVT_BUTTON, self.on_model_help_clicked,id=id)
414        self.model_help.SetToolTipString("Model Function Help")
[7b0fd65]415       
[7ad6ff5]416        ## class base method  to add view 2d button   
[ff8f99b]417        self._set_model_sizer(sizer=sizer, box_sizer=boxsizer1, title="Model",object=self.model_help )   
[7ad6ff5]418
[c77d859]419   
[30d103a]420    def _set_sizer_dispersion(self, dispersity):
[c77d859]421        """
422            draw sizer with gaussian dispersity parameters
423        """
424        self.fittable_param=[]
425        self.fixed_param=[]
[60132ef]426        self.orientation_params_disp=[]
[920a6e5]427
[c77d859]428        self.sizer4_4.Clear(True)
429        if self.model==None:
430            ##no model is selected
431            return
432        if not self.enable_disp.GetValue():
433            ## the user didn't select dispersity display
434            return 
[b421b1a]435           
[376916c]436        self._reset_dispersity()
[b421b1a]437       
[376916c]438        # Create the dispersion objects
439        for item in self.model.dispersion.keys():
[30d103a]440            #disp_model =  GaussianDispersion()
441            disp_model = dispersity()
[376916c]442            self._disp_obj_dict[item] = disp_model
443            self.model.set_dispersion(item, disp_model)
[c477b31]444            self.state._disp_obj_dict[item]= disp_model
[376916c]445
[b421b1a]446
[c77d859]447        ix=0
448        iy=1
449        disp = wx.StaticText(self, -1, 'Names')
450        self.sizer4_4.Add(disp,( iy, ix),(1,1), 
451                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
452        ix += 1 
[a720d1f]453        values = wx.StaticText(self, -1, 'Sigmas (STD)')
[c77d859]454        self.sizer4_4.Add(values,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
455        ix +=2 
[920a6e5]456        self.text_disp_1 = wx.StaticText(self, -1, '')
[c77d859]457        self.sizer4_4.Add( self.text_disp_1,(iy, ix),(1,1),\
458                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
459        self.text_disp_1.Hide()
[920a6e5]460       
461       
462        ix +=1 
463        self.text_disp_min = wx.StaticText(self, -1, 'Min')
464        self.sizer4_4.Add(self.text_disp_min,(iy, ix),(1,1),\
465                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
466        self.text_disp_min.Hide()
467        ix +=1 
468        self.text_disp_max = wx.StaticText(self, -1, 'Max')
469        self.sizer4_4.Add(self.text_disp_max,(iy, ix),(1,1),\
470                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
471        self.text_disp_max.Hide()
472                       
473       
[c77d859]474        ix += 1 
475        npts = wx.StaticText(self, -1, 'Npts')
476        self.sizer4_4.Add(npts,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
477        ix += 1 
478        nsigmas = wx.StaticText(self, -1, 'Nsigmas')
479        self.sizer4_4.Add(nsigmas,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[920a6e5]480       
481        if self.engine_type=="park":
482            self.text_disp_max.Show(True)
483            self.text_disp_min.Show(True)
[6dc9ad8]484
[c77d859]485        for item in self.model.dispersion.keys():
[780d095]486            if not item in self.model.orientation_params:
[edd166b]487                if not self.disp_cb_dict.has_key(item):
488                    self.disp_cb_dict[item]= None
[780d095]489                name1=item+".width"
490                name2=item+".npts"
491                name3=item+".nsigmas"
[c99a6c5]492                if not self.model.details.has_key(name1):
[b421b1a]493                    self.model.details [name1] = ["",None,None] 
[c99a6c5]494
[780d095]495                iy += 1
496                for p in self.model.dispersion[item].keys(): 
497       
498                    if p=="width":
499                        ix = 0
500                        cb = wx.CheckBox(self, -1, name1, (10, 10))
501                        wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
502                        self.sizer4_4.Add( cb,( iy, ix),(1,1), 
503                                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
504                        ix = 1
505                        value= self.model.getParam(name1)
[7975f2b]506                        ctl1 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
[c77d859]507                                            style=wx.TE_PROCESS_ENTER)
[780d095]508                        ctl1.SetValue(str (format_number(value)))
509                        self.sizer4_4.Add(ctl1, (iy,ix),(1,1),wx.EXPAND)
510                        ## text to show error sign
511                        ix = 2
512                        text2=wx.StaticText(self, -1, '+/-')
513                        self.sizer4_4.Add(text2,(iy, ix),(1,1),
514                                          wx.EXPAND|wx.ADJUST_MINSIZE, 0)
515                        text2.Hide() 
[b421b1a]516
[780d095]517                        ix = 3
[c13b8cc]518                        ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=0)
[eacf1d66]519                 
[780d095]520                        self.sizer4_4.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[eacf1d66]521                     
[b421b1a]522                        ctl2.Hide()
[eacf1d66]523
[920a6e5]524                        ix = 4
[7975f2b]525                        ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
526                                                       text_enter_callback = self._onparamRangeEnter)
[eacf1d66]527
[920a6e5]528                        self.sizer4_4.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
529                        ctl3.Hide()
530               
531                        ix = 5
[7975f2b]532                        ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
533                                                       text_enter_callback = self._onparamRangeEnter)
[920a6e5]534                        self.sizer4_4.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[eacf1d66]535
[920a6e5]536                        ctl4.Hide()
537                       
538                        if self.engine_type=="park":
539                            ctl3.Show(True)
540                            ctl4.Show(True)
541                                         
[780d095]542                        self.fittable_param.append([cb,name1,ctl1,text2,
[c99a6c5]543                                                    ctl2, ctl3, ctl4,None])                   
[920a6e5]544                   
[780d095]545                    elif p=="npts":
[920a6e5]546                            ix = 6
[780d095]547                            value= self.model.getParam(name2)
[7975f2b]548                            Tctl = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
[780d095]549                                                style=wx.TE_PROCESS_ENTER)
550                           
551                            Tctl.SetValue(str (format_number(value)))
552                            self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
553                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
554                            self.fixed_param.append([None,name2, Tctl,None,None,
555                                                      None, None,None])
556                    elif p=="nsigmas":
[920a6e5]557                            ix = 7
[780d095]558                            value= self.model.getParam(name3)
[7975f2b]559                            Tct2 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
[780d095]560                                                style=wx.TE_PROCESS_ENTER)
[c985bef]561                            Tct2.SetValue(str (format_number(value)))
562                            self.sizer4_4.Add(Tct2, (iy,ix),(1,1),
[780d095]563                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
564                            ix +=1
565                            self.sizer4_4.Add((20,20), (iy,ix),(1,1),
566                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
567                           
[c985bef]568                            self.fixed_param.append([None,name3, Tct2
[920a6e5]569                                                     ,None,None,None, None,None])
570                           
[780d095]571        ix =0
572        iy +=1 
573        self.sizer4_4.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 
574        for item in self.model.dispersion.keys():
575            if  item in self.model.orientation_params:
[edd166b]576                if not self.disp_cb_dict.has_key(item):
577                    self.disp_cb_dict[item]= None
[780d095]578                name1=item+".width"
579                name2=item+".npts"
580                name3=item+".nsigmas"
[c99a6c5]581                if not self.model.details.has_key(name1):
[b421b1a]582                    self.model.details [name1] = ["",None,None]                 
583 
584
[780d095]585                iy += 1
586                for p in self.model.dispersion[item].keys(): 
587       
588                    if p=="width":
589                        ix = 0
590                        cb = wx.CheckBox(self, -1, name1, (10, 10))
591                        wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
592                        self.sizer4_4.Add( cb,( iy, ix),(1,1), 
593                                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
594                        if self.data.__class__.__name__ =="Data2D":
[6dc9ad8]595                            cb.Show(True)
[c99a6c5]596                        elif cb.IsShown():
[6dc9ad8]597                            cb.Hide()
[780d095]598                        ix = 1
599                        value= self.model.getParam(name1)
[7975f2b]600                        ctl1 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
[c77d859]601                                            style=wx.TE_PROCESS_ENTER)
[780d095]602                        ctl1.SetValue(str (format_number(value)))
603                        if self.data.__class__.__name__ =="Data2D":
[6dc9ad8]604                            ctl1.Show(True)
[c99a6c5]605                        elif ctl1.IsShown():
[6dc9ad8]606                            ctl1.Hide()
[780d095]607                        self.sizer4_4.Add(ctl1, (iy,ix),(1,1),wx.EXPAND)
608                        ## text to show error sign
609                        ix = 2
610                        text2=wx.StaticText(self, -1, '+/-')
611                        self.sizer4_4.Add(text2,(iy, ix),(1,1),
612                                          wx.EXPAND|wx.ADJUST_MINSIZE, 0)
613                        text2.Hide() 
[b421b1a]614
[780d095]615                        ix = 3
[c13b8cc]616                        ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=0)
[b421b1a]617                   
[780d095]618                        self.sizer4_4.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[b421b1a]619                        ctl2.Hide()
[920a6e5]620                           
621                        ix = 4
[7975f2b]622                        ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
623                                                       text_enter_callback = self._onparamRangeEnter)
[eacf1d66]624
[920a6e5]625                        self.sizer4_4.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[c99a6c5]626
[920a6e5]627                        ctl3.Hide()
628               
629                        ix = 5
[7975f2b]630                        ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
631                                                       text_enter_callback = self._onparamRangeEnter)
[920a6e5]632                        self.sizer4_4.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
633                        ctl4.Hide()
[c99a6c5]634                        #if self.data.__class__.__name__ =="Data2D":
635                            #ctl4.Enable(True)
636                        #elif ctl4.Shown():
637                            #ctl4.Hide()
[920a6e5]638                       
639                        if self.engine_type=="park" and self.data.__class__.__name__ =="Data2D":
640                            ctl3.Show(True)
[c99a6c5]641                            ctl4.Show(True) 
[920a6e5]642                           
643                           
644                           
645                           
[780d095]646                        self.fittable_param.append([cb,name1,ctl1,text2,
[920a6e5]647                                                    ctl2, ctl3, ctl4,None])
[60132ef]648                        self.orientation_params_disp.append([cb,name1,ctl1,text2,
[920a6e5]649                                                    ctl2, ctl3, ctl4,None])
[780d095]650                    elif p=="npts":
[920a6e5]651                            ix = 6
[780d095]652                            value= self.model.getParam(name2)
[7975f2b]653                            Tctl = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
[780d095]654                                                style=wx.TE_PROCESS_ENTER)
655                           
656                            Tctl.SetValue(str (format_number(value)))
657                            if self.data.__class__.__name__ =="Data2D":
[6dc9ad8]658                                Tctl.Show(True)
[780d095]659                            else:
[6dc9ad8]660                                Tctl.Hide()
[780d095]661                            self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
662                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
663                            self.fixed_param.append([None,name2, Tctl,None,None,
664                                                      None, None,None])
[60132ef]665                            self.orientation_params_disp.append([None,name2, Tctl,None,None,
[780d095]666                                                      None, None,None])
667                    elif p=="nsigmas":
[920a6e5]668                            ix = 7
[780d095]669                            value= self.model.getParam(name3)
[7975f2b]670                            Tct2 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
[780d095]671                                                style=wx.TE_PROCESS_ENTER)
[c985bef]672                            Tct2.SetValue(str (format_number(value)))
[780d095]673                            if self.data.__class__.__name__ =="Data2D":
[c985bef]674                                Tct2.Show(True)
[780d095]675                            else:
[c985bef]676                                Tct2.Hide()
677                            self.sizer4_4.Add(Tct2, (iy,ix),(1,1),
[780d095]678                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
679                            ix +=1
[7975f2b]680
[c985bef]681                            self.fixed_param.append([None,name3, Tct2
[780d095]682                                                     ,None,None, None, None,None])   
[920a6e5]683                                                       
[c985bef]684                            self.orientation_params_disp.append([None,name3, Tct2
[1c1436d]685                                                     ,None,None, None, None,None])
[b324aa9]686       
687
[b421b1a]688        self.state.disp_cb_dict = copy.deepcopy(self.disp_cb_dict) 
689         
[71f0373]690        self.state.model = self.model.clone() 
[240b9966]691         ## save state into
[4043c96]692        self.state.cb1 = self.cb1.GetValue()
[920a6e5]693        self._copy_parameters_state(self.parameters, self.state.parameters)
[240b9966]694        self._copy_parameters_state(self.orientation_params_disp,
695                                     self.state.orientation_params_disp)
696        self._copy_parameters_state(self.fittable_param, self.state.fittable_param)
697        self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
[d40a9cd]698
699
[c77d859]700        wx.PostEvent(self.parent, StatusEvent(status=\
701                        " Selected Distribution: Gaussian"))   
[b324aa9]702        #Fill the list of fittable parameters
703        self.select_all_param(event=None)
704       
[71f0373]705        self.Layout()
[7975f2b]706
707
[c77d859]708    def _onFit(self, event):     
709        """
710            Allow to fit
711        """
[c13b8cc]712        #make sure all parameter values are updated.
[ffa69b6]713        if self.check_invalid_panel():
714            return
[85b3971]715        flag = self._update_paramv_on_fit() 
[acd0bda3]716               
[c77d859]717        if not flag:
[7609f1a]718            msg= "Fitting range or parameters are invalid"
[c77d859]719            wx.PostEvent(self.parent.parent, StatusEvent(status= msg ))
720            return 
721       
722        if len(self.param_toFit) <= 0:
723            msg= "Select at least one parameter to fit"
724            wx.PostEvent(self.parent.parent, StatusEvent(status= msg ))
725            return 
[7975f2b]726     
727
728        self.select_param(event =None)
[acd0bda3]729       
[c99a6c5]730        #Clear errors if exist from previous fitting
[edd166b]731        #self._clear_Err_on_Fit()
[d0ce2c30]732
[c13b8cc]733        # Remove or do not allow fitting on the Q=0 point, especially when y(q=0)=None at x[0].         
[1c1436d]734        self.qmin_x = float(self.qmin.GetValue())
[c13b8cc]735        self.qmax_x = float( self.qmax.GetValue())
[6f023e8]736        self.manager._reset_schedule_problem( value=0)
[ca7a626]737        self.manager.schedule_for_fit( value=1,page=self,fitproblem =None) 
738        self.manager.set_fit_range(page= self,qmin= self.qmin_x, qmax= self.qmax_x)
[ad6dd4c]739       
[c77d859]740        #single fit
[ca7a626]741        self.manager.onFit()
[ad6dd4c]742        ## allow stopping the fit
[34a0c17]743        #if self.engine_type=="scipy":
744        #    self.btFit.SetLabel("Stop")
745        #    self.btFit.Unbind(event=wx.EVT_BUTTON, id= self.btFit.GetId())
746        #    self.btFit.Bind(event= wx.EVT_BUTTON, handler=self._StopFit, id=self.btFit.GetId())
747        #else:
748        #    self.btFit.SetLabel("Fit")
749        #    self.btFit.Bind(event= wx.EVT_BUTTON, handler=self._onFit, id=self.btFit.GetId())
[7975f2b]750           
[5f9a6b1]751
[c77d859]752       
[ad6dd4c]753    def _StopFit(self, event):
754        """
755            Stop fit
756        """
757        self.btFit.SetLabel("Fit")
758        if self.engine_type=="scipy":
759            self.manager.stop_fit()
[34a0c17]760        self.btFit.Unbind(event=wx.EVT_BUTTON, id=self.btFit.GetId())
761        self.btFit.Bind(event=wx.EVT_BUTTON, handler=self._onFit,id=self.btFit.GetId())
[7975f2b]762       
[ad6dd4c]763           
[c77d859]764    def _on_select_model(self, event): 
765        """
766             call back for model selection
767        """   
[59a7f2d]768        self._on_select_model_helper() 
[70c57ebf]769        self.set_model_param_sizer(self.model)                   
[b421b1a]770       
[3b605bb]771        self.enable_disp.SetValue(False)
772        self.disable_disp.SetValue(True)
[4043c96]773        try:
774            self.set_dispers_sizer()
775        except:
776            pass
[9237df4]777        if self.model != None:
[70c57ebf]778            try:
779                temp_smear= None
780                if self.enable_smearer.GetValue():
781                    temp_smear= self.smearer
782                self.compute_chisqr(temp_smear)
783            except:
784                ## error occured on chisqr computation
785                pass
[fcd8887d]786            if self.data is not None and self.data.__class__.__name__ !="Data2D":
[9237df4]787                ## set smearing value whether or not the data contain the smearing info
788                self.manager.set_smearer(smearer=temp_smear, qmin= float(self.qmin_x),
[2a2af47]789                                     qmax= float(self.qmax_x)) 
[fcd8887d]790           
[70c57ebf]791            evt = ModelEventbox(model=self.model)
[c99a6c5]792            wx.PostEvent(self.event_owner, evt) 
[4043c96]793           
[848a2ef]794        self.btFit.SetFocus() 
[240b9966]795        self.state.enable_disp = self.enable_disp.GetValue()
796        self.state.disable_disp = self.disable_disp.GetValue()
[7609f1a]797        self.state.pinhole_smearer = self.pinhole_smearer.GetValue()
798        self.state.slit_smearer = self.slit_smearer.GetValue()
[4043c96]799   
[3b9e023]800        self.state.structurecombobox = self.structurebox.GetCurrentSelection()
801        self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection()
[077809c]802     
[3b9e023]803       
[3595309d]804        if event !=None:
[3a37fe0]805            #self._undo.Enable(True)
[3595309d]806            ## post state to fit panel
807            event = PageInfoEvent(page = self)
808            wx.PostEvent(self.parent, event) 
[330573d]809     
[e2f7b92]810               
[dd5949d]811    def _onparamEnter(self,event):
812        """
813            when enter value on panel redraw model according to changed
814        """
[7975f2b]815        flag = False
[69bee6d]816        tcrtl= event.GetEventObject()
[7975f2b]817
[edd166b]818        #Clear msg if previously shown.
819        msg= ""
820        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
[c99a6c5]821
[7975f2b]822        if check_float(tcrtl):
[7609f1a]823            flag = self._onparamEnter_helper()               
824            temp_smearer = None
825            if not self.disable_smearer.GetValue():
826                temp_smearer= self.current_smearer
827                ## set smearing value whether or not the data contain the smearing info
828                if self.slit_smearer.GetValue():
829                    flag1 = self.update_slit_smear()
830                    flag = flag or flag1
831                elif self.pinhole_smearer.GetValue():
832                    flag1 = self.update_pinhole_smear()
833                    flag = flag or flag1
[18e6c5e]834            elif self.data.__class__.__name__ !="Data2D":
[7609f1a]835                self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
836                                                         qmax= float(self.qmax_x)) 
837            if flag:   
[7975f2b]838                self.compute_chisqr(smearer= temp_smearer)
839   
840                ## new state posted
841                if self.state_change:
842                    #self._undo.Enable(True)
843                    event = PageInfoEvent(page = self)
844                    wx.PostEvent(self.parent, event)
[7609f1a]845                self.state_change= False           
[69bee6d]846        else:
[7975f2b]847            self.save_current_state()
[69bee6d]848            msg= "Cannot Plot :Must enter a number!!!  "
849            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
[7609f1a]850             
851        self.save_current_state() 
852        return 
853   
[e2f7b92]854    def _onparamRangeEnter(self, event):
[920a6e5]855        """
856            Check validity of value enter in the parameters range field
857        """
[ffa69b6]858        if self.check_invalid_panel():
859            return
[920a6e5]860        tcrtl= event.GetEventObject()
[edd166b]861        #Clear msg if previously shown.
862        msg= ""
863        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
864        # Flag to register when a parameter has changed.
865        is_modified = False
[920a6e5]866        if tcrtl.GetValue().lstrip().rstrip()!="":
867            try:
868                value = float(tcrtl.GetValue())
869                tcrtl.SetBackgroundColour(wx.WHITE)
[edd166b]870                self._check_value_enter(self.fittable_param ,is_modified)
871                self._check_value_enter(self.parameters ,is_modified) 
[920a6e5]872            except:
873                tcrtl.SetBackgroundColour("pink")
[edd166b]874                msg= "Model Error:wrong value entered : %s"% sys.exc_value
875                wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
876                return 
[920a6e5]877        else:
878           tcrtl.SetBackgroundColour(wx.WHITE)
[e2f7b92]879           
[edd166b]880        #self._undo.Enable(True)
881        self.save_current_state()
882        event = PageInfoEvent(page = self)
883        wx.PostEvent(self.parent, event)
884        self.state_change= False
[c69b6d5]885
[12eac73]886                   
887    def _onQrangeEnter(self, event):
888        """
889            Check validity of value enter in the Q range field
890        """
[ffa69b6]891        if self.check_invalid_panel():
892            return
[12eac73]893        tcrtl= event.GetEventObject()
894        #Clear msg if previously shown.
895        msg= ""
896        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
897        # Flag to register when a parameter has changed.
898        is_modified = False
899        if tcrtl.GetValue().lstrip().rstrip()!="":
900            try:
901                value = float(tcrtl.GetValue())
902                tcrtl.SetBackgroundColour(wx.WHITE)
903
904                # If qmin and qmax have been modified, update qmin and qmax
[85b3971]905                if self._validate_qrange( self.qmin, self.qmax):
[12eac73]906                    tempmin = float(self.qmin.GetValue())
907                    if tempmin != self.qmin_x:
908                        self.qmin_x = tempmin
909                    tempmax = float(self.qmax.GetValue())
910                    if tempmax != self.qmax_x:
911                        self.qmax_x = tempmax
912                else:
913                    tcrtl.SetBackgroundColour("pink")
914                    msg= "Model Error:wrong value entered : %s"% sys.exc_value
915                    wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
916                    return 
917               
918            except:
919                tcrtl.SetBackgroundColour("pink")
920                msg= "Model Error:wrong value entered : %s"% sys.exc_value
921                wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
922                return 
923            #Check if # of points for theory model are valid(>0).
924            if self.npts != None:
925                if check_float(self.npts):
926                    temp_npts = float(self.npts.GetValue())
927                    if temp_npts !=  self.num_points:
928                        self.num_points = temp_npts
929                        is_modified = True
930                else:
931                    msg= "Cannot Plot :No npts in that Qrange!!!  "
932                    wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
933           
934        else:
935           tcrtl.SetBackgroundColour("pink")
936           msg= "Model Error:wrong value entered!!!"
937           wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
938       
939        self.compute_chisqr()   
940        #self._undo.Enable(True)
941        self.save_current_state()
942        event = PageInfoEvent(page = self)
943        wx.PostEvent(self.parent, event)
944        self.state_change= False
[66c488b]945        self._draw_model()
946       
[edd166b]947    def _clear_Err_on_Fit(self):
948        """
949            hide the error text control shown
950            after fitting
951        """
952       
953        if hasattr(self,"text2_3"):
954            self.text2_3.Hide()
955
956        if len(self.parameters)>0:
957            for item in self.parameters:
958                #Skip t ifhe angle parameters if 1D data
959                if self.data.__class__.__name__ !="Data2D":
960                    if item in self.orientation_params:
961                        continue
962                if item in self.param_toFit:
963                    continue
964                ## hide statictext +/-   
965                if item[3]!=None and item[3].IsShown():
966                    item[3].Hide()
967                ## hide textcrtl  for error after fit
968                if item[4]!=None and item[4].IsShown():                   
969                    item[4].Hide()
[7975f2b]970 
[edd166b]971        if len(self.fittable_param)>0:
972            for item in self.fittable_param:
973                #Skip t ifhe angle parameters if 1D data
974                if self.data.__class__.__name__ !="Data2D":
975                    if item in self.orientation_params:
976                        continue
977                if item in self.param_toFit:
978                    continue
979                ## hide statictext +/-   
980                if item[3]!=None and item[3].IsShown():
981                    item[3].Hide()
982                ## hide textcrtl  for error after fit
983                if item[4]!=None and item[4].IsShown():
984                    item[4].Hide()
985        return       
[920a6e5]986               
[7609f1a]987    def _get_defult_custom_smear(self):
988        """
989           Get the defult values for custum smearing.
990        """
991
992        # get the default values
993        if self.dxl == None: self.dxl = 0.0
994        if self.dxw == None: self.dxw = ""
995        if self.dx_min == None: self.dx_min = SMEAR_SIZE_L
996        if self.dx_max == None: self.dx_max = SMEAR_SIZE_H
997       
998    def _get_smear_info(self):
999        """
1000           Get the smear info from data.
1001           @return: self.smear_type, self.dq_l and self.dq_r,
1002            respectively the type of the smear, dq_min and dq_max for pinhole smear data
1003            while dxl and dxw for slit smear
1004        """
1005
1006        # default
1007        self.smear_type = None
1008        self.dq_l = None
1009        self.dq_r = None
1010       
1011        if self.data is None or\
1012                self.data.__class__.__name__ == 'Data2D':           
1013            return
1014
1015        data = self.data
1016
1017        # check if it is pinhole smear and get min max if it is.
1018        if data.dx != None and all(data.dx !=0): 
1019            self.smear_type = "Pinhole" 
1020            self.dq_l = numpy.min(data.dx)
1021            self.dq_r = numpy.max(data.dx)
1022           
1023        # check if it is slit smear and get min max if it is.
1024        elif data.dxl != None or data.dxw != None: 
1025            self.smear_type = "Slit" 
1026            if data.dxl != None and all(data.dxl !=0):
1027                self.dq_l = data.dxl[0]
1028            if data.dxw != None and all(data.dxw !=0): 
1029                self.dq_r = data.dxw[0]
1030               
1031        #return self.smear_type,self.dq_l,self.dq_r       
1032   
1033    def _show_smear_sizer(self):   
1034        """
1035            Show only the sizers depending on smear selection
1036        """
1037        if self.disable_smearer.GetValue():
1038            self.smear_description_none.Show(True)
1039        elif self.enable_smearer.GetValue():
1040            self.smear_description_dqdata.Show(True)
1041            if self.smear_type != None:
1042                self.smear_description_type.Show(True)
1043                self.smear_description_smear_type.Show(True)
1044                if self.smear_type == 'Slit':
1045                    self.smear_description_slit_height.Show(True)
1046                    self.smear_description_slit_width.Show(True)
1047                elif self.smear_type == 'Pinhole':
1048                    self.smear_description_pin_min.Show(True)
1049                    self.smear_description_pin_max.Show(True)
1050                self.smear_data_left.Show(True)
1051                self.smear_data_right.Show(True)
1052        elif self.pinhole_smearer.GetValue():
1053            self.smear_message_new_p.Show(True)
1054            self.smear_description_pin_min.Show(True)
1055            self.smear_pinhole_min.Show(True)
1056            self.smear_description_pin_max.Show(True)
1057            self.smear_pinhole_max.Show(True)
1058        elif self.slit_smearer.GetValue():
1059            self.smear_message_new_s.Show(True)
1060            self.smear_description_slit_height.Show(True)
1061            self.smear_slit_height.Show(True)
1062            self.smear_description_slit_width.Show(True)
1063            self.smear_slit_width.Show(True)
1064
1065    def _hide_all_smear_info(self):
1066        """
1067           Hide all smearing messages in the set_smearer sizer
1068        """
1069        self.smear_description_none.Hide()
1070        self.smear_description_dqdata.Hide()
1071        self.smear_description_type.Hide()
1072        self.smear_description_smear_type.Hide()
1073        self.smear_description_2d.Hide()
1074        self.smear_data_left.Hide()
1075        self.smear_data_right.Hide()
1076        self.smear_description_pin_min.Hide()
1077        self.smear_pinhole_min.Hide()
1078        self.smear_description_pin_max.Hide()
1079        self.smear_pinhole_max.Hide()
1080        self.smear_description_slit_height.Hide()
1081        self.smear_slit_height.Hide()
1082        self.smear_description_slit_width.Hide()
1083        self.smear_slit_width.Hide()
1084        self.smear_message_new_p.Hide()
1085        self.smear_message_new_s.Hide()
1086   
[882a912]1087       
[9237df4]1088    def set_data(self, data):
[882a912]1089        """
1090            reset the current data
1091        """
[9237df4]1092        self.data = data
1093        if self.data is None:
1094            data_min = ""
1095            data_max = ""
1096            data_name = ""
[ffa69b6]1097            self.formfactorbox.Disable()
1098            self.structurebox.Disable()
[9237df4]1099        else:
[00e8df8]1100            self.smearer = smear_selection( self.data )
[d493f66]1101            self.disable_smearer.SetValue(True)
[00e8df8]1102            if self.smearer == None:
1103                self.enable_smearer.Disable()
1104            else:
1105                self.enable_smearer.Enable()
[7609f1a]1106
1107            # more disables for 2D
1108            if self.data.__class__.__name__ =="Data2D":
1109                self.smear_description_none.Hide()
1110                self.smear_description_2d.Show(True)
1111                self.pinhole_smearer.Disable()
1112                self.slit_smearer.Disable()
[00e8df8]1113               
[d493f66]1114               
[ffa69b6]1115            self.formfactorbox.Enable()
1116            self.structurebox.Enable()
[9237df4]1117            data_name = self.data.name
1118            #set maximum range for x in linear scale
1119            if not hasattr(self.data,"data"): #Display only for 1D data fit
1120                # Minimum value of data   
1121                data_min = min(self.data.x)
1122                # Maximum value of data 
1123                data_max = max(self.data.x)
1124            else:
1125                ## Minimum value of data
1126                data_min = 0
1127                x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
1128                y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax))
1129                ## Maximum value of data 
1130                data_max = math.sqrt(x*x + y*y)
1131       
1132        self.dataSource.SetValue(data_name)
1133        self.qmin_x = data_min
1134        self.qmax_x = data_max
[ffa69b6]1135        self.minimum_q.SetValue(str(data_min))
1136        self.maximum_q.SetValue(str(data_max))
1137        self.qmin.SetValue(str(data_min))
1138        self.qmax.SetValue(str(data_max))
1139        self.qmin.SetBackgroundColour("white")
1140        self.qmax.SetBackgroundColour("white")
1141        self.state.data = data
1142        self.state.qmin = self.qmin_x
1143        self.state.qmax = self.qmax_x
1144       
[7609f1a]1145
[240b9966]1146    def reset_page(self, state,first=False):
[a074145]1147        """
1148            reset the state
1149        """
1150        self.reset_page_helper(state)
[b421b1a]1151        import sans.guiframe.gui_manager
[f20767b]1152        evt = ModelEventbox(model=state.model)
[edd166b]1153        wx.PostEvent(self.event_owner, evt) 
1154   
1155        if self.engine_type != None:
1156            self.manager._on_change_engine(engine=self.engine_type)
[7975f2b]1157
[edd166b]1158        self.select_param(event = None) 
1159        #Save state_fit
[c985bef]1160        self.save_current_state_fit()
[7975f2b]1161        self._lay_out()
[c985bef]1162        self.Refresh()
[edd166b]1163       
[2140e68]1164    def get_range(self):
1165        """
1166            return the fitting range
1167        """
[c9a4377]1168        return float(self.qmin_x) , float(self.qmax_x)
[7975f2b]1169   
1170    def get_npts2fit(self):
1171        """
1172            return numbers of data points within qrange
1173            Note: This is for Park where chi2 is not normalized by Npts of fit
1174        """
1175        npts2fit = 0
1176        qmin,qmax = self.get_range()
1177        if self.data.__class__.__name__ =="Data2D":
[18e6c5e]1178            npts2fit = len(self.data.data[self.mask])
[7975f2b]1179        else:
1180            for qx in self.data.x:
1181                   if qx >= qmin and qx <= qmax:
1182                       npts2fit += 1
1183        return npts2fit
1184
[c69b6d5]1185
1186    def get_chi2(self):
1187        """
1188            return the current chi2
1189        """
1190        return self.tcChi.GetLabel()
[c77d859]1191       
1192    def get_param_list(self):
1193        """
1194            @return self.param_toFit: list containing  references to TextCtrl
1195            checked.Theses TextCtrl will allow reference to parameters to fit.
1196            @raise: if return an empty list of parameter fit will nnote work
1197            properly so raise ValueError,"missing parameter to fit"
1198        """
1199        if self.param_toFit !=[]:
1200            return self.param_toFit
1201        else:
1202            raise ValueError,"missing parameter to fit"   
1203     
[6d91073]1204    def onsetValues(self,chisqr,p_name, out,cov):
[c77d859]1205        """
1206            Build the panel from the fit result
1207            @param chisqr:Value of the goodness of fit metric
[6d91073]1208            @p_name: the name of parameters
[c77d859]1209            @param out:list of parameter with the best value found during fitting
1210            @param cov:Covariance matrix
1211       
1212        """
[edd166b]1213        if out == None or not numpy.isfinite(chisqr):
1214            raise ValueError,"Fit error occured..." 
1215       
1216        is_modified = False
1217        has_error = False   
[7975f2b]1218       
1219        #Hide textctrl boxes of errors.
[edd166b]1220        self._clear_Err_on_Fit()   
[7975f2b]1221       
1222        #Check if chi2 is finite
1223        if chisqr != None or numpy.isfinite(chisqr):
[e575db9]1224        #format chi2 
[7609f1a]1225            if self.engine_type == "park": 
[e575db9]1226                npt_fit = float(self.get_npts2fit()) 
[7609f1a]1227                if npt_fit > 0:
1228                    chisqr =chisqr/npt_fit   
[7975f2b]1229            chi2 = format_number(chisqr)   
1230            self.tcChi.SetLabel(chi2)   
1231            self.tcChi.Refresh()   
1232        else:
1233            self.tcChi.SetLabel("-")
[c13b8cc]1234       
[edd166b]1235        #Hide error title
1236        if self.text2_3.IsShown():
1237            self.text2_3.Hide()
1238     
[e473e4f5]1239        try:
1240            n = self.disp_box.GetCurrentSelection()
1241            dispersity= self.disp_box.GetClientData(n)
[7975f2b]1242            if dispersity !=None and self.enable_disp.GetValue():
1243                name= dispersity.__name__
1244                if name == "GaussianDispersion":
1245                    if hasattr(self,"text_disp_1" ):
1246                        if self.text_disp_1 !=None:
1247                            self.text_disp_1.Hide()
[e473e4f5]1248        except:
[7975f2b]1249            dispersty = None
[e473e4f5]1250            pass
[c77d859]1251        #set the panel when fit result are float not list
[c99a6c5]1252        if out.__class__== numpy.float64:
[c77d859]1253            self.param_toFit[0][2].SetValue(format_number(out))
[0a518e4c]1254           
[c69b6d5]1255            if self.param_toFit[0][4].IsShown:
1256                self.param_toFit[0][4].Hide()
[c77d859]1257            if cov !=None :
1258                self.text2_3.Show(True)
[e473e4f5]1259                try:
[7975f2b]1260                    if dispersity !=None:
1261                        name= dispersity.__name__
1262                        if name == "GaussianDispersion" and self.enable_disp.GetValue():
1263                            if hasattr(self,"text_disp_1" ):
1264                                if self.text_disp_1 !=None:
1265                                    self.text_disp_1.Show(True)
[e473e4f5]1266                except:
1267                    pass
[c99a6c5]1268
[ad6dd4c]1269                if cov[0]==None or  not numpy.isfinite(cov[0]): 
[c69b6d5]1270                    if self.param_toFit[0][3].IsShown:
1271                        self.param_toFit[0][3].Hide()
[7975f2b]1272                else:                   
1273                    self.param_toFit[0][3].Show(True)               
[69bee6d]1274                    self.param_toFit[0][4].Show(True)
[c69b6d5]1275                    self.param_toFit[0][4].SetValue(format_number(cov[0]))
[ffb838f]1276                    has_error = True
[c77d859]1277        else:
[edd166b]1278
[c69b6d5]1279            i = 0
[c77d859]1280            #Set the panel when fit result are list
[7975f2b]1281            for item in self.param_toFit:     
[edd166b]1282                if len(item)>5 and item != None:     
1283                    ## reset error value to initial state
[7975f2b]1284                    item[3].Hide()
1285                    item[4].Hide()
1286                   
[edd166b]1287                    for ind in range(len(out)):
1288                       
1289                        if item[1] == p_name[ind]:
1290                            break       
[7975f2b]1291                    if len(out)<=len(self.param_toFit) and out[ind] !=None:   
1292                        val_out = format_number(out[ind])                 
1293                        item[2].SetValue(val_out)
[c99a6c5]1294
[7975f2b]1295                    if(cov !=None):
[edd166b]1296                       
1297                        try:
[7975f2b]1298                            if dispersity !=None:
1299                                name= dispersity.__name__
1300                                if name == "GaussianDispersion" and self.enable_disp.GetValue():
1301                                    if hasattr(self,"text_disp_1" ):
1302                                        if self.text_disp_1!=None:
1303                                            if not self.text_disp_1.IsShown():
1304                                                self.text_disp_1.Show(True)
[edd166b]1305                        except:
1306                            pass   
1307                   
[7975f2b]1308                        if cov[ind]!=None :
1309                            if numpy.isfinite(float(cov[ind])):
1310                                val_err = format_number(cov[ind])
1311                                item[3].Show(True)
1312                                item[4].Show(True)
1313                                item[4].SetValue(val_err)
1314
1315                                has_error = True
[e575db9]1316                    i += 1         
[c99a6c5]1317        #Show error title when any errors displayed
[b421b1a]1318        if has_error: 
[c99a6c5]1319            if not self.text2_3.IsShown():
[edd166b]1320                self.text2_3.Show(True) 
[7975f2b]1321               
1322        ## save current state 
1323        self.save_current_state()         
1324        #plot model
1325        self._draw_model()   
1326        self._lay_out()     
1327        #PostStatusEvent     
[9237df4]1328        msg = "Fit completed! "
[7975f2b]1329        wx.PostEvent(self.manager.parent, StatusEvent(status=msg))
[c69b6d5]1330
[7609f1a]1331    def onPinholeSmear(self, event):
1332        """
1333            Create a custom pinhole smear object that will change the way residuals
1334            are compute when fitting
1335        """
1336
1337        if self.check_invalid_panel():
1338            return
1339        if self.model ==None:
1340            msg="Need model and data to smear plot"
1341            wx.PostEvent(self.manager.parent, StatusEvent(status=\
1342                            "Smear: %s"%msg))
1343            return
1344       
1345        # msg default
1346        msg = None
1347        if event != None:
1348            tcrtl= event.GetEventObject()
1349            # event case of radio button
1350            if tcrtl.GetValue()== True:
1351                self.dx_min = 0.0
1352                self.dx_max = 0.0
1353                is_new_pinhole = True
1354            else:
1355                is_new_pinhole = self._is_changed_pinhole()
[d493f66]1356        else:
1357            is_new_pinhole = self._is_changed_pinhole()
[7609f1a]1358        # if any value is changed
1359        if is_new_pinhole:
1360            msg = self._set_pinhole_smear()
1361        # hide all silt sizer   
1362        self._hide_all_smear_info()
1363           
1364        ##Calculate chi2
1365        self.compute_chisqr(smearer= self.current_smearer) 
1366        # show relevant slit sizers
1367        self._show_smear_sizer()
1368        self.sizer_set_smearer.Layout()
1369        self.Layout()   
1370       
1371        if event != None: 
1372            event.Skip()                 
1373        #self._undo.Enable(True)
1374        self.save_current_state()
1375        event = PageInfoEvent(page = self)
1376        wx.PostEvent(self.parent, event)
1377       
1378    def _is_changed_pinhole(self): 
1379        """
1380            check if any of pinhole smear is changed
1381            return: True or False
1382        """
1383        # get the values
1384        pin_min = self.smear_pinhole_min.GetValue()
1385        pin_max = self.smear_pinhole_max.GetValue()
1386                   
1387        # Check changes in slit width   
1388        try:
1389            dx_min = float(pin_min)
1390        except:
1391            return True
1392        if self.dx_min != dx_min:
1393            return True
1394       
1395        # Check changes in slit heigth
1396        try:
1397            dx_max = float(pin_max)
1398        except:
1399            return True
1400        if self.dx_max != dx_max:
1401            return True
1402        return False
1403   
1404    def _set_pinhole_smear(self):
1405        """
1406            Set custom pinhole smear
1407            return: msg
1408        """
1409        # copy data
1410        data = copy.deepcopy(self.data)
1411        data_len = len(data.x)
1412        data.dx = None
1413        data.dxl = None
1414        data.dxw = None
1415        msg = None
1416   
1417        # make sure once more if it is smearer
1418        data = copy.deepcopy(self.data)
1419        len_data = len(data.x)
1420        data.dx = numpy.zeros(len_data)
1421        get_pin_min = self.smear_pinhole_min
1422        get_pin_max = self.smear_pinhole_max       
1423
1424        if self._validate_qrange(get_pin_min, get_pin_max ):
1425            if len_data < 2: len_data = 2     
1426            self.dx_min = float(get_pin_min.GetValue())
1427            self.dx_max = float(get_pin_max.GetValue())
1428            if self.dx_min != None and self.dx_max != None:             
1429                if self.dx_min == self.dx_max:
1430                    data.dx[data.dx==0] = self.dx_min
1431                else:
1432                    step = math.fabs(self.dx_max - self.dx_min)/(len_data-1)   
1433                    data.dx = numpy.arange(self.dx_min,self.dx_max+step/1.1,step)           
1434            elif self.dx_min != None: 
1435                data.dx[data.dx==0] = self.dx_min
1436            elif self.dx_max != None:
1437                data.dx[data.dx==0] = self.dx_max         
1438            self.current_smearer = smear_selection(data)
1439
1440        else:
1441            get_pin_min.SetBackgroundColour("pink")
1442            get_pin_max.SetBackgroundColour("pink")
1443            msg= "Model Error:wrong value entered!!!"
1444            wx.PostEvent(self.manager.parent, StatusEvent(status = msg ))
1445        ## set smearing value whether or not the data contain the smearing info
1446        self.manager.set_smearer(smearer=self.current_smearer, qmin= float(self.qmin_x),qmax= float(self.qmax_x))
1447 
1448        return msg
1449       
1450    def update_pinhole_smear(self):
1451        """
1452            called by kill_focus on pinhole TextCntrl
1453            to update the changes
1454            return: msg: False when wrong value was entered
1455        """
1456        # msg default
1457        msg = None
1458        # check if any value is changed
1459        if self._is_changed_pinhole():
1460            msg = self._set_pinhole_smear()           
1461        #self._undo.Enable(True)
1462        self.save_current_state()
1463
1464        if msg != None:
1465            return False   
1466        else:
1467            return True
1468                     
1469    def onSlitSmear(self, event):
1470        """
1471            Create a custom slit smear object that will change the way residuals
1472            are compute when fitting
1473        """
1474
1475               
1476        if self.check_invalid_panel():
1477            return
1478        if self.model ==None:
1479            msg="Need model and data to smear plot"
1480            wx.PostEvent(self.manager.parent, StatusEvent(status=\
1481                            "Smear: %s"%msg))
1482            return
1483        # msg default
1484        msg = None
1485        # for event given
1486        if event != None:
1487            tcrtl= event.GetEventObject()
1488            # event case of radio button
1489            if tcrtl.GetValue():
1490                self.dxl = 0.0
1491                self.dxw = 0.0
1492                is_new_slit = True
1493            else:
1494                is_new_slit = self._is_changed_slit()
[d493f66]1495        else:
1496            is_new_slit = self._is_changed_slit()
[7609f1a]1497               
1498        # if any value is changed
1499        if is_new_slit:
1500            msg = self._set_slit_smear()
1501        # hide all silt sizer
1502        self._hide_all_smear_info()       
1503        ##Calculate chi2
1504        self.compute_chisqr(smearer= self.current_smearer) 
1505        # show relevant slit sizers       
1506        self._show_smear_sizer()
1507        self.sizer_set_smearer.Layout()
1508        self.Layout()
1509       
1510        if event != None:
1511            event.Skip()     
1512        #self._undo.Enable(True)
1513        self.save_current_state()
1514        event = PageInfoEvent(page = self)
1515        wx.PostEvent(self.parent, event)
1516        if msg != None:
1517            wx.PostEvent(self.manager.parent, StatusEvent(status = msg))
1518
1519           
1520    def _is_changed_slit(self): 
1521        """
1522            check if any of slit lengths is changed
1523            return: True or False
1524        """
1525        # get the values
1526        width = self.smear_slit_width.GetValue()
1527        height = self.smear_slit_height.GetValue()
1528       
1529        # check and change the box bg color if it was pink but it should be white now
1530        # because this is the case that _set_slit_smear() will not handle
1531        if height.lstrip().rstrip()=="":
1532            self.smear_slit_height.SetBackgroundColour(wx.WHITE)
1533        if width.lstrip().rstrip()=="":
1534            self.smear_slit_width.SetBackgroundColour(wx.WHITE)
1535           
1536        # Check changes in slit width   
1537        if width == "": 
1538            dxw = 0.0
1539        else:
1540            try:
1541                dxw = float(width)
1542            except:
1543                return True
1544        if self.dxw != dxw:
1545            return True
1546       
1547        # Check changes in slit heigth
1548        if height == "": 
1549            dxl = 0.0
1550        else:
1551            try:
1552                dxl = float(height)
1553            except:
1554                return True
1555        if self.dxl != dxl:
1556            return True
1557        return False
1558   
1559    def _set_slit_smear(self):
1560        """
1561            Set custom slit smear
1562            return: msg
1563        """
1564        temp_smearer = None
1565        # make sure once more if it is smearer
1566        data = copy.deepcopy(self.data)
1567        data_len = len(data.x)
1568        data.dx = None
1569        data.dxl = None
1570        data.dxw = None
1571        msg = None
1572   
1573        try:
1574            self.dxl = float(self.smear_slit_height.GetValue())
1575            data.dxl = self.dxl* numpy.ones(data_len)
1576            self.smear_slit_height.SetBackgroundColour(wx.WHITE)
1577        except: 
1578            data.dxl = numpy.zeros(data_len)
1579            if self.smear_slit_height.GetValue().lstrip().rstrip()!="":
1580                self.smear_slit_height.SetBackgroundColour("pink")
1581                msg = "Wrong value entered... " 
1582            else:
1583                self.smear_slit_height.SetBackgroundColour(wx.WHITE)
1584        try:
1585            self.dxw = float(self.smear_slit_width.GetValue())
1586            self.smear_slit_width.SetBackgroundColour(wx.WHITE)
1587            data.dxw = self.dxw* numpy.ones(data_len)
1588        except: 
1589            data.dxw = numpy.zeros(data_len)
1590            if self.smear_slit_width.GetValue().lstrip().rstrip()!="":
1591                self.smear_slit_width.SetBackgroundColour("pink")
1592                msg = "Wrong Fit value entered... "
1593            else:
1594                self.smear_slit_width.SetBackgroundColour(wx.WHITE)
1595               
1596        self.current_smearer = smear_selection(data)
1597        #temp_smearer = self.current_smearer
1598        ## set smearing value whether or not the data contain the smearing info
1599        self.manager.set_smearer(smearer=self.current_smearer, qmin= float(self.qmin_x), qmax= float(self.qmax_x)) 
1600
1601        return msg
1602   
1603   
1604    def update_slit_smear(self):
1605        """
1606            called by kill_focus on pinhole TextCntrl
1607            to update the changes
1608            return: msg: False when wrong value was entered
1609        """             
1610        # msg default
1611        msg = None
1612        # check if any value is changed
1613        if self._is_changed_slit():
1614            msg = self._set_slit_smear()           
1615        #self._undo.Enable(True)
1616        self.save_current_state()
1617
1618        if msg != None:
1619            return False   
1620        else:
1621            return True
1622                           
1623   
[c77d859]1624    def onSmear(self, event):
1625        """
1626            Create a smear object that will change the way residuals
1627            are compute when fitting
1628        """
[ffa69b6]1629        if self.check_invalid_panel():
1630            return
[2a2af47]1631        if self.model ==None:
1632            msg="Need model and data to smear plot"
1633            wx.PostEvent(self.manager.parent, StatusEvent(status=\
1634                            "Smear: %s"%msg))
1635            return
[3370922]1636        temp_smearer = None
[7609f1a]1637        self._get_smear_info()
1638       
1639        #renew smear sizer
1640        if self.smear_type != None:
1641            self.smear_description_smear_type.SetValue(str(self.smear_type))
1642            self.smear_data_left.SetValue(str(self.dq_l))   
1643            self.smear_data_right.SetValue(str(self.dq_r))       
1644       
1645        self._hide_all_smear_info()
1646       
1647        data = copy.deepcopy(self.data)
1648        # make sure once more if it is smearer
1649        self.current_smearer = smear_selection(data)
1650
[c77d859]1651        if self.enable_smearer.GetValue():
[7609f1a]1652            temp_smearer= self.current_smearer
[c77d859]1653            if hasattr(self.data,"dxl"):
[7609f1a]1654               
[c77d859]1655                msg= ": Resolution smearing parameters"
1656            if hasattr(self.data,"dxw"):
1657                msg= ": Slit smearing parameters"
[997131a]1658            if self.smearer ==None:
[c77d859]1659                wx.PostEvent(self.manager.parent, StatusEvent(status=\
1660                            "Data contains no smearing information"))
1661            else:
1662                wx.PostEvent(self.manager.parent, StatusEvent(status=\
1663                            "Data contains smearing information %s"%msg))
[7609f1a]1664            self.smear_description_dqdata.Show(True)
1665            self.smear_data_left.Show(True)
1666            self.smear_data_right.Show(True)
1667        elif self.disable_smearer.GetValue():
1668            self.smear_description_none.Show(True)
1669           
1670        self._show_smear_sizer()
1671        self.sizer_set_smearer.Layout()
1672        self.Layout()
[fb8daaaf]1673        ## set smearing value whether or not the data contain the smearing info
[3370922]1674        self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
[2b63df0]1675                                     qmax= float(self.qmax_x)) 
[875f1a2]1676        ##Calculate chi2
[997131a]1677        self.compute_chisqr(smearer= temp_smearer) 
[5582a9f1]1678       
1679        self.state.enable_smearer=  self.enable_smearer.GetValue()
1680        self.state.disable_smearer=self.disable_smearer.GetValue()
[7609f1a]1681        self.state.pinhole_smearer = self.pinhole_smearer.GetValue()
1682        self.state.slit_smearer = self.slit_smearer.GetValue()
1683       
[2b63df0]1684    def complete_chisqr(self, output, elapsed=None): 
1685        """
1686            print result chisqr
1687        """
1688        try:
[077809c]1689            if output ==None:
1690                output= "-"
[edd166b]1691
[ba95543]1692            self.tcChi.SetLabel(str(format_number(output)))
[12eac73]1693
[edd166b]1694            self.state.tcChi =self.tcChi
[5582a9f1]1695         
[2b63df0]1696        except:
[0aeabc6]1697            pass
[2b63df0]1698       
1699       
1700    def compute_chisqr1D(self, smearer=None):
1701        """
1702            Compute chisqr for 1D
1703        """
1704        try:
1705            self.qmin_x = float(self.qmin.GetValue())
1706            self.qmax_x = float(self.qmax.GetValue())
1707            ##return residuals within self.qmin_x and self.qmax_x
1708            from gui_thread import CalcChisqr1D
1709            ## If a thread is already started, stop it
1710            if self.calc_Chisqr!= None and self.calc_Chisqr.isrunning():
1711                self.calc_Chisqr.stop()
1712               
[077809c]1713            self.calc_Chisqr= CalcChisqr1D( data1d= self.data,
[2b63df0]1714                                            model= self.model,
1715                                            smearer=smearer,
1716                                            qmin=self.qmin_x,
1717                                            qmax=self.qmax_x,
1718                                            completefn = self.complete_chisqr,
1719                                            updatefn   = None)
1720   
1721            self.calc_Chisqr.queue()
1722           
1723        except:
1724            raise ValueError," Could not compute Chisqr for %s Model 2D: "%self.model.name
1725           
1726           
1727   
1728       
[b787e68c]1729       
[c77d859]1730    def compute_chisqr2D(self):
1731        """
1732            compute chi square given a model and data 2D and set the value
1733            to the tcChi txtcrl
1734        """
[2b63df0]1735        try:
1736            self.qmin_x = float(self.qmin.GetValue())
1737            self.qmax_x = float(self.qmax.GetValue())
1738           
1739            ##return residuals within self.qmin_x and self.qmax_x
1740            from gui_thread import CalcChisqr2D
1741            ## If a thread is already started, stop it
1742            if self.calc_Chisqr!= None and self.calc_Chisqr.isrunning():
1743                self.calc_Chisqr.stop()
[0aeabc6]1744           
[077809c]1745            self.calc_Chisqr= CalcChisqr2D( data2d= self.data,
[2b63df0]1746                                            model= self.model,
1747                                            qmin= self.qmin_x,
1748                                            qmax = self.qmax_x,
1749                                            completefn = self.complete_chisqr,
1750                                            updatefn   = None)
[c77d859]1751   
[2b63df0]1752            self.calc_Chisqr.queue()
1753         
1754        except:
[077809c]1755           raise
[2b63df0]1756
[c77d859]1757       
[997131a]1758    def compute_chisqr(self , smearer=None):
[c77d859]1759        """
1760            compute chi square given a model and data 1D and set the value
1761            to the tcChi txtcrl
1762        """
[85b3971]1763        flag = self._validate_qrange( self.qmin, self.qmax)
[c77d859]1764        if flag== True:
1765            try:
1766                if hasattr(self.data,"data"):
1767                    self.compute_chisqr2D()
1768                    return
1769                else:
[2b63df0]1770                    self.compute_chisqr1D(smearer=smearer)
1771                    return
[c77d859]1772            except:
[077809c]1773                wx.PostEvent(self.parent.parent, StatusEvent(status=\
[2b63df0]1774                            "Chisqr Error: %s"% sys.exc_value))
[a8088d7]1775                return 
[c77d859]1776           
1777   
1778    def select_all_param(self,event): 
1779        """
1780             set to true or false all checkBox given the main checkbox value cb1
[d1e0473]1781        """           
1782
[c77d859]1783        self.param_toFit=[]
1784        if  self.parameters !=[]:
[998b6b8]1785            if  self.cb1.GetValue():
[c77d859]1786                for item in self.parameters:
[3fef0a8]1787                    ## for data2D select all to fit
1788                    if self.data.__class__.__name__=="Data2D":
[c77d859]1789                        item[0].SetValue(True)
1790                        self.param_toFit.append(item )
[3fef0a8]1791                    else:
1792                        ## for 1D all parameters except orientation
1793                        if not item in self.orientation_params:
1794                            item[0].SetValue(True)
1795                            self.param_toFit.append(item )
[b324aa9]1796                #if len(self.fittable_param)>0:
1797                for item in self.fittable_param:
1798                    if self.data.__class__.__name__=="Data2D":
1799                        item[0].SetValue(True)
1800                        self.param_toFit.append(item )
1801                    else:
1802                        ## for 1D all parameters except orientation
1803                        if not item in self.orientation_params_disp:
[3fef0a8]1804                            item[0].SetValue(True)
1805                            self.param_toFit.append(item )
[c77d859]1806            else:
1807                for item in self.parameters:
1808                    item[0].SetValue(False)
1809                for item in self.fittable_param:
1810                    item[0].SetValue(False)
1811                self.param_toFit=[]
[330573d]1812           
[52cac46]1813        self.save_current_state_fit() 
[b324aa9]1814       
[3595309d]1815        if event !=None:
[3a37fe0]1816            #self._undo.Enable(True)
[3595309d]1817            ## post state to fit panel
1818            event = PageInfoEvent(page = self)
1819            wx.PostEvent(self.parent, event) 
1820     
[c77d859]1821               
1822               
1823    def select_param(self,event):
1824        """
1825            Select TextCtrl  checked for fitting purpose and stores them
1826            in  self.param_toFit=[] list
1827        """
1828        self.param_toFit=[]
1829        for item in self.parameters:
[edd166b]1830            #Skip t ifhe angle parameters if 1D data
1831            if self.data.__class__.__name__ !="Data2D":
1832                if item in self.orientation_params:
1833                    continue
[c77d859]1834            #Select parameters to fit for list of primary parameters
[998b6b8]1835            if item[0].GetValue():
[c77d859]1836                if not (item in self.param_toFit):
1837                    self.param_toFit.append(item ) 
1838            else:
1839                #remove parameters from the fitting list
1840                if item in self.param_toFit:
1841                    self.param_toFit.remove(item)
[edd166b]1842
[c77d859]1843        #Select parameters to fit for list of fittable parameters with dispersion         
1844        for item in self.fittable_param:
[edd166b]1845            #Skip t ifhe angle parameters if 1D data
1846            if self.data.__class__.__name__ !="Data2D":
1847                if item in self.orientation_params:
1848                    continue
[998b6b8]1849            if item[0].GetValue():
[c77d859]1850                if not (item in self.param_toFit):
1851                    self.param_toFit.append(item) 
1852            else:
1853                #remove parameters from the fitting list
1854                if item in self.param_toFit:
[edd166b]1855                    self.param_toFit.remove(item)
1856
1857        #Calculate num. of angle parameters
1858        if self.data.__class__.__name__ =="Data2D": 
1859            len_orient_para = 0
1860        else:
1861            len_orient_para = len(self.orientation_params)  #assume even len
1862        #Total num. of angle parameters
1863        if len(self.fittable_param) > 0:
1864            len_orient_para *= 2
[c77d859]1865        #Set the value of checkbox that selected every checkbox or not           
[edd166b]1866        if len(self.parameters)+len(self.fittable_param)-len_orient_para ==len(self.param_toFit):
[c77d859]1867            self.cb1.SetValue(True)
1868        else:
1869            self.cb1.SetValue(False)
[52cac46]1870        self.save_current_state_fit()
[3595309d]1871        if event !=None:
[3a37fe0]1872            #self._undo.Enable(True)
[3595309d]1873            ## post state to fit panel
1874            event = PageInfoEvent(page = self)
1875            wx.PostEvent(self.parent, event) 
1876     
[c77d859]1877   
1878       
[77e23a2]1879    def set_model_param_sizer(self, model):
[c77d859]1880        """
1881            Build the panel from the model content
1882            @param model: the model selected in combo box for fitting purpose
1883        """
1884        self.sizer3.Clear(True)
1885        self.parameters = []
1886        self.param_toFit=[]
1887        self.fittable_param=[]
1888        self.fixed_param=[]
[780d095]1889        self.orientation_params=[]
[60132ef]1890        self.orientation_params_disp=[]
[c77d859]1891       
1892        if model ==None:
1893            self.sizer3.Layout()
[08ba57d]1894            self.SetScrollbars(20,20,25,65)
[c77d859]1895            return
[707436d]1896        ## the panel is drawn using the current value of the fit engine
1897        if self.engine_type==None and self.manager !=None:
1898            self.engine_type= self.manager._return_engine_type()
[c99a6c5]1899
[707436d]1900           
[c77d859]1901        box_description= wx.StaticBox(self, -1,str("Model Parameters"))
1902        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
1903        sizer = wx.GridBagSizer(5,5)
1904        ## save the current model
1905        self.model = model
1906           
1907        keys = self.model.getParamList()
1908        #list of dispersion paramaters
1909        self.disp_list=self.model.getDispParamList()
[b421b1a]1910
[c77d859]1911        keys.sort()
1912   
[6dc9ad8]1913        iy = 0
[c77d859]1914        ix = 0
[b324aa9]1915        select_text = "Uncheck all to fix"
1916        self.cb1 = wx.CheckBox(self, -1,str(select_text), (10, 10))
[c77d859]1917        wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param)
[b324aa9]1918        self.cb1.SetValue(True)
[c77d859]1919       
1920        sizer.Add(self.cb1,(iy, ix),(1,1),\
[eda428b]1921                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
[c77d859]1922        ix +=1
1923        self.text2_2 = wx.StaticText(self, -1, 'Values')
1924        sizer.Add(self.text2_2,(iy, ix),(1,1),\
1925                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1926        ix +=2 
1927        self.text2_3 = wx.StaticText(self, -1, 'Errors')
1928        sizer.Add(self.text2_3,(iy, ix),(1,1),\
1929                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1930        self.text2_3.Hide()
1931        ix +=1 
1932        self.text2_min = wx.StaticText(self, -1, 'Min')
1933        sizer.Add(self.text2_min,(iy, ix),(1,1),\
1934                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1935        self.text2_min.Hide()
1936        ix +=1 
1937        self.text2_max = wx.StaticText(self, -1, 'Max')
1938        sizer.Add(self.text2_max,(iy, ix),(1,1),\
1939                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1940        self.text2_max.Hide()
[6fdfc8f]1941        ix += 1
1942        self.text2_4 = wx.StaticText(self, -1, '[Units]')
1943        sizer.Add(self.text2_4,(iy, ix),(1,1),\
1944                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1945        self.text2_4.Hide()
[dcf29d7]1946        if self.engine_type=="park":
1947            self.text2_max.Show(True)
1948            self.text2_min.Show(True)
[b421b1a]1949       
[c77d859]1950        for item in keys:
[780d095]1951            if not item in self.disp_list and not item in self.model.orientation_params:
[b421b1a]1952               
1953                ##prepare a spot to store errors
1954                if not self.model.details.has_key(item):
1955                    self.model.details [item] = ["",None,None] 
1956         
[c77d859]1957                iy += 1
1958                ix = 0
1959                ## add parameters name with checkbox for selecting to fit
1960                cb = wx.CheckBox(self, -1, item )
[b324aa9]1961                cb.SetValue(True)
[c77d859]1962                wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
1963                sizer.Add( cb,( iy, ix),(1,1),
[eda428b]1964                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
[d1e0473]1965               
[c77d859]1966                ## add parameter value
1967                ix += 1
1968                value= self.model.getParam(item)
[7975f2b]1969                ctl1 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
[c77d859]1970                                    style=wx.TE_PROCESS_ENTER)
1971               
[77e23a2]1972                ctl1.SetValue(format_number(value))
[c77d859]1973                sizer.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)
1974                ## text to show error sign
1975                ix += 1
1976                text2=wx.StaticText(self, -1, '+/-')
1977                sizer.Add(text2,(iy, ix),(1,1),\
1978                                wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1979                text2.Hide() 
1980                ix += 1
[c13b8cc]1981                ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=0)
[c77d859]1982                sizer.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[b421b1a]1983                ctl2.Hide()
[c77d859]1984               
1985                ix += 1
[7975f2b]1986                ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
1987                                               text_enter_callback = self._onparamRangeEnter)
[eacf1d66]1988     
[c77d859]1989                sizer.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1990                ctl3.Hide()
[77e23a2]1991       
[c77d859]1992                ix += 1
[7975f2b]1993                ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
1994                                               text_enter_callback = self._onparamRangeEnter)
[c77d859]1995                sizer.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[eacf1d66]1996     
[c77d859]1997                ctl4.Hide()
[edd166b]1998
[dcf29d7]1999                if self.engine_type=="park":
2000                    ctl3.Show(True)
2001                    ctl4.Show(True)
[6fdfc8f]2002                ix +=1
2003                # Units
[7975f2b]2004                if self.model.details.has_key(item):
[6fdfc8f]2005                    units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT)
[7975f2b]2006                else:
[6fdfc8f]2007                    units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT)
2008                sizer.Add(units, (iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[dcf29d7]2009                   
[c77d859]2010                ##[cb state, name, value, "+/-", error of fit, min, max , units]
2011                self.parameters.append([cb,item, ctl1,
[240b9966]2012                                        text2,ctl2, ctl3, ctl4,units])
[2d5f7a1]2013             
[c77d859]2014        iy+=1
[2a5bba7]2015        sizer.Add((10,10),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[5af5183]2016       
[f20767b]2017        # type can be either Guassian or Array
[5b53a5c]2018        if len(self.model.dispersion.values())>0:
2019            type= self.model.dispersion.values()[0]["type"]
2020        else:
2021            type = "Gaussian"
[6dc9ad8]2022           
2023        iy += 1
2024        ix = 0
2025        #Add tile for orientational angle
2026        for item in keys:
2027            if item in self.model.orientation_params:       
2028                orient_angle = wx.StaticText(self, -1, '[For 2D only]:')
2029                sizer.Add(orient_angle,(iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 
2030                if not self.data.__class__.__name__ =="Data2D":
2031                    orient_angle.Hide()
2032                else:
2033                    orient_angle.Show(True)
2034                break
[5b53a5c]2035     
[f20767b]2036        #For Gaussian only
2037        if type.lower() != "array":
2038            for item in self.model.orientation_params:
2039                if not item in self.disp_list:
[c13b8cc]2040                    ##prepare a spot to store min max
2041                    if not self.model.details.has_key(item):
2042                        self.model.details [item] = ["",None,None] 
2043                         
[f20767b]2044                    iy += 1
2045                    ix = 0
2046                    ## add parameters name with checkbox for selecting to fit
2047                    cb = wx.CheckBox(self, -1, item )
2048                    cb.SetValue(False)
2049                    wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
2050                    if self.data.__class__.__name__ =="Data2D":
[6dc9ad8]2051                        cb.Show(True)
[f20767b]2052                    else:
[6dc9ad8]2053                        cb.Hide()
[f20767b]2054                    sizer.Add( cb,( iy, ix),(1,1),
2055                                 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
2056   
2057                    ## add parameter value
2058                    ix += 1
2059                    value= self.model.getParam(item)
[7975f2b]2060                    ctl1 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
[f20767b]2061                                        style=wx.TE_PROCESS_ENTER)
[780d095]2062                   
[f20767b]2063                    ctl1.SetValue(format_number(value))
2064                    if self.data.__class__.__name__ =="Data2D":
[c5cd3b9]2065                        ctl1.Show(True)
[f20767b]2066                    else:
[c5cd3b9]2067                        ctl1.Hide()
[f20767b]2068                    sizer.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)
2069                    ## text to show error sign
2070                    ix += 1
2071                    text2=wx.StaticText(self, -1, '+/-')
2072                    sizer.Add(text2,(iy, ix),(1,1),\
2073                                    wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
2074                    text2.Hide() 
2075                    ix += 1
[c13b8cc]2076                    ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=0)
[e2f7b92]2077                   
[f20767b]2078                    sizer.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
2079                    ctl2.Hide()
[e2f7b92]2080                   
[c99a6c5]2081                   
[f20767b]2082                    ix += 1
[7975f2b]2083                    ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
2084                                                   text_enter_callback = self._onparamRangeEnter)
[eacf1d66]2085               
[f20767b]2086                    sizer.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
2087                    ctl3.Hide()
[b324aa9]2088                 
[f20767b]2089                    ix += 1
[7975f2b]2090                    ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
2091                                                   text_enter_callback = self._onparamRangeEnter)
[f20767b]2092                    sizer.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[eacf1d66]2093                   
[f20767b]2094                    ctl4.Hide()
[edd166b]2095                   
2096                    if self.engine_type =="park" and self.data.__class__.__name__ =="Data2D":                     
[f20767b]2097                        ctl3.Show(True)
2098                        ctl4.Show(True)
[c5cd3b9]2099                   
[f20767b]2100                    ix +=1
2101                    # Units
[7975f2b]2102                    if self.model.details.has_key(item):
[f20767b]2103                        units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT)
[7975f2b]2104                    else:
[f20767b]2105                        units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT)
2106                    if self.data.__class__.__name__ =="Data2D":
[6dc9ad8]2107                        units.Show(True)
[c99a6c5]2108                   
[f20767b]2109                    else:
[6dc9ad8]2110                        units.Hide()
[c99a6c5]2111                   
[f20767b]2112                    sizer.Add(units, (iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[7975f2b]2113                                         
[f20767b]2114                    ##[cb state, name, value, "+/-", error of fit, min, max , units]
2115                    self.parameters.append([cb,item, ctl1,
2116                                            text2,ctl2, ctl3, ctl4,units])
2117                    self.orientation_params.append([cb,item, ctl1,
2118                                            text2,ctl2, ctl3, ctl4,units])
[780d095]2119             
2120        iy+=1
[c77d859]2121       
2122        #Display units text on panel
2123        for item in keys:   
[7975f2b]2124            if self.model.details.has_key(item):
[c77d859]2125                self.text2_4.Show()
[b324aa9]2126        #Fill the list of fittable parameters
2127        self.select_all_param(event=None)
[7975f2b]2128
[52cac46]2129        self.save_current_state_fit()
[240b9966]2130        boxsizer1.Add(sizer)
[c77d859]2131        self.sizer3.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
2132        self.sizer3.Layout()
[330573d]2133        self.Layout()
2134        self.Refresh()
[08ba57d]2135        self.SetScrollbars(20,20,25,65)
[52cac46]2136
[7609f1a]2137class BGTextCtrl(wx.TextCtrl):
2138    """
2139        Text control used to display outputs.
2140        No editing allowed. The background is
2141        grayed out. User can't select text.
2142    """
2143    def __init__(self, *args, **kwds):
2144        wx.TextCtrl.__init__(self, *args, **kwds)
2145        self.SetEditable(False)
2146        self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
2147       
2148        # Bind to mouse event to avoid text highlighting
2149        # The event will be skipped once the call-back
2150        # is called.
2151        self.Bind(wx.EVT_MOUSE_EVENTS, self._click)
2152       
2153    def _click(self, event):
2154        """
2155            Prevent further handling of the mouse event
2156            by not calling Skip().
2157        """ 
2158        pass
[c77d859]2159       
2160class HelpWindow(wx.Frame):
2161    def __init__(self, parent, id, title):
2162        wx.Frame.__init__(self, parent, id, title, size=(570, 400))
2163       
2164        from sans.models.CylinderModel import CylinderModel
2165        model = CylinderModel()
[2d5f7a1]2166       
[c77d859]2167        from danse.common.plottools.plottables import Data1D
2168        data= Data1D(x=[1,2], y=[3,4], dy=[0.1, 0,1])
2169   
[cfc0913]2170        from fitpanel import PageInfo
[c77d859]2171        myinfo = PageInfo(self,  model, data=data )
2172       
2173        ## add data
2174       
2175        from models import ModelList
2176        mylist= ModelList()
2177
2178        from sans.models.SphereModel import SphereModel
2179        from sans.models.SquareWellStructure import SquareWellStructure
2180        from sans.models.DebyeModel import DebyeModel
2181        from sans.models.LineModel import LineModel
2182        name= "shapes"
2183        list1= [SphereModel]
2184        mylist.set_list( name, list1)
2185       
2186        name= "Shape-independent"
2187        list1= [DebyeModel]
2188        mylist.set_list( name, list1)
2189       
2190        name= "Structure Factors"
2191        list1= [SquareWellStructure]
2192        mylist.set_list( name, list1)
2193       
2194        name= "Added models"
2195        list1= [LineModel]
2196        mylist.set_list( name, list1)
2197       
2198        myinfo.model_list_box = mylist.get_list()
2199       
2200        self.page = FitPage(self, myinfo) 
2201       
2202        self.Centre()
2203        self.Show(True)
[eacf1d66]2204 
[c77d859]2205if __name__=="__main__":
2206    app = wx.App()
2207    HelpWindow(None, -1, 'HelpWindow')
2208    app.MainLoop()
2209               
Note: See TracBrowser for help on using the repository browser.