Changeset c77d859 in sasview
- Timestamp:
- Mar 20, 2009 8:26:01 PM (16 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 20d30e9
- Parents:
- f2776f6
- Location:
- sansview/perspectives/fitting
- Files:
-
- 7 added
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
sansview/perspectives/fitting/fit_thread.py
rbb18ef1 rc77d859 102 102 """Thread performing the fit """ 103 103 104 def __init__(self,parent, fn,pars=None,cpage=None, qmin=None,qmax=None,ymin=None, ymax=None, 105 xmin=None,xmax=None, 104 def __init__(self,parent, fn,pars=None,cpage=None, qmin=None,qmax=None, 106 105 completefn = None, 107 106 updatefn = None, … … 118 117 self.pars = pars 119 118 self.starttime = 0 119 120 120 self.qmin = qmin 121 121 self.qmax = qmax 122 self.xmin = xmin 123 self.xmax = xmax 124 self.ymin = ymin 125 self.ymax = ymax 122 126 123 self.done= False 127 124 wx.PostEvent(self.parent, StatusEvent(status=\ … … 165 162 qmin = self.qmin, 166 163 qmax = self.qmax, 167 xmin= self.xmin, 168 xmax= self.xmax, 169 ymin = self.ymin, 170 ymax = self.ymax, 164 171 165 elapsed=elapsed ) 172 166 except KeyboardInterrupt: -
sansview/perspectives/fitting/fitpanel.py
rbb18ef1 rc77d859 40 40 #dictionary of miodel {model class name, model class} 41 41 self.model_list_box={} 42 ## list of structure factor 43 self.struct_list_box=[] 42 44 43 # save the title of the last page tab added 45 44 self.fit_page_name=[] … … 103 102 @param owner: the class responsible of plotting 104 103 """ 105 self.event_owner=owner 106 104 self.event_owner = owner 105 106 def set_model_list(self,dict): 107 """ 108 copy a dictionary of model into its own dictionary 109 @param dict: dictionnary made of model name as key and model class 110 as value 111 """ 112 self.model_list_box = dict 113 114 115 def get_current_page(self): 116 """ 117 @return the current page selected 118 """ 119 return self.GetPage(self.GetSelection() ) 120 107 121 def add_sim_page(self): 108 122 """ … … 125 139 except: 126 140 name = 'Fit' 141 from pageInfo import PageInfo 142 myinfo = PageInfo( self, data=data ) 143 myinfo.model_list_box = self.model_list_box.get_list() 144 myinfo.event_owner =self.event_owner 127 145 128 146 if not name in self.fit_page_name : 129 from fitpage 1D import FitPage1D130 panel = FitPage 1D(self,data, -1)147 from fitpage import FitPage 148 panel = FitPage(parent= self, page_info=myinfo, name=name ) 131 149 panel.name=name 132 150 … … 135 153 136 154 self.AddPage(page=panel,caption=name,select=True) 137 panel.populate_box( self.model_list_box)155 #panel.populate_box( self.model_list_box) 138 156 self.fit_page_name.append(name) 139 157 … … 150 168 @param npts: number of Q points 151 169 """ 170 ## storing page info 171 from pageInfo import PageInfo 172 myinfo = PageInfo( self, model ) 173 myinfo.model_list_box = self.model_list_box.get_list() 174 myinfo.event_owner =self.event_owner 175 152 176 from modelpage import ModelPage 153 #print "fitpanel model", model 154 panel = ModelPage(self,model,page_title, -1) 177 panel = ModelPage(self,myinfo,page_title) 155 178 panel.set_manager(self.manager) 156 179 panel.set_owner(self.event_owner) 180 181 157 182 self.AddPage(page=panel,caption="Model",select=True) 158 panel.populate_box( self.model_list_box)183 #panel.populate_box( self.model_list_box) 159 184 panel.name = page_title 160 185 self.draw_model_name=page_title … … 168 193 # We just created a model page, we are ready to plot the model 169 194 #self.manager.draw_model(model, model.name) 170 #FOR PLUGIN for somereason model.name is = BASEcomponent171 self.manager.draw_model(model, page_title)172 173 def new_help_add_model_page(self,model,description,page_title, qmin=0, qmax=0.1, npts=50):174 """175 #TODO: fill in description176 177 @param qmin: mimimum Q178 @param qmax: maximum Q179 @param npts: number of Q points180 """181 ## storing page info182 from pageInfo import PageInfo183 myinfo = PageInfo( self, model )184 myinfo.model_list_box = self.model_list_box185 from modelpage import ModelPage186 187 panel = ModelPage(self,myinfo,page_title)188 panel.set_manager(self.manager)189 panel.set_owner(self.event_owner)190 191 192 self.AddPage(page=panel,caption="Model",select=True)193 panel.populate_box( self.model_list_box)194 panel.name = page_title195 self.draw_model_name=page_title196 self.model_page_number=self.GetSelection()197 self.model_page=self.GetPage(self.GetSelection())198 199 200 # Set the range used to plot models201 self.model_page.set_range(qmin, qmax, npts)202 203 # We just created a model page, we are ready to plot the model204 #self.manager.draw_model(model, model.name)205 195 #FOR PLUGIN for some reason model.name is = BASEcomponent 206 self.manager.draw_model(model , page_title)196 self.manager.draw_model(model) 207 197 208 198 … … 226 216 self.model_page.select_model(model, page_title) 227 217 228 def get_current_page(self): 229 """ 230 @return the current page selected 231 """ 232 #return self.nb.GetCurrentPage() 233 return self.GetPage(self.GetSelection() ) 218 234 219 235 236 237 def set_model_list(self,dict): 238 """ 239 copy a dictionary of model into its own dictionary 240 @param dict: dictionnary made of model name as key and model class 241 as value 242 """ 243 self.model_list_box = dict 244 220 221 -
sansview/perspectives/fitting/fitting.py
rbb18ef1 rc77d859 14 14 from fit_thread import FitThread 15 15 import models 16 import fitpage 1D16 import fitpage 17 17 18 18 DEFAULT_BEAM = 0.005 … … 22 22 import time 23 23 import thread 24 24 class PlotInfo: 25 """ 26 store some plotting field 27 """ 28 _xunit = 'A^{-1}' 29 _xaxis= "\\rm{Q}" 30 _yunit = "cm^{-1}" 31 _yaxis= "\\rm{Intensity} " 32 id = "Model" 33 group_id = "Model" 34 title= None 35 info= None 36 37 25 38 class Plugin: 26 39 """ … … 40 53 self.mypanels=[] 41 54 # reference to the current running thread 42 self.calc_thread = None 55 self.calc_2D= None 56 self.calc_1D= None 57 self.calc_fit= None 58 43 59 # Start with a good default 44 60 self.elapsed = 0.022 … … 60 76 self.err_dy={} 61 77 62 def _on_data_error(self, event): 63 """ 64 receives and event from plotting plu-gins to store the data name and 65 their errors of y coordinates for 1Data hide and show error 66 """ 67 self.err_dy= event.err_dy 78 68 79 69 80 def populate_menu(self, id, owner): … … 79 90 self.menu1.Append(id1, '&Simultaneous') 80 91 wx.EVT_MENU(owner, id1, self.on_add_sim_page) 92 self.menu1.AppendSeparator() 81 93 #Set park engine 82 94 id3 = wx.NewId() … … 84 96 self.menu1.Append(id3, "Scipy",scipy_help) 85 97 wx.EVT_MENU(owner, id3, self._onset_engine_scipy) 86 98 self.menu1.AppendSeparator() 87 99 id3 = wx.NewId() 88 100 park_help = "Park Engine: Perform Complex fit. More in Help window...." … … 99 111 self.fit_panel.set_owner(owner) 100 112 self.fit_panel.set_model_list(self.menu_mng.get_model_list()) 101 owner.Bind(fitpage 1D.EVT_MODEL_BOX,self._on_model_panel)113 owner.Bind(fitpage.EVT_MODEL_BOX,self._on_model_panel) 102 114 103 115 #create menubar items … … 168 180 169 181 170 def _on_slicer_event(self, event):171 """172 Receive a panel as event and send it to guiframe173 @param event: event containing a panel174 """175 if event.panel!=None:176 new_panel = event.panel177 # Set group ID if available178 event_id = self.parent.popup_panel(new_panel)179 self.menu1.Append(event_id, new_panel.window_caption,180 "Show %s plot panel" % new_panel.window_caption)181 # Set UID to allow us to reference the panel later182 new_panel.uid = event_id183 new_panel184 self.mypanels.append(new_panel)185 return186 187 188 def _on_show_panel(self, event):189 print "_on_show_panel: fitting"190 191 182 192 183 def get_perspective(self): … … 240 231 241 232 233 234 235 def schedule_for_fit(self,value=0,fitproblem =None): 236 """ 237 Set the fit problem field to 0 or 1 to schedule that problem to fit. 238 Schedule the specified fitproblem or get the fit problem related to 239 the current page and set value. 240 @param value : integer 0 or 1 241 @param fitproblem: fitproblem to schedule or not to fit 242 """ 243 if fitproblem !=None: 244 fitproblem.schedule_tofit(value) 245 else: 246 current_pg=self.fit_panel.get_current_page() 247 for page, val in self.page_finder.iteritems(): 248 if page ==current_pg : 249 val.schedule_tofit(value) 250 break 251 252 253 def get_page_finder(self): 254 """ @return self.page_finder used also by simfitpage.py""" 255 return self.page_finder 256 257 258 def set_page_finder(self,modelname,names,values): 259 """ 260 Used by simfitpage.py to reset a parameter given the string constrainst. 261 @param modelname: the name ot the model for with the parameter has to reset 262 @param value: can be a string in this case. 263 @param names: the paramter name 264 @note: expecting park used for fit. 265 """ 266 sim_page= self.sim_page 267 for page, value in self.page_finder.iteritems(): 268 if page != sim_page: 269 list=value.get_model() 270 model = list[0] 271 if model.name== modelname: 272 value.set_model_param(names,values) 273 break 274 275 276 277 def split_string(self,item): 278 """ 279 receive a word containing dot and split it. used to split parameterset 280 name into model name and parameter name example: 281 paramaterset (item) = M1.A 282 @return model_name =M1 , parameter name =A 283 """ 284 if string.find(item,".")!=-1: 285 param_names= re.split("\.",item) 286 model_name=param_names[0] 287 param_name=param_names[1] 288 return model_name,param_name 289 290 291 def stop_fit(self): 292 """ 293 Stop the fit engine 294 """ 295 if self.calc_fit!= None and self.calc_thread.isrunning(): 296 self.calc_thread.stop() 297 wx.PostEvent(self.parent, StatusEvent(status="Fitting \ 298 is cancelled" , type="stop")) 299 300 301 def on_single_fit(self,id=None,qmin=None, qmax=None): 302 """ 303 perform fit for the current page and return chisqr,out and cov 304 @param engineName: type of fit to be performed 305 @param id: unique id corresponding to a fit problem(model, set of data) 306 @param model: model to fit 307 308 """ 309 #set an engine to perform fit 310 from sans.fit.Fitting import Fit 311 self.fitter = Fit(self._fit_engine) 312 #Setting an id to store model and data in fit engine 313 self.fit_id = 0 314 if id!=None: 315 self.fit_id = id 316 317 page_fitted = None 318 fit_problem = None 319 #Get information (model , data) related to the page on 320 #with the fit will be perform 321 current_pg= self.fit_panel.get_current_page() 322 simul_pg= self.sim_page 323 pars=[] 324 ## Check that the current page is different from self.sim_page 325 if current_pg != simul_pg: 326 value = self.page_finder[current_pg] 327 metadata = value.get_fit_data() 328 list = value.get_model() 329 model = list[0] 330 smearer = value.get_smearer() 331 332 #Create list of parameters for fitting used 333 templist=[] 334 try: 335 ## get the list of parameter names to fit 336 templist = current_pg.get_param_list() 337 338 for element in templist: 339 pars.append(str(element[1])) 340 341 pars.sort() 342 #Do the single fit 343 self.fitter.set_model(Model(model), self.fit_id, pars) 344 dy=[] 345 x=[] 346 y=[] 347 ## checking the validity of error 348 if metadata.__class__ in ["Data1D","Theory1D"]: 349 for i in range(len(metadata.dy)): 350 if metadata.dy[i] !=0: 351 dy.append(metadata.dy[i]) 352 x.append(metadata.x[i]) 353 y.append(metadata.y[i]) 354 if len(dy)>0: 355 metadata.dy=numpy.zeros(len(dy)) 356 metadata.dy=dy 357 metadata.y=numpy.zeros(len(y)) 358 metadata.y=y 359 metadata.x=numpy.zeros(len(x)) 360 metadata.x=x 361 362 self.fitter.set_data(data=metadata,Uid=self.fit_id, 363 smearer=smearer,qmin= qmin,qmax=qmax ) 364 365 self.fitter.select_problem_for_fit(Uid= self.fit_id, 366 value= value.get_scheduled()) 367 page_fitted=current_pg 368 369 except: 370 msg= "Single Fit error: %s" % sys.exc_value 371 wx.PostEvent(self.parent, StatusEvent(status= msg )) 372 return 373 # make sure to keep an alphabetic order 374 #of parameter names in the list 375 try: 376 ## If a thread is already started, stop it 377 if self.calc_fit!= None and self.calc_fit.isrunning(): 378 self.calc_fit.stop() 379 380 self.calc_fit=FitThread(parent =self.parent, 381 fn= self.fitter, 382 pars= pars, 383 cpage= page_fitted, 384 qmin=qmin, 385 qmax=qmax, 386 387 completefn=self._single_fit_completed, 388 updatefn=None) 389 self.calc_fit.queue() 390 self.calc_fit.ready(2.5) 391 392 except: 393 wx.PostEvent(self.parent, StatusEvent(status="Single Fit error: %s" % sys.exc_value)) 394 return 395 396 def on_simul_fit(self, id=None,qmin=None,qmax=None): 397 """ 398 perform fit for all the pages selected on simpage and return chisqr,out and cov 399 @param engineName: type of fit to be performed 400 @param id: unique id corresponding to a fit problem(model, set of data) 401 in park_integration 402 @param model: model to fit 403 404 """ 405 ##Setting an id to store model and data 406 self.fit_id= 0 407 #Setting an id to store model and data 408 if id!=None: 409 self.fit_id= id 410 ## count the number of fitproblem schedule to fit 411 fitproblem_count= 0 412 for value in self.page_finder.itervalues(): 413 if value.get_scheduled()==1: 414 fitproblem_count += 1 415 ## if simultaneous fit change automatically the engine to park 416 if fitproblem_count >1: 417 self._on_change_engine(engine='park') 418 from sans.fit.Fitting import Fit 419 self.fitter= Fit(self._fit_engine) 420 421 422 for page, value in self.page_finder.iteritems(): 423 try: 424 if value.get_scheduled()==1: 425 metadata = value.get_fit_data() 426 list = value.get_model() 427 model= list[0] 428 ## store page 429 cpage= page 430 #Get list of parameters name to fit 431 pars = [] 432 templist = [] 433 templist = page.get_param_list() 434 for element in templist: 435 try: 436 name = str(element[0].GetLabelText()) 437 pars.append(name) 438 except: 439 wx.PostEvent(self.parent, StatusEvent(status="Simultaneous Fit error: %s" % sys.exc_value)) 440 return 441 ## create a park model and reset parameter value if constraint 442 ## is given 443 new_model=Model(model) 444 param=value.get_model_param() 445 446 if len(param)>0: 447 for item in param: 448 param_value = item[1] 449 param_name = item[0] 450 451 new_model.parameterset[ param_name].set( param_value ) 452 453 self.fitter.set_model(new_model, self.fit_id, pars) 454 ## check that non -zero value are send as dy in the fit engine 455 dy=[] 456 x=[] 457 y=[] 458 if metadata.__class__ in ["Data1D","Theory1D"]: 459 for i in range(len(metadata.dy)): 460 if metadata.dy[i] !=0: 461 dy.append(metadata.dy[i]) 462 x.append(metadata.x[i]) 463 y.append(metadata.y[i]) 464 if len(dy)>0: 465 metadata.dy=numpy.zeros(len(dy)) 466 metadata.dy=dy 467 metadata.y=numpy.zeros(len(y)) 468 metadata.y=y 469 metadata.x=numpy.zeros(len(x)) 470 metadata.x=x 471 472 self.fitter.set_data(metadata,self.fit_id,qmin,qmax) 473 self.fitter.select_problem_for_fit(Uid= self.fit_id, 474 value= value.get_scheduled()) 475 self.fit_id += 1 476 value.clear_model_param() 477 478 except: 479 msg= "Simultaneous Fit error: %s" % sys.exc_value 480 wx.PostEvent(self.parent, StatusEvent(status= msg )) 481 return 482 483 #Do the simultaneous fit 484 try: 485 ## If a thread is already started, stop it 486 if self.calc_fit!= None and self.calc_fit.isrunning(): 487 self.calc_fit.stop() 488 ## perform single fit 489 if fitproblem_count==1: 490 self.calc_fit=FitThread(parent =self.parent, 491 fn= self.fitter, 492 qmin=qmin, 493 qmax=qmax, 494 ymin= ymin, 495 ymax= ymax, 496 cpage=cpage, 497 pars= pars, 498 completefn= self._simul_fit_completed, 499 updatefn=None) 500 501 else: 502 ## Perform more than 1 fit at the time 503 self.calc_fit=FitThread(parent =self.parent, 504 fn= self.fitter, 505 qmin=qmin, 506 qmax=qmax, 507 ymin= ymin, 508 ymax= ymax, 509 completefn= self._simul_fit_completed, 510 updatefn=None) 511 self.calc_fit.queue() 512 self.calc_fit.ready(2.5) 513 514 except: 515 msg= "Simultaneous Fit error: %s" % sys.exc_value 516 wx.PostEvent(self.parent, StatusEvent(status= msg )) 517 return 518 519 def set_smearer(self,smearer, qmin=None, qmax=None): 520 """ 521 Get a smear object and store it to a fit problem 522 @param smearer: smear object to allow smearing data 523 """ 524 current_pg=self.fit_panel.get_current_page() 525 self.page_finder[current_pg].set_smearer(smearer) 526 ## draw model 1D with smeared data 527 data = self.page_finder[current_pg].get_plotted_data() 528 list = self.page_finder[current_pg].get_model() 529 model = list[0] 530 smearer = value.get_smearer() 531 self.draw_model( model=model, data= data, smearer= smearer, 532 qmin= qmin, qmax= qmax) 533 534 535 536 def draw_model(self, model, data= None,smearer= None, 537 enable1D= True, enable2D= False, 538 qmin= DEFAULT_QMIN, qmax= DEFAULT_QMAX, qstep= DEFAULT_NPTS): 539 """ 540 Draw model. 541 @param model: the model to draw 542 @param name: the name of the model to draw 543 @param data: the data on which the model is based to be drawn 544 @param description: model's description 545 @param enable1D: if true enable drawing model 1D 546 @param enable2D: if true enable drawing model 2D 547 @param qmin: Range's minimum value to draw model 548 @param qmax: Range's maximum value to draw model 549 @param qstep: number of step to divide the x and y-axis 550 551 """ 552 ## draw model 1D with no loaded data 553 self._draw_model1D( model= model, data= data,enable1D=enable1D, smearer= smearer, 554 qmin= qmin, qmax= qmax, qstep= qstep ) 555 ## draw model 2D with no initial data 556 self._draw_model2D(model=model, 557 data = data, 558 enable2D= enable2D, 559 qmin=qmin, 560 qmax=qmax, 561 qstep=qstep) 562 563 564 242 565 def _onSelect(self,event): 243 566 """ … … 284 607 %sys.exc_value)) 285 608 return 286 287 288 def schedule_for_fit(self,value=0,fitproblem =None): 289 """ 290 Set the fit problem field to 0 or 1 to schedule that problem to fit. 291 Schedule the specified fitproblem or get the fit problem related to 292 the current page and set value. 293 @param value : integer 0 or 1 294 @param fitproblem: fitproblem to schedule or not to fit 295 """ 296 if fitproblem !=None: 297 fitproblem.schedule_tofit(value) 298 else: 299 current_pg=self.fit_panel.get_current_page() 300 for page, val in self.page_finder.iteritems(): 301 if page ==current_pg : 302 val.schedule_tofit(value) 303 break 304 305 306 def get_page_finder(self): 307 """ @return self.page_finder used also by simfitpage.py""" 308 return self.page_finder 309 310 311 def set_page_finder(self,modelname,names,values): 312 """ 313 Used by simfitpage.py to reset a parameter given the string constrainst. 314 @param modelname: the name ot the model for with the parameter has to reset 315 @param value: can be a string in this case. 316 @param names: the paramter name 317 @note: expecting park used for fit. 318 """ 319 sim_page= self.sim_page 320 for page, value in self.page_finder.iteritems(): 321 if page != sim_page: 322 list=value.get_model() 323 model = list[0] 324 if model.name== modelname: 325 value.set_model_param(names,values) 326 break 327 328 329 330 def split_string(self,item): 331 """ 332 receive a word containing dot and split it. used to split parameterset 333 name into model name and parameter name example: 334 paramaterset (item) = M1.A 335 @return model_name =M1 , parameter name =A 336 """ 337 if string.find(item,".")!=-1: 338 param_names= re.split("\.",item) 339 model_name=param_names[0] 340 param_name=param_names[1] 341 return model_name,param_name 342 343 344 def _single_fit_completed(self,result,pars,cpage,qmin,qmax,elapsed=None, 345 ymin=None, ymax=None, xmin=None, xmax=None): 609 610 def _single_fit_completed(self,result,pars,cpage,qmin,qmax,elapsed=None): 346 611 """ 347 612 Display fit result on one page of the notebook. … … 371 636 cpage.onsetValues(result.fitness, result.pvec,result.stderr) 372 637 ## plot the current model with new param 373 self.plot_helper(currpage=cpage,qmin=qmin,qmax=qmax, 374 ymin=ymin, ymax=ymax, 375 xmin=xmin, xmax=xmax,title=None) 638 metadata = self.page_finder[cpage].get_fit_data() 639 list = self.page_finder[cpage].get_model() 640 model = list[0] 641 self.draw_model( model=model, data= metadata,qmin= qmin, qmax= qmax) 642 376 643 except: 377 644 msg= "Single Fit completed but Following error occurred:" … … 429 696 return 430 697 431 432 def stop_fit(self): 433 """ 434 Stop the fit engine 435 """ 436 if self.calc_thread != None and self.calc_thread.isrunning(): 437 self.calc_thread.stop() 438 wx.PostEvent(self.parent, StatusEvent(status="Fitting \ 439 is cancelled" , type="stop")) 440 441 442 def _on_single_fit(self,id=None,qmin=None, qmax=None,ymin=None, ymax=None,xmin=None,xmax=None): 443 """ 444 perform fit for the current page and return chisqr,out and cov 445 @param engineName: type of fit to be performed 446 @param id: unique id corresponding to a fit problem(model, set of data) 447 @param model: model to fit 448 449 """ 450 #set an engine to perform fit 451 from sans.fit.Fitting import Fit 452 self.fitter = Fit(self._fit_engine) 453 #Setting an id to store model and data in fit engine 454 self.fit_id = 0 455 if id!=None: 456 self.fit_id = id 457 458 page_fitted = None 459 fit_problem = None 460 #Get information (model , data) related to the page on 461 #with the fit will be perform 462 current_pg= self.fit_panel.get_current_page() 463 simul_pg= self.sim_page 464 pars=[] 465 ## Check that the current page is different from self.sim_page 466 if current_pg != simul_pg: 467 value = self.page_finder[current_pg] 468 metadata = value.get_fit_data() 469 list = value.get_model() 470 model = list[0] 471 smearer = value.get_smearer() 472 473 #Create list of parameters for fitting used 474 templist=[] 475 try: 476 ## get the list of parameter names to fit 477 templist = current_pg.get_param_list() 478 for element in templist: 479 pars.append(str(element[0].GetLabelText())) 480 pars.sort() 481 482 #Do the single fit 483 self.fitter.set_model(Model(model), self.fit_id, pars) 484 dy=[] 485 x=[] 486 y=[] 487 ## checking the validity of error 488 if metadata.__class__ in ["Data1D","Theory1D"]: 489 for i in range(len(metadata.dy)): 490 if metadata.dy[i] !=0: 491 dy.append(metadata.dy[i]) 492 x.append(metadata.x[i]) 493 y.append(metadata.y[i]) 494 if len(dy)>0: 495 metadata.dy=numpy.zeros(len(dy)) 496 metadata.dy=dy 497 metadata.y=numpy.zeros(len(y)) 498 metadata.y=y 499 metadata.x=numpy.zeros(len(x)) 500 metadata.x=x 501 502 self.fitter.set_data(data=metadata,Uid=self.fit_id, 503 smearer=smearer,qmin= qmin,qmax=qmax, 504 ymin=ymin,ymax=ymax) 505 506 self.fitter.select_problem_for_fit(Uid= self.fit_id, 507 value= value.get_scheduled()) 508 page_fitted=current_pg 509 510 except: 511 msg= "Single Fit error: %s" % sys.exc_value 512 wx.PostEvent(self.parent, StatusEvent(status= msg )) 513 return 514 # make sure to keep an alphabetic order 515 #of parameter names in the list 516 try: 517 ## If a thread is already started, stop it 518 if self.calc_thread != None and self.calc_thread.isrunning(): 519 self.calc_thread.stop() 520 521 self.calc_thread =FitThread(parent =self.parent, 522 fn= self.fitter, 523 pars= pars, 524 cpage= page_fitted, 525 qmin=qmin, 526 qmax=qmax, 527 528 completefn=self._single_fit_completed, 529 updatefn=None) 530 self.calc_thread.queue() 531 self.calc_thread.ready(2.5) 532 533 except: 534 wx.PostEvent(self.parent, StatusEvent(status="Single Fit error: %s" % sys.exc_value)) 535 return 536 537 def _on_simul_fit(self, id=None,qmin=None,qmax=None, ymin=None, ymax=None): 538 """ 539 perform fit for all the pages selected on simpage and return chisqr,out and cov 540 @param engineName: type of fit to be performed 541 @param id: unique id corresponding to a fit problem(model, set of data) 542 in park_integration 543 @param model: model to fit 544 545 """ 546 ##Setting an id to store model and data 547 self.fit_id= 0 548 #Setting an id to store model and data 549 if id!=None: 550 self.fit_id= id 551 ## count the number of fitproblem schedule to fit 552 fitproblem_count= 0 553 for value in self.page_finder.itervalues(): 554 if value.get_scheduled()==1: 555 fitproblem_count += 1 556 ## if simultaneous fit change automatically the engine to park 557 if fitproblem_count >1: 558 self._on_change_engine(engine='park') 559 from sans.fit.Fitting import Fit 560 self.fitter= Fit(self._fit_engine) 561 562 563 for page, value in self.page_finder.iteritems(): 564 try: 565 if value.get_scheduled()==1: 566 metadata = value.get_fit_data() 567 list = value.get_model() 568 model= list[0] 569 ## store page 570 cpage= page 571 #Get list of parameters name to fit 572 pars = [] 573 templist = [] 574 templist = page.get_param_list() 575 for element in templist: 576 try: 577 name = str(element[0].GetLabelText()) 578 pars.append(name) 579 except: 580 wx.PostEvent(self.parent, StatusEvent(status="Simultaneous Fit error: %s" % sys.exc_value)) 581 return 582 ## create a park model and reset parameter value if constraint 583 ## is given 584 new_model=Model(model) 585 param=value.get_model_param() 586 587 if len(param)>0: 588 for item in param: 589 param_value = item[1] 590 param_name = item[0] 591 592 new_model.parameterset[ param_name].set( param_value ) 593 594 self.fitter.set_model(new_model, self.fit_id, pars) 595 ## check that non -zero value are send as dy in the fit engine 596 dy=[] 597 x=[] 598 y=[] 599 if metadata.__class__ in ["Data1D","Theory1D"]: 600 for i in range(len(metadata.dy)): 601 if metadata.dy[i] !=0: 602 dy.append(metadata.dy[i]) 603 x.append(metadata.x[i]) 604 y.append(metadata.y[i]) 605 if len(dy)>0: 606 metadata.dy=numpy.zeros(len(dy)) 607 metadata.dy=dy 608 metadata.y=numpy.zeros(len(y)) 609 metadata.y=y 610 metadata.x=numpy.zeros(len(x)) 611 metadata.x=x 612 613 self.fitter.set_data(metadata,self.fit_id,qmin,qmax,ymin,ymax) 614 self.fitter.select_problem_for_fit(Uid= self.fit_id, 615 value= value.get_scheduled()) 616 self.fit_id += 1 617 value.clear_model_param() 618 619 except: 620 msg= "Simultaneous Fit error: %s" % sys.exc_value 621 wx.PostEvent(self.parent, StatusEvent(status= msg )) 622 return 623 624 #Do the simultaneous fit 625 try: 626 ## If a thread is already started, stop it 627 if self.calc_thread != None and self.calc_thread.isrunning(): 628 self.calc_thread.stop() 629 ## perform single fit 630 if fitproblem_count==1: 631 self.calc_thread =FitThread(parent =self.parent, 632 fn= self.fitter, 633 qmin=qmin, 634 qmax=qmax, 635 ymin= ymin, 636 ymax= ymax, 637 cpage=cpage, 638 pars= pars, 639 completefn= self._simul_fit_completed, 640 updatefn=None) 641 642 else: 643 ## Perform more than 1 fit at the time 644 self.calc_thread =FitThread(parent =self.parent, 645 fn= self.fitter, 646 qmin=qmin, 647 qmax=qmax, 648 ymin= ymin, 649 ymax= ymax, 650 completefn= self._simul_fit_completed, 651 updatefn=None) 652 self.calc_thread.queue() 653 self.calc_thread.ready(2.5) 654 655 except: 656 msg= "Simultaneous Fit error: %s" % sys.exc_value 657 wx.PostEvent(self.parent, StatusEvent(status= msg )) 658 return 659 698 699 700 def _on_show_panel(self, event): 701 print "_on_show_panel: fitting" 702 703 660 704 def _onset_engine_park(self,event): 661 705 """ … … 671 715 self._on_change_engine('scipy') 672 716 717 def _on_slicer_event(self, event): 718 """ 719 Receive a panel as event and send it to guiframe 720 @param event: event containing a panel 721 """ 722 if event.panel!=None: 723 new_panel = event.panel 724 # Set group ID if available 725 event_id = self.parent.popup_panel(new_panel) 726 self.menu1.Append(event_id, new_panel.window_caption, 727 "Show %s plot panel" % new_panel.window_caption) 728 # Set UID to allow us to reference the panel later 729 new_panel.uid = event_id 730 new_panel 731 self.mypanels.append(new_panel) 732 return 673 733 674 734 def _on_change_engine(self, engine='park'): … … 686 746 @param evt: wx.combobox event 687 747 """ 688 689 748 model = evt.model 690 name = evt.name 691 749 if model ==None: 750 return 751 name = model.name 692 752 sim_page=self.sim_page 693 753 current_pg = self.fit_panel.get_current_page() … … 711 771 self.page_finder[current_pg].set_model(model,M_name) 712 772 713 714 773 # save model name 715 self.plot_helper(currpage= current_pg,qmin= None,qmax= None) 774 self.draw_model( model=model, data= metadata) 775 716 776 if self.sim_page!=None: 717 777 self.sim_page.add_model(self.page_finder) 718 778 719 779 720 721 def set_smearer(self,smearer): 722 """ 723 Get a smear object and store it to a fit problem 724 @param smearer: smear object to allow smearing data 725 """ 726 current_pg=self.fit_panel.get_current_page() 727 self.page_finder[current_pg].set_smearer(smearer) 728 729 730 def redraw_model(self,qmin= None,qmax= None): 731 """ 732 Draw a theory according to model changes or data range. 733 @param qmin: the minimum value plotted for theory 734 @param qmax: the maximum value plotted for theory 735 """ 736 current_pg=self.fit_panel.get_current_page() 737 for page, value in self.page_finder.iteritems(): 738 if page ==current_pg : 739 break 740 self.plot_helper(currpage=page,qmin= qmin,qmax= qmax) 741 742 743 744 def plot_helper(self,currpage, qmin=None,qmax=None, 745 ymin=None,ymax=None, xmin=None, xmax=None,title=None ): 746 """ 747 Plot a theory given a model and data 748 @param model: the model from where the theory is derived 749 @param currpage: page in a dictionary referring to some data 750 """ 751 if self.fit_panel.GetPageCount() >1: 752 for page in self.page_finder.iterkeys(): 753 if page == currpage : 754 data= self.page_finder[page].get_plotted_data() 755 list= self.page_finder[page].get_model() 756 smearer = self.page_finder[page].get_smearer() 757 model = list[0] 758 break 759 ## create Model 1D 760 if data != None and data.__class__.__name__ != 'Data2D': 761 x= numpy.zeros(len(data.x)) 762 y= numpy.zeros(len(data.y)) 763 764 theory = Theory1D(x=x, y=y) 765 theory.name = model.name 766 if hasattr(data ,"group_id"): 767 theory.group_id = data.group_id 768 theory.id = "Model" 769 770 x_name, x_units = data.get_xaxis() 771 y_name, y_units = data.get_yaxis() 772 theory.xaxis(x_name, x_units) 773 theory.yaxis(y_name, y_units) 774 if qmin == None : 775 qmin = min(data.x) 776 if qmax == None : 777 qmax = max(data.x) 778 779 j=0 780 try: 781 tempx = qmin 782 tempy = model.run(qmin) 783 theory.x[j]=tempx 784 theory.y[j]=tempy 785 j+=1 786 except : 787 wx.PostEvent(self.parent, StatusEvent(status="fitting \ 788 skipping point x %g %s" %(qmin, sys.exc_value))) 789 790 for i in range(len(data.x)): 791 try: 792 if data.x[i]> qmin and data.x[i]< qmax: 793 tempx = data.x[i] 794 tempy = model.run(tempx) 795 796 if j< i: 797 theory.x[j]=tempx 798 theory.y[j]=tempy 799 j+=1 800 801 except: 802 wx.PostEvent(self.parent, StatusEvent(status="fitting \ 803 skipping point x %g %s" %(data.x[i], sys.exc_value))) 804 try: 805 tempx = qmax 806 tempy = model.run(qmax) 807 808 theory.x[j]=tempx 809 theory.y[j]=tempy 810 j+=1 811 except: 812 wx.PostEvent(self.parent, StatusEvent(status="fitting \ 813 skipping point x %g %s" %(qmin, sys.exc_value)) ) 814 815 if smearer!=None: 816 theory.y= smearer(theory.y) 817 wx.PostEvent(self.parent, NewPlotEvent(plot=theory, 818 title=str(data.name))) 819 else: 820 ## create Model 2D 821 theory=Data2D(data.data, data.err_data) 822 theory.name= model.name 823 if title !=None: 824 self.title = title 825 theory.id= self.title 826 theory.group_id= self.title+data.name 827 else: 828 self.title= "Analytical model 2D " 829 theory.id= "Model" 830 theory.group_id= "Model"+data.name 831 theory.x_bins= data.x_bins 832 theory.y_bins= data.y_bins 833 tempy=[] 834 835 if qmin==None: 836 qmin=0 837 if qmax==None: 838 x= math.pow(max(math.fabs(data.xmax),math.fabs(data.xmin)),2) 839 y= math.pow(max(math.fabs(data.ymax),math.fabs(data.ymin)),2) 840 qmax=math.sqrt( x+y ) 841 842 if ymin==None: 843 ymin=data.ymin 844 if ymax==None: 845 ymax=data.ymax 846 if xmin ==None: 847 xmin=data.xmin 848 if xmax==None: 849 xmax=data.xmax 850 851 theory.data = numpy.zeros((len(data.y_bins),len(data.x_bins))) 852 for j in range(len(data.y_bins)): 853 for i in range(len(data.x_bins)): 854 tempqij=math.sqrt(( math.pow(data.y_bins[j],2)\ 855 +math.pow(data.x_bins[i],2) )) 856 857 if tempqij>= qmin and tempqij<= qmax: 858 theory.data[j][i] = model.runXY([data.y_bins[j], 859 data.x_bins[i]] ) 860 else: 861 ## Later, We need to decide which of 0 and None is better. 862 theory.data[j][i]=0 863 864 theory.detector= data.detector 865 theory.source= data.source 866 ## qmin, qmax will used later to define q range. 867 theory.qmin= qmin 868 theory.qmax= qmax 869 ## plot boundaries 870 theory.ymin= ymin 871 theory.ymax= ymax 872 theory.xmin= xmin 873 theory.xmax= xmax 874 875 wx.PostEvent(self.parent, NewPlotEvent(plot=theory, 876 title=self.title +str(data.name))) 877 878 780 879 781 def _on_model_menu(self, evt): 880 782 """ … … 893 795 self.fit_panel.add_model_page(model,description,name,topmenu=True) 894 796 895 def complete1D_from_data(self, output,model, data, x, elapsed, name): 896 """ 897 plot model 1D with data info 898 """ 899 y= output 900 x= data.x 901 theory = Theory1D(x=x, y=y) 902 theory.name = model.name 903 theory.group_id = data.group_id 904 theory.id = "Model" 905 906 x_name, x_units = data.get_xaxis() 907 y_name, y_units = data.get_yaxis() 908 theory.xaxis(x_name, x_units) 909 theory.yaxis(y_name, y_units) 910 wx.PostEvent(self.parent, NewPlotEvent(plot=theory, 911 title=str(data.name))) 912 913 def draw_model1D_from_Data(self, data, model,name=None, 914 qmin=None, qmax=None, smearer= None): 915 """ 916 Draw model 1D from loaded data1D 917 @param data: loaded data 918 @param model: the model to plot 919 """ 920 x = data.x 921 self.model= model 922 if qmin == None : 923 qmin = min(data.x) 924 if qmax == None : 925 qmax = max(data.x) 926 if name ==None: 927 name=model.name 928 try: 929 from model_thread import Calc1D 930 ## If a thread is already started, stop it 931 if self.calc_thread != None and self.calc_thread.isrunning(): 932 self.calc_thread.stop() 933 self.calc_thread = Calc1D( x= x, 934 model= self.model, 935 qmin= qmin, 936 qmax= qmax, 937 name= name, 938 smearer= smearer, 939 completefn= self.complete1D_from_data, 940 updatefn= self.update1D) 941 self.calc_thread.queue() 942 943 except: 944 msg= " Error occurred when drawing %s Model 1D: "%self.model.name 945 msg+= " %s"%sys.exc_value 946 wx.PostEvent( self.parent, StatusEvent(status= msg )) 947 return 948 949 def draw_model(self, model, name, data= None, description= None, 950 enable1D= True, enable2D= False, 951 qmin= DEFAULT_QMIN, qmax= DEFAULT_QMAX, qstep= DEFAULT_NPTS): 952 """ 953 Draw model. 954 @param model: the model to draw 955 @param name: the name of the model to draw 956 @param data: the data on which the model is based to be drawn 957 @param description: model's description 958 @param enable1D: if true enable drawing model 1D 959 @param enable2D: if true enable drawing model 2D 960 @param qmin: Range's minimum value to draw model 961 @param qmax: Range's maximum value to draw model 962 @param qstep: number of step to divide the x and y-axis 963 964 """ 965 ## draw model based on loaded data 966 if data !=None: 967 self.redraw_model(qmin,qmax) 968 return 969 ## draw model 1D with no loaded data 970 self._draw_model1D(model,name,model.description, enable1D,qmin,qmax, qstep) 971 ## draw model 2D with no initial data 972 self._draw_model2D(model=model, 973 description=model.description, 974 enable2D= enable2D, 975 qmin=qmin, 976 qmax=qmax, 977 qstep=qstep) 978 979 980 def update1D(self,x, output): 797 798 799 800 def _update1D(self,x, output): 981 801 """ 982 802 Update the output of plotting model 1D … … 984 804 self.calc_thread.ready(1) 985 805 986 def complete1D(self, x,output, elapsed, name,data=None): 987 """ 988 Complete plotting 1D data 989 """ 990 try: 991 y = output 992 new_plot = Theory1D(x, y) 993 new_plot.name = name 994 new_plot.xaxis("\\rm{Q}", 'A^{-1}') 995 new_plot.yaxis("\\rm{Intensity} ","cm^{-1}") 996 new_plot.id ="Model" 997 new_plot.group_id ="Model" 998 # Pass the reset flag to let the plotting event handler 999 # know that we are replacing the whole plot 1000 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 1001 title="Analytical model 1D ", reset=True )) 1002 1003 except: 1004 msg= " Error occurred when drawing %s Model 1D: "%new_plot.name 1005 msg+= " %s"%sys.exc_value 1006 wx.PostEvent( self.parent, StatusEvent(status= msg )) 1007 return 1008 1009 1010 def _draw_model1D(self, model, name, description= None, enable1D= True, 1011 qmin= DEFAULT_QMIN, qmax= DEFAULT_QMAX, qstep= DEFAULT_NPTS): 1012 """ 1013 Draw model 1D between qmin and qmax value 1014 @param model: the model to draw 1015 @param name: the name of the model 1016 @param description: descripion of the model as string 1017 @param enable1D: allow to draw model 1D if True else False 1018 @param qmin: the minimum value of the range to draw the model 1019 @param qmax: the maximum value of the range to draw the model 1020 @param qstep: the number of points to draw 1021 """ 1022 x= numpy.linspace(start= qmin, 1023 stop= qmax, 1024 num= qstep, 1025 endpoint=True 1026 ) 1027 self.model= model 1028 if enable1D: 1029 try: 1030 from model_thread import Calc1D 1031 ## If a thread is already started, stop it 1032 if self.calc_thread != None and self.calc_thread.isrunning(): 1033 self.calc_thread.stop() 1034 self.calc_thread = Calc1D( x= x, 1035 model= self.model, 1036 qmin= qmin, 1037 qmax= qmax, 1038 name= name, 1039 data=None, 1040 smearer=None, 1041 completefn= self.complete1D, 1042 updatefn= self.update1D) 1043 self.calc_thread.queue() 1044 1045 except: 1046 msg= " Error occurred when drawing %s Model 1D: "%self.model.name 1047 msg+= " %s"%sys.exc_value 1048 wx.PostEvent( self.parent, StatusEvent(status= msg )) 1049 return 1050 1051 1052 1053 1054 def update2D(self, output,time=None): 1055 """ 1056 Update the output of plotting model 1057 """ 1058 wx.PostEvent(self.parent, StatusEvent(status="Plot \ 1059 #updating ... ",type="update")) 1060 self.calc_thread.ready(0.01) 1061 1062 1063 def complete2D(self, output, elapsed, model, qmin, qmax,qstep=DEFAULT_NPTS): 1064 """ 1065 Complete get the result of modelthread and create model 2D 1066 that can be plot. 1067 """ 1068 msg = "Calc complete !" 1069 wx.PostEvent( self.parent, StatusEvent( status= msg , type="stop" )) 1070 1071 data = output 1072 temp= numpy.zeros(numpy.shape(data)) 1073 temp[temp==0]=1 1074 theory= Data2D(image=data, err_image=temp) 1075 806 def _fill_default_model2D(self, theory, qmax,qstep, qmin=None): 807 """ 808 fill Data2D with default value 809 @param theory: Data2D to fill 810 """ 1076 811 from DataLoader.data_info import Detector, Source 1077 812 1078 813 detector = Detector() 1079 theory.detector=[]1080 814 theory.detector.append(detector) 1081 815 … … 1083 817 theory.source= Source() 1084 818 theory.source.wavelength=2*math.pi/1e+32 1085 theory.x_bins =[] 1086 theory.y_bins =[] 819 1087 820 ## Create detector for Model 2D 1088 821 xmax=2*theory.detector[0].distance*math.atan(\ … … 1114 847 theory.y_bins.append(qy) 1115 848 1116 theory.name= model.name1117 849 theory.group_id ="Model" 1118 850 theory.id ="Model" … … 1122 854 theory.ymin= -qmax 1123 855 theory.ymax= qmax 856 857 858 def _get_plotting_info(self, data=None): 859 """ 860 get plotting info from data if data !=None 861 else use some default 862 """ 863 my_info = PlotInfo() 864 if data !=None: 865 if hasattr(data,"info"): 866 x_name, x_units = data.get_xaxis() 867 y_name, y_units = data.get_yaxis() 868 869 my_info._xunit = x_units 870 my_info._xaxis = x_name 871 my_info._yunit = y_units 872 my_info._yaxis = y_name 873 874 my_info.title= data.name 875 if hasattr(data, "info"): 876 my_info.info= data.info 877 if hasattr(data, "group_id"): 878 my_info.group_id= data.group_id 879 880 return my_info 881 882 def _complete1D(self, x,y, elapsed,model,data=None): 883 """ 884 Complete plotting 1D data 885 """ 886 try: 887 new_plot = Theory1D(x=x, y=y) 888 my_info = self._get_plotting_info( data) 889 new_plot.name = model.name 890 new_plot.id = my_info.id 891 new_plot.group_id = my_info.group_id 892 893 new_plot.xaxis( my_info._xaxis, my_info._xunit) 894 new_plot.yaxis( my_info._yaxis, my_info._yunit) 895 896 # Pass the reset flag to let the plotting event handler 897 # know that we are replacing the whole plot 898 title= my_info.title 899 if title== None: 900 title="Analytical model 1D " 901 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 902 title= str(title), reset=True )) 903 else: 904 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 905 title= str(title))) 906 907 except: 908 msg= " Error occurred when drawing %s Model 1D: "%new_plot.name 909 msg+= " %s"%sys.exc_value 910 wx.PostEvent( self.parent, StatusEvent(status= msg )) 911 return 912 913 914 915 916 def _update2D(self, output,time=None): 917 """ 918 Update the output of plotting model 919 """ 920 wx.PostEvent(self.parent, StatusEvent(status="Plot \ 921 #updating ... ",type="update")) 922 self.calc_thread.ready(0.01) 923 924 925 def _complete2D(self, image,data, model, elapsed,qmin, qmax,qstep=DEFAULT_NPTS): 926 """ 927 Complete get the result of modelthread and create model 2D 928 that can be plot. 929 """ 930 msg = "Calc complete !" 931 wx.PostEvent( self.parent, StatusEvent( status= msg , type="stop" )) 932 933 err_image = numpy.zeros(numpy.shape(image)) 934 err_image[err_image==0]= 1 935 theory= Data2D(image= image , err_image= err_image) 936 937 if data ==None: 938 self._fill_default_model2D(theory= theory, qmax=qmax,qstep=qstep, qmin= qmin) 939 theory.name= model.name 940 else: 941 theory.name= data.name 942 theory.id= "Model" 943 theory.group_id= "Model"+data.name 944 theory.x_bins= data.x_bins 945 theory.y_bins= data.y_bins 946 theory.detector= data.detector 947 theory.source= data.source 948 949 ## plot boundaries 950 theory.ymin= data.ymin 951 theory.ymax= data.ymax 952 theory.xmin= data.xmin 953 theory.xmax= data.xmax 954 1124 955 ## plot 1125 956 wx.PostEvent(self.parent, NewPlotEvent(plot=theory, 1126 957 title="Analytical model 2D ", reset=True )) 1127 958 1128 959 def _on_data_error(self, event): 960 """ 961 receives and event from plotting plu-gins to store the data name and 962 their errors of y coordinates for 1Data hide and show error 963 """ 964 self.err_dy= event.err_dy 1129 965 1130 def _draw_model2D(self,model,d escription=None, enable2D=False,966 def _draw_model2D(self,model,data=None,description=None, enable2D=False, 1131 967 qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, qstep=DEFAULT_NPTS): 1132 968 """ … … 1140 976 1141 977 """ 978 1142 979 x= numpy.linspace(start= -1*qmax, 1143 980 stop= qmax, … … 1148 985 num= qstep, 1149 986 endpoint=True ) 1150 1151 self.model= model 1152 if enable2D: 1153 try: 1154 from model_thread import Calc2D 1155 ## If a thread is already started, stop it 1156 if self.calc_thread != None and self.calc_thread.isrunning(): 1157 self.calc_thread.stop() 1158 self.calc_thread = Calc2D( x= x, 1159 y= y, model= self.model, 1160 qmin= qmin, 1161 qmax= qmax, 1162 qstep= qstep, 1163 completefn= self.complete2D, 1164 updatefn= self.update2D ) 1165 self.calc_thread.queue() 1166 1167 except: 1168 raise 1169 987 ## use data info instead 988 if data !=None: 989 ## check if data2D to plot 990 if hasattr(data, "x_bins"): 991 enable2D = True 992 x= data.x_bins 993 y= data.y_bins 994 995 if not enable2D: 996 return 997 try: 998 from model_thread import Calc2D 999 ## If a thread is already started, stop it 1000 if self.calc_2D != None and self.calc_2D.isrunning(): 1001 self.calc_2D.stop() 1002 self.calc_2D = Calc2D( x= x, 1003 y= y, 1004 model= model, 1005 data = data, 1006 qmin= qmin, 1007 qmax= qmax, 1008 qstep= qstep, 1009 completefn= self._complete2D, 1010 updatefn= self._update2D ) 1011 self.calc_2D.queue() 1012 1013 except: 1014 msg= " Error occurred when drawing %s Model 2D: "%model.name 1015 msg+= " %s"%sys.exc_value 1016 wx.PostEvent( self.parent, StatusEvent(status= msg )) 1017 return 1018 1019 def _draw_model1D(self, model, data=None, smearer= None, 1020 qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, qstep= DEFAULT_NPTS,enable1D= True): 1021 """ 1022 Draw model 1D from loaded data1D 1023 @param data: loaded data 1024 @param model: the model to plot 1025 """ 1026 1027 x= numpy.linspace(start= qmin, 1028 stop= qmax, 1029 num= qstep, 1030 endpoint=True 1031 ) 1032 if data!=None: 1033 ## check for data2D 1034 if hasattr(data,"x_bins"): 1035 return 1036 x = data.x 1037 if qmin == DEFAULT_QMIN : 1038 qmin = min(data.x) 1039 if qmax == DEFAULT_QMAX: 1040 qmax = max(data.x) 1041 1042 if not enable1D: 1043 return 1044 1045 try: 1046 from model_thread import Calc1D 1047 ## If a thread is already started, stop it 1048 if self.calc_1D!= None and self.calc_1D.isrunning(): 1049 self.calc_1D.stop() 1050 self.calc_1D= Calc1D( x= x, 1051 data = data, 1052 model= model, 1053 qmin = qmin, 1054 qmax = qmax, 1055 smearer = smearer, 1056 completefn = self._complete1D, 1057 updatefn = self._update1D ) 1058 self.calc_1D.queue() 1059 1060 except: 1061 msg= " Error occurred when drawing %s Model 1D: "%model.name 1062 msg+= " %s"%sys.exc_value 1063 wx.PostEvent( self.parent, StatusEvent(status= msg )) 1064 return 1065 1066 1067 1068 1170 1069 1171 1070 if __name__ == "__main__": -
sansview/perspectives/fitting/model_thread.py
rbb18ef1 rc77d859 90 90 """ 91 91 92 def __init__(self, x, y, model,qmin, qmax,qstep,92 def __init__(self, x, y, data,model,qmin, qmax,qstep, 93 93 completefn = None, 94 94 updatefn = None, … … 101 101 worktime) 102 102 self.qmin= qmin 103 self.qmax= qmax103 self.qmax= qmax 104 104 self.qstep= qstep 105 105 self.x = x 106 106 self.y = y 107 self.data= data 107 108 ## the model on to calculate 108 109 self.model = model … … 128 129 y = self.y 129 130 output = numpy.zeros((len(x),len(y))) 130 131 center_x=0 132 center_y=0 131 132 if self.qmin==None: 133 self.qmin = 0 134 if self.qmax== None: 135 if data ==None: 136 return 137 newx= math.pow(max(math.fabs(data.xmax),math.fabs(data.xmin)),2) 138 newy= math.pow(max(math.fabs(data.ymax),math.fabs(data.ymin)),2) 139 self.qmax=math.sqrt( newx + newy ) 133 140 134 141 self.starttime = time.time() 135 142 136 137 143 lx = len(self.x) 138 139 144 for i_x in range(len(self.x)): 140 145 # Check whether we need to bail out … … 143 148 144 149 for i_y in range(int(len(self.y))): 145 146 if (self.x[i_x]*self.x[i_x]+self.y[i_y]*self.y[i_y]) \147 < self.qmin * self.qmin:148 149 output[i_x] [i_y]= 0150 radius = self.x[i_x]*self.x[i_x]+self.y[i_y]*self.y[i_y] 151 152 if self.qmin <= radius or radius<= self.qmax: 153 value = self.model.runXY( [self.x[i_x], self.y[i_y]] ) 154 output[i_x] [i_y]=value 150 155 else: 151 value = self.model.runXY([self.x[i_x]-center_x, self.y[i_y]-center_y]) 152 output[i_x] [i_y]=value 156 output[i_x] [i_y]=0 153 157 154 158 elapsed = time.time()-self.starttime 155 self.complete( 156 output=output, elapsed=elapsed,model= self.model, 157 qmin= self.qmin, 158 qmax=self.qmax, 159 qstep=self.qstep) 159 self.complete( image = output, 160 data = self.data , 161 model = self.model, 162 elapsed = elapsed, 163 qmin = self.qmin, 164 qmax =self.qmax, 165 qstep = self.qstep ) 160 166 161 167 … … 256 262 qmin=None, 257 263 qmax=None, 258 name=None,259 264 smearer=None, 260 265 completefn = None, … … 272 277 self.qmax= qmax 273 278 self.model = model 274 self.name= name275 279 self.smearer= smearer 276 280 self.starttime = 0 277 281 278 282 def compute(self): 283 """ 284 Compute model 1d value given qmin , qmax , x value 285 """ 279 286 import numpy 280 287 281 288 output = numpy.zeros(len(self.x)) 282 if self.qmin==None: 283 self.qmin= min(self.x) 284 if self.qmax==None: 285 self.qmax= max(self.x) 286 289 287 290 self.starttime = time.time() 288 291 … … 294 297 value = self.model.run(self.x[i_x]) 295 298 output[i_x] = value 299 296 300 if self.smearer!=None: 297 301 output = self.smearer(output) 298 302 303 299 304 elapsed = time.time()-self.starttime 300 self.complete(x= self.x, output=output,301 elapsed=elapsed, name=self.name, data=self.data)305 self.complete(x= self.x, y= output, 306 elapsed=elapsed, model= self.model, data=self.data) 302 307 303 308 -
sansview/perspectives/fitting/modelpage.py
rbb18ef1 rc77d859 1 import sys 1 2 2 import wx 3 3 import wx.lib.newevent … … 12 12 _BOX_WIDTH = 80 13 13 14 15 16 17 class ModelPage(wx.ScrolledWindow): 14 import basepage 15 from basepage import BasicPage 16 17 18 class ModelPage(BasicPage): 18 19 """ 19 20 FitPanel class contains fields allowing to display results when … … 23 24 24 25 """ 25 ## Internal name for the AUI manager 26 window_name = "Fit page" 27 ## Title to appear on top of the window 28 window_caption = "Fit Page" 29 name="" 30 def __init__(self, parent,model,name, *args, **kwargs): 31 wx.ScrolledWindow.__init__(self, parent, *args, **kwargs) 26 def __init__(self,parent, page_info, name=""): 27 BasicPage.__init__(self, parent, page_info,name) 32 28 """ 33 29 Initialization of the Panel 34 30 """ 35 # model on which the fit would be performed 36 self.model=model 37 # Data member to store the dispersion object created 38 self._disp_obj_dict = {} 39 self.back_up_model= model.clone() 40 #list of dispersion paramaters 41 self.disp_list=[] 42 try: 43 self.disp_list=self.model.getDispParamList() 44 except: 45 pass 46 self.manager = None 47 self.parent = parent 48 self.event_owner = None 49 # this panel does contain data .existing data allow a different drawing 50 #on set_model parameters 51 self.data=None 52 #panel interface 53 self.vbox = wx.BoxSizer(wx.VERTICAL) 54 self.sizer11 = wx.BoxSizer(wx.HORIZONTAL) 55 #self.sizer10 = wx.GridBagSizer(5,5) 56 self.sizer9 = wx.GridBagSizer(5,5) 57 self.sizer8 = wx.GridBagSizer(5,5) 58 self.sizer7 = wx.GridBagSizer(5,5) 59 self.sizer6 = wx.GridBagSizer(5,5) 60 self.sizer5 = wx.GridBagSizer(5,5) 61 self.sizer4 = wx.GridBagSizer(5,5) 62 63 #model selection 64 self.vbox.Add(wx.StaticLine(self, -1), 0, wx.EXPAND, 0) 65 self.vbox.Add(self.sizer4) 66 #model description 67 self.vbox.Add(self.sizer11) 68 #model paramaters layer 69 self.vbox.Add(self.sizer5) 70 #polydispersion selected 71 self.vbox.Add(wx.StaticLine(self, -1), 0, wx.EXPAND, 0) 72 self.vbox.Add(self.sizer6) 73 #combox box for type of dispersion 74 self.vbox.Add(self.sizer7) 75 #dispersion parameters layer 76 self.vbox.Add(self.sizer8) 77 # plotting range 78 self.vbox.Add(self.sizer9) 79 #close layer 80 #self.vbox.Add(wx.StaticLine(self, -1), 0, wx.EXPAND, 0) 81 #self.vbox.Add(self.sizer10) 82 83 84 #------------------ sizer 4 draw------------------------ 85 86 ## structure combox box 87 self.structbox = wx.ComboBox(self, -1) 88 # define combox box 89 self.modelbox = wx.ComboBox(self, -1) 90 91 #enable model 2D draw 92 self.enable2D= False 93 self.fitrange= True 94 #filling sizer2 95 ix = 0 96 iy = 1 97 self.sizer4.Add(wx.StaticText(self,-1,'Model'),(iy,ix),(1,1)\ 98 , wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 99 ix += 1 100 self.sizer4.Add(self.modelbox,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 101 ix +=1 102 self.text_mult= wx.StaticText(self,-1,' x ') 103 self.sizer4.Add(self.text_mult,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 104 ix += 1 105 self.sizer4.Add(self.structbox,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 106 107 if hasattr(model ,"model2"): 108 name= model.model2.name 109 110 self.structbox.SetValue(name) 111 if hasattr(model ,"model1"): 112 name= model.model1.name 113 items = self.modelbox.GetItems() 114 self.modelbox.SetValue(name) 31 32 self._fill_model_sizer( self.sizer1) 33 self._fill_range_sizer() 34 if hasattr(self.page_info,"model"): 35 model=self.page_info.model 36 description="" 37 if model!=None: 38 description = self.page_info.model.description 39 self.set_model_param_sizer(self.model) 40 self.set_model_description(description,self.sizer2) 41 42 43 44 45 def _on_display_description(self, event): 46 """ 47 Show or Hide description 48 @param event: wx.EVT_RADIOBUTTON 49 """ 50 self._on_display_description_helper() 51 52 53 54 def _on_display_description_helper(self): 55 """ 56 Show or Hide description 57 @param event: wx.EVT_RADIOBUTTON 58 """ 59 ## save state of radiobox 60 self.page_info. save_radiobox_state( self.description_hide ) 61 self.page_info. save_radiobox_state( self.description_show ) 62 ## Show description 63 if not self.description_show.GetValue(): 64 self.sizer_description.Clear(True) 65 115 66 else: 116 #print "model view prev_model",name 117 self.modelbox.SetValue( name ) 118 ix += 1 119 id = wx.NewId() 120 self.model_view =wx.Button(self,id,'View 2D') 121 self.model_view.Bind(wx.EVT_BUTTON, self.onModel2D,id=id) 122 self.model_view.SetToolTipString("View model in 2D") 123 124 self.sizer4.Add(self.model_view,(iy,ix),(1,1),\ 125 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 126 127 self.model_view.Enable() 128 self.model_view.SetFocus() 129 130 ix = 0 131 iy += 1 132 self.sizer4.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 133 134 #----------sizer6------------------------------------------------- 135 self.disable_disp = wx.RadioButton(self, -1, 'No', (10, 10), style=wx.RB_GROUP) 136 self.enable_disp = wx.RadioButton(self, -1, 'Yes', (10, 30)) 137 self.Bind(wx.EVT_RADIOBUTTON, self.Set_DipersParam, id=self.disable_disp.GetId()) 138 self.Bind(wx.EVT_RADIOBUTTON, self.Set_DipersParam, id=self.enable_disp.GetId()) 139 ix= 0 140 iy=1 141 self.sizer6.Add(wx.StaticText(self,-1,'Polydispersity: '),(iy,ix),(1,1)\ 142 , wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 143 ix += 1 144 self.sizer6.Add(self.enable_disp ,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 145 ix += 1 146 self.sizer6.Add(self.disable_disp ,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 147 ix =0 148 iy+=1 149 self.sizer6.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 150 151 152 #---------sizer 9 draw---------------------------------------- 153 154 ## Q range 155 self.qmin_x= 0.001 156 self.qmax_x= 0.1 157 self.num_points= 100 158 159 160 self.qmin = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20)) 161 self.qmin.SetValue(format_number(self.qmin_x)) 162 self.qmin.SetToolTipString("Minimun value of Q in linear scale.") 163 self.qmin.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 164 self.qmin.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter) 165 166 self.qmax = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20)) 167 self.qmax.SetValue(format_number(self.qmax_x)) 168 self.qmax.SetToolTipString("Maximum value of Q in linear scale.") 169 self.qmax.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 170 self.qmax.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter) 171 172 67 model=self.page_info.model 68 description="" 69 if model!=None: 70 description = self.page_info.model.description 71 self.description = wx.StaticText( self,-1,str(description) ) 72 self.sizer_description.Add( self.description, 1, wx.EXPAND | wx.ALL, 10 ) 73 74 self.Layout() 75 76 77 def _fill_range_sizer(self): 78 """ 79 Fill the sizer containing the plotting range 80 add access to npts 81 """ 82 sizer_npts= wx.GridSizer(1, 1,5, 5) 83 173 84 self.npts = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20)) 174 85 self.npts.SetValue(format_number(self.num_points)) … … 176 87 self.npts.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 177 88 self.npts.Bind(wx.EVT_TEXT_ENTER, self._onparamEnter) 178 179 ix = 0 180 iy = 1 181 self.sizer9.Add(wx.StaticText(self, -1, 'Plotting Range'),(iy, ix),(1,1),\ 182 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 89 90 sizer_npts.Add(wx.StaticText(self, -1, 'Npts'),1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5) 91 sizer_npts.Add(self.npts,1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5) 92 self._set_range_sizer( title="Plotted Q Range", object= sizer_npts) 93 94 def _on_select_model(self, event): 95 """ 96 call back for model selection 97 """ 98 self._on_select_model_helper(event) 99 self.set_model_param_sizer(self.model) 100 self._set_sizer_gaussian() 101 self.name = self.model.name 102 self.model_view.SetFocus() 103 self.parent.model_page.name = self.name 104 self.parent.draw_model_name = self.name 105 self._draw_model() 106 107 def _fill_model_sizer(self, sizer): 108 """ 109 fill sizer containing model info 110 """ 111 id = wx.NewId() 112 self.model_view =wx.Button(self,id,'View 2D') 113 self.model_view.Bind(wx.EVT_BUTTON, self._onModel2D,id=id) 114 self.model_view.SetToolTipString("View model in 2D") 115 116 ## class base method to add view 2d button 117 self._set_model_sizer(sizer=sizer, title="Model",object= self.model_view ) 118 119 120 def _set_sizer_gaussian(self): 121 """ 122 draw sizer with gaussian dispersity parameters 123 """ 124 self.fittable_param=[] 125 self.fixed_param=[] 126 ##reset model dispersity to gaussian 127 self._reset_gaussian_dispers() 128 129 self.sizer4_4.Clear(True) 130 if self.model==None: 131 ##no model is selected 132 return 133 if not self.enable_disp.GetValue(): 134 ## the user didn't select dispersity display 135 return 136 ix=0 137 iy=1 138 disp = wx.StaticText(self, -1, 'Names') 139 self.sizer4_4.Add(disp,( iy, ix),(1,1), 140 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 183 141 ix += 1 184 self.sizer9.Add(wx.StaticText(self, -1, 'Min'),(iy, ix),(1,1),\ 185 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 186 ix += 1 187 self.sizer9.Add(wx.StaticText(self, -1, 'Max'),(iy, ix),(1,1),\ 188 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 189 ix += 1 190 self.sizer9.Add(wx.StaticText(self, -1, 'Npts'),(iy, ix),(1,1),\ 191 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 192 ix = 0 193 iy += 1 194 self.sizer9.Add(wx.StaticText(self, -1, 'Q range'),(iy, ix),(1,1),\ 195 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 196 ix += 1 197 self.sizer9.Add(self.qmin,(iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0) 198 ix += 1 199 self.sizer9.Add(self.qmax,(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0) 200 ix += 1 201 self.sizer9.Add(self.npts,(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0) 202 142 values = wx.StaticText(self, -1, 'Values') 143 self.sizer4_4.Add(values,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 144 145 ix += 1 146 npts = wx.StaticText(self, -1, 'Npts') 147 self.sizer4_4.Add(npts,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 148 ix += 1 149 nsigmas = wx.StaticText(self, -1, 'Nsigmas') 150 self.sizer4_4.Add(nsigmas,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 151 152 for item in self.model.dispersion.keys(): 153 name1=item+".width" 154 name2=item+".npts" 155 name3=item+".nsigmas" 156 iy += 1 157 for p in self.model.dispersion[item].keys(): 158 if p=="width": 159 ix = 0 160 name = wx.StaticText(self, -1, name1) 161 self.sizer4_4.Add( name,( iy, ix),(1,1), 162 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 163 ix = 1 164 value= self.model.getParam(name1) 165 ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), 166 style=wx.TE_PROCESS_ENTER) 167 168 ctl1.SetValue(str (format_number(value))) 169 ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 170 ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter) 171 self.sizer4_4.Add(ctl1, (iy,ix),(1,1), wx.EXPAND) 172 173 self.fittable_param.append([None,name1,ctl1,None, 174 None, None, None,None]) 175 176 elif p=="npts": 177 ix =2 178 value= self.model.getParam(name2) 179 Tctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), 180 style=wx.TE_PROCESS_ENTER) 181 182 Tctl1.SetValue(str (format_number(value))) 183 Tctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 184 Tctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter) 185 self.sizer4_4.Add(Tctl1, (iy,ix),(1,1), 186 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 187 188 self.fixed_param.append([None,name2, Tctl1,None,None, 189 None, None,None]) 190 191 elif p=="nsigmas": 192 ix =3 193 value= self.model.getParam(name3) 194 Tctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), 195 style=wx.TE_PROCESS_ENTER) 196 Tctl2.SetValue(str (format_number(value))) 197 Tctl2.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 198 Tctl2.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter) 199 self.sizer4_4.Add(Tctl2, (iy,ix),(1,1), 200 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 201 ix +=1 202 self.sizer4_4.Add((20,20), (iy,ix),(1,1), 203 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 204 205 self.fixed_param.append([None,name3, Tctl2, 206 None,None, None, None,None]) 207 208 msg = " Selected Distribution: Gaussian" 209 wx.PostEvent(self.parent.parent, StatusEvent( status= msg )) 203 210 ix =0 204 iy+=1 205 self.sizer9.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0) 206 207 # contains link between model ,all its parameters, and panel organization 208 self.parameters=[] 209 self.fixed_param=[] 210 self.fittable_param=[] 211 self.polydisp= {} 212 #contains link between a model and selected parameters to fit 213 self.param_toFit=[] 214 215 #dictionary of model name and model class 216 self.model_list_box={} 217 #Draw initial panel 218 #-----sizer 11--------------------model description------ 219 if self.model!=None: 220 self.set_panel(self.model) 221 self.theta_cb=None 222 223 224 self.vbox.Layout() 225 self.vbox.Fit(self) 226 self.SetSizer(self.vbox) 227 self.SetScrollbars(20,20,55,40) 228 229 self.Centre() 230 self.Layout() 231 self.parent.GetSizer().Layout() 232 def set_model_description(self, model=None): 233 234 if model !=None: 235 description="description" 236 else: 237 description="" 238 if hasattr(model,description.lower())and self.data==None: 239 self.sizer11.Clear(True) 240 self.box_description= wx.StaticBox(self, -1, 'Model Description') 241 boxsizer1 = wx.StaticBoxSizer(self.box_description, wx.VERTICAL) 242 boxsizer1.SetMinSize((320,20)) 243 self.description = wx.StaticText(self,-1,str(model.description)) 244 boxsizer1.Add(self.description, 0, wx.EXPAND) 245 self.sizer11.Add(boxsizer1,1, wx.EXPAND | wx.ALL, 2) 246 247 248 def set_owner(self,owner): 249 """ 250 set owner of fitpage 251 @param owner: the class responsible of plotting 252 """ 253 self.event_owner=owner 254 255 256 def set_manager(self, manager): 257 """ 258 set panel manager 259 @param manager: instance of plugin fitting 260 """ 261 self.manager = manager 262 263 def populate_box(self, dict): 264 """ 265 Populate each combox box of each page 266 @param page: the page to populate 267 """ 268 269 self.model_list_box = dict.get_list() 270 271 for item , mylist in self.model_list_box.iteritems(): 272 separator= "---%s---"%item 273 self.modelbox.Append(separator,"separator") 274 275 for models in mylist: 276 model= models() 277 name = model.__class__.__name__ 278 if hasattr(model, "name"): 279 name = model.name 280 self.modelbox.Append(name,models) 281 wx.EVT_COMBOBOX(self.modelbox,-1, self._on_select_model) 282 if item == "Structure Factors" : 283 for structs in mylist: 284 struct= structs() 285 name = struct.__class__.__name__ 286 if hasattr(struct, "name"): 287 name = struct.name 288 self.structbox.Append(name,structs) 289 wx.EVT_COMBOBOX(self.structbox,-1, self._on_select_model) 290 291 292 return 0 293 294 295 def Set_DipersParam(self, event): 296 if self.model ==None: 297 msg= " Select non - model value:%s !"%self.model 298 wx.PostEvent(self.parent.parent, StatusEvent(status= msg)) 299 return 300 if self.enable_disp.GetValue(): 301 if len(self.disp_list)==0: 302 ix=0 303 iy=1 304 self.fittable_param=[] 305 self.fixed_param=[] 306 self.sizer8.Clear(True) 307 model_disp = wx.StaticText(self, -1, 'No PolyDispersity for this model') 308 self.sizer7.Add(model_disp,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 309 self.vbox.Layout() 310 self.SetScrollbars(20,20,55,40) 311 self.Layout() 312 self.parent.GetSizer().Layout() 313 return 314 else: 315 if self.data !=None and self.model !=None: # allow to recognize data panel from model panel 316 317 318 self.cb1.SetValue(False) 319 self.select_all_param_helper() 320 321 self.populate_disp_box() 322 self.set_panel_dispers(self.disp_list) 323 324 else: 325 if self.data !=None and self.model!=None: 326 if self.cb1.GetValue(): 327 self.select_all_param_helper() 328 329 if self.back_up_model!=None: 330 keys = self.back_up_model.getDispParamList() 331 keys.sort() 332 #disperse param into the initial state 333 for item in keys: 334 value= self.back_up_model.getParam(item) 335 self.model.setParam(item, value) 336 self._draw_model() 337 338 339 self.fittable_param=[] 340 self.fixed_param=[] 341 self.sizer7.Clear(True) 342 self.sizer8.Clear(True) 343 self.vbox.Layout() 344 self.SetScrollbars(20,20,55,40) 345 self.Layout() 346 self.parent.GetSizer().Layout() 347 348 def populate_disp_box(self): 349 self.sizer7.Clear(True) 350 if len(self.disp_list)>0: 351 ix=0 352 iy=1 353 model_disp = wx.StaticText(self, -1, 'Model Disp') 354 self.sizer7.Add(model_disp,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 355 ix += 1 356 # set up the combox box 357 id = 0 358 import sans.models.dispersion_models 359 self.polydisp= sans.models.dispersion_models.models 360 self.disp_box = wx.ComboBox(self, -1) 361 self.disp_box.SetValue("GaussianModel") 362 for k,v in self.polydisp.iteritems(): 363 if str(v)=="MyModel": 364 # Remove the option until the rest of the code is ready for it 365 #self.disp_box.Insert("Select customized Model",id) 366 pass 367 else: 368 self.disp_box.Insert(str(v),id) 369 id+=1 370 371 wx.EVT_COMBOBOX(self.disp_box,-1, self._on_select_Disp) 372 self.sizer7.Add(self.disp_box,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 373 self.vbox.Layout() 374 self.SetScrollbars(20,20,55,40) 375 self.Layout() 376 self.parent.GetSizer().Layout() 377 378 379 def set_range(self, qmin_x, qmax_x, npts): 380 """ 381 Set the range for the plotted models 382 @param qmin: minimum Q 383 @param qmax: maximum Q 384 @param npts: number of Q bins 385 """ 386 # Set the data members 387 self.qmin_x = qmin_x 388 self.qmax_x = qmax_x 389 self.num_points = npts 390 391 # Set the controls 392 self.qmin.SetValue(format_number(self.qmin_x)) 393 self.qmax.SetValue(format_number(self.qmax_x)) 394 self.npts.SetValue(format_number(self.num_points)) 395 def checkFitRange(self): 396 """ 397 Check the validity of fitting range 398 @note: qmin should always be less than qmax or else each control box 399 background is colored in pink. 400 """ 401 402 flag = True 403 valueMin = self.qmin.GetValue() 404 valueMax = self.qmax.GetValue() 405 # Check for possible values entered 406 #print "fitpage: checkfitrange:",valueMin,valueMax 407 try: 408 if (float(valueMax)> float(valueMin)): 409 self.qmax.SetBackgroundColour(wx.WHITE) 410 self.qmin.SetBackgroundColour(wx.WHITE) 411 else: 412 flag = False 413 self.qmin.SetBackgroundColour("pink") 414 self.qmax.SetBackgroundColour("pink") 415 except: 416 flag = False 417 self.qmin.SetBackgroundColour("pink") 418 self.qmax.SetBackgroundColour("pink") 419 420 self.qmin.Refresh() 421 self.qmax.Refresh() 422 return flag 423 424 425 426 def onClose(self,event): 427 """ close the page associated with this panel""" 428 self.parent.onClose() 429 430 431 432 def onModel2D(self, event): 211 iy +=1 212 self.sizer4_4.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 213 self.sizer4_4.Layout() 214 self.sizer4.Layout() 215 self.SetScrollbars(20,20,200,100) 216 217 def _onModel2D(self, event): 433 218 """ 434 219 call manager to plot model in 2D … … 442 227 self._draw_model() 443 228 self.model_view.Disable() 444 445 446 229 447 230 def select_model(self, model, name): 448 231 """ … … 454 237 self.parent.draw_model_name = name 455 238 456 self.set_ panel(model)239 self.set_model_param_sizer(self.model) 457 240 self._draw_model() 458 459 if hasattr(model ,"model2"): 460 name= model.model2.name 461 items = self.structbox.GetItems() 462 for i in range(len(items)): 463 if items[i]==name: 464 self.structbox.SetSelection(i) 465 466 if hasattr(model ,"model1"): 467 name= model.model1.name 468 items = self.modelbox.GetItems() 469 for i in range(len(items)): 470 if items[i]==name: 471 self.modelbox.SetSelection(i) 472 else: 473 # Select the model from the combo box 474 items = self.modelbox.GetItems() 475 for i in range(len(items)): 476 if items[i]==name: 477 self.modelbox.SetSelection(i) 478 self.structbox.SetValue("No Structure") 479 241 ## keep the sizer view consistent with the model menu selecting 242 ## 243 self.structurebox.Hide() 244 self.text2.Hide() 245 self.multip_cb.SetValue(False) 246 247 if hasattr( model,"model1"): 248 self._set_model_sizer_selection( model ) 249 480 250 self.model_view.SetFocus() 481 482 def _on_select_Disp(self,event): 483 """ 484 allow selecting different dispersion 485 self.disp_list should change type later .now only gaussian 486 """ 487 type =event.GetString() 488 self.set_panel_dispers( self.disp_list,type ) 489 490 def _on_select_model(self,event): 491 """ 492 react when a model is selected from page's combo box 493 post an event to its owner to draw an appropriate theory 494 """ 495 self.disable_disp.SetValue(True) 496 self.sizer8.Clear(True) 497 self.sizer7.Clear(True) 498 self.vbox.Layout() 499 self.SetScrollbars(20,20,55,40) 500 self.Layout() 501 self.parent.GetSizer().Layout() 502 form_factor =self.modelbox.GetClientData(self.modelbox.GetCurrentSelection()) 503 struct_factor =self.structbox.GetClientData(self.structbox.GetCurrentSelection()) 504 505 if form_factor!="separator": 506 if struct_factor != None and struct_factor.__name__ != "NoStructure": 507 from sans.models.MultiplicationModel import MultiplicationModel 508 self.model= MultiplicationModel(form_factor(),struct_factor()) 509 else: 510 self.model= form_factor() 511 else: 512 self.model=None 513 msg= " Select non - model value:%s !Please select another model"%name 514 wx.PostEvent(self.parent.parent, StatusEvent(status= msg)) 515 516 self.set_model_description(self.model) 517 self.set_panel(self.model) 518 self.name= self.model.name 519 self.model_view.SetFocus() 520 self.parent.model_page.name= self.name 521 self.parent.draw_model_name= self.name 522 self._draw_model() 251 252 253 def set_model_description(self,description,sizer): 254 """ 255 fill a sizer with description 256 @param description: of type string 257 @param sizer: wx.BoxSizer() 258 """ 259 260 sizer.Clear(True) 261 box_description= wx.StaticBox(self, -1, 'Model Description') 262 boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 523 263 524 def get_model_box(self): 525 """ return reference to combox box self.model""" 526 return self.modelbox 527 528 529 def get_param_list(self): 530 """ 531 @return self.param_toFit: list containing references to TextCtrl 532 checked.Theses TextCtrl will allow reference to parameters to fit. 533 @raise: if return an empty list of parameter fit will nnote work 534 properly so raise ValueError,"missing parameter to fit" 535 """ 536 if self.param_toFit !=[]: 537 return self.param_toFit 538 else: 539 raise ValueError,"missing parameter to fit" 540 541 542 def set_panel(self,model): 264 sizer_selection=wx.BoxSizer(wx.HORIZONTAL) 265 266 self.description_show = wx.RadioButton(self, -1, 'Show', style=wx.RB_GROUP) 267 self.description_hide = wx.RadioButton(self, -1, 'Hide') 268 269 if description=="": 270 self.description_hide.SetValue(True) 271 description=" Description unavailable. Click for details" 272 273 self.description = wx.StaticText( self,-1,str(description) ) 274 275 self.Bind( wx.EVT_RADIOBUTTON, self._on_display_description, 276 id=self.description_hide.GetId() ) 277 278 self.Bind( wx.EVT_RADIOBUTTON, self._on_display_description, 279 id=self.description_show.GetId() ) 280 281 self.model_description = wx.Button(self, -1, "More Details") 282 self.model_description.SetToolTipString("See more description in help menu.") 283 284 self.page_info.save_radiobox_state( self.description_hide ) 285 self.page_info.save_radiobox_state( self.description_show ) 286 287 sizer_selection.Add( self.description_show ) 288 sizer_selection.Add( (20,20)) 289 sizer_selection.Add( self.description_hide ) 290 sizer_selection.Add( (20,20)) 291 sizer_selection.Add( self.model_description ) 292 293 294 self.sizer_description=wx.BoxSizer(wx.HORIZONTAL) 295 self.sizer_description.Add( self.description, 1, wx.EXPAND | wx.ALL, 10 ) 296 297 boxsizer1.Add( sizer_selection) 298 boxsizer1.Add( (20,20)) 299 boxsizer1.Add( self.sizer_description) 300 301 302 sizer.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10) 303 sizer.Layout() 304 305 306 307 def set_range(self, qmin, qmax, npts): 308 """ 309 Set the range for the plotted models 310 @param qmin: minimum Q 311 @param qmax: maximum Q 312 @param npts: number of Q bins 313 """ 314 # Set the data members 315 self.qmin_x = qmin_x 316 self.qmax_x = qmax_x 317 self.num_points = npts 318 319 # Set the controls 320 self.qmin.SetValue(format_number(self.qmin_x)) 321 self.qmax.SetValue(format_number(self.qmax_x)) 322 self.npts.SetValue(format_number(self.num_points)) 323 324 325 def set_model_param_sizer(self, model): 543 326 """ 544 327 Build the panel from the model content 545 328 @param model: the model selected in combo box for fitting purpose 546 329 """ 547 548 self.sizer5.Clear(True) 330 self.sizer3.Clear(True) 549 331 self.parameters = [] 550 332 self.param_toFit=[] 551 333 self.fixed_param=[] 552 if model !=None: 553 self.model = model 334 335 if model ==None: 336 ##no model avaiable to draw sizer 337 return 338 box_description= wx.StaticBox(self, -1,str("Model Parameters")) 339 boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 340 sizer = wx.GridBagSizer(5,5) 341 342 self.model = model 343 self.set_model_description(self.model.description,self.sizer2) 344 345 keys = self.model.getParamList() 346 #list of dispersion paramaters 347 self.disp_list=self.model.getDispParamList() 348 349 keys.sort() 350 351 iy = 1 352 ix = 0 353 self.text1_2 = wx.StaticText(self, -1, 'Names') 354 sizer.Add(self.text1_2,(iy, ix),(1,1),\ 355 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 356 ix +=1 357 self.text2_2 = wx.StaticText(self, -1, 'Values') 358 sizer.Add(self.text2_2,(iy, ix),(1,1),\ 359 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 360 ix +=1 361 self.text2_4 = wx.StaticText(self, -1, 'Units') 362 sizer.Add(self.text2_4,(iy, ix),(1,1),\ 363 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 364 self.text2_4.Hide() 365 366 367 for item in keys: 368 if not item in self.disp_list: 369 iy += 1 370 ix = 0 371 372 name = wx.StaticText(self, -1,item) 373 sizer.Add( name,( iy, ix),(1,1), 374 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 375 376 ix += 1 377 value= self.model.getParam(item) 378 ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), 379 style=wx.TE_PROCESS_ENTER) 380 381 ctl1.SetValue(str (format_number(value))) 382 ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 383 ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter) 384 sizer.Add(ctl1, (iy,ix),(1,1), wx.EXPAND) 385 386 ix +=1 387 # Units 388 try: 389 units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT) 390 except: 391 units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT) 392 sizer.Add(units, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 393 394 ##[cb state, name, value, "+/-", error of fit, min, max , units] 395 self.parameters.append([None,item, ctl1, 396 None,None, None, None,None]) 397 398 iy+=1 399 sizer.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 400 401 #Display units text on panel 402 for item in keys: 403 if self.model.details[item][0]!='': 404 self.text2_4.Show() 405 break 406 else: 407 self.text2_4.Hide() 408 409 boxsizer1.Add(sizer) 410 411 self.sizer3.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10) 412 self.sizer3.Layout() 413 self.SetScrollbars(20,20,200,100) 414 415 554 416 555 self.set_model_description( self.model) 556 557 keys = self.model.getParamList() 558 #list of dispersion paramaters 559 self.disp_list=self.model.getDispParamList() 560 561 keys.sort() 562 ik=0 563 im=1 564 565 iy = 1 566 ix = 0 567 self.cb1 = wx.CheckBox(self, -1,"Select all", (10, 10)) 568 if self.data!=None: 569 wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param) 570 self.cb1.SetValue(False) 571 else: 572 self.cb1.Disable() 573 self.cb1.Hide() 574 575 self.sizer5.Add(self.cb1,(iy, ix),(1,1),\ 576 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 577 ix +=1 578 self.text2_2 = wx.StaticText(self, -1, 'Values') 579 self.sizer5.Add(self.text2_2,(iy, ix),(1,1),\ 580 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 581 ix +=2 582 self.text2_3 = wx.StaticText(self, -1, 'Errors') 583 self.sizer5.Add(self.text2_3,(iy, ix),(1,1),\ 584 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 585 self.text2_3.Hide() 586 587 588 ix +=1 589 self.text2_4 = wx.StaticText(self, -1, 'Units') 590 self.sizer5.Add(self.text2_4,(iy, ix),(1,1),\ 591 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 592 self.text2_4.Hide() 593 disp_list=self.model.getDispParamList() 594 for item in keys: 595 if not item in disp_list: 596 iy += 1 597 ix = 0 598 599 cb = wx.CheckBox(self, -1, item, (10, 10)) 600 if self.data!=None: 601 cb.SetValue(False) 602 wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param) 603 else: 604 cb.Disable() 605 self.sizer5.Add( cb,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 606 607 ix += 1 608 value= self.model.getParam(item) 609 ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER) 610 ctl1.SetValue(str (format_number(value))) 611 ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 612 ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter) 613 self.sizer5.Add(ctl1, (iy,ix),(1,1), wx.EXPAND) 614 615 ix += 1 616 text2=wx.StaticText(self, -1, '+/-') 617 self.sizer5.Add(text2,(iy, ix),(1,1),\ 618 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 619 text2.Hide() 620 ix += 1 621 ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER) 622 self.sizer5.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 623 ctl2.Hide() 624 625 ix +=1 626 # Units 627 try: 628 units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT) 629 except: 630 units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT) 631 self.sizer5.Add(units, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 632 633 self.parameters.append([cb,ctl1,text2,ctl2]) 634 635 iy+=1 636 self.sizer5.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 637 638 #Display units text on panel 639 for item in keys: 640 if self.model.details[item][0]!='': 641 self.text2_4.Show() 642 break 643 else: 644 self.text2_4.Hide() 645 646 self.vbox.Layout() 647 self.SetScrollbars(20,20,55,40) 648 self.Layout() 649 self.parent.GetSizer().Layout() 650 651 652 653 def _selectDlg(self): 654 import os 655 dlg = wx.FileDialog(self, "Choose a weight file", os.getcwd(), "", "*.*", wx.OPEN) 656 path = None 657 if dlg.ShowModal() == wx.ID_OK: 658 path = dlg.GetPath() 659 dlg.Destroy() 660 return path 661 def read_file(self, path): 662 try: 663 if path==None: 664 wx.PostEvent(self.parent.parent, StatusEvent(status=\ 665 " Selected Distribution was not loaded: %s"%path)) 666 return None, None 667 input_f = open(path, 'r') 668 buff = input_f.read() 669 lines = buff.split('\n') 670 671 angles = [] 672 weights=[] 673 for line in lines: 674 toks = line.split() 675 if len(toks)==2: 676 try: 677 angle = float(toks[0]) 678 weight = float(toks[1]) 679 except: 680 # Skip non-data lines 681 pass 682 angles.append(angle) 683 weights.append(weight) 684 return numpy.array(angles), numpy.array(weights) 685 except: 686 raise 687 688 689 def select_disp_angle(self, event): 690 """ 691 Event for when a user select a parameter to average over. 692 @param event: check box event 693 """ 694 695 696 # Go through the list of dispersion check boxes to identify which one has changed 697 for p in self.disp_cb_dict: 698 # Catch which one of the box was just checked or unchecked. 699 if event.GetEventObject() == self.disp_cb_dict[p]: 700 417 418 class HelpWindow(wx.Frame): 419 def __init__(self, parent, id, title): 420 wx.Frame.__init__(self, parent, id, title, size=(570, 400)) 421 422 from sans.models.CylinderModel import CylinderModel 423 model = CylinderModel() 424 #from sans.models.LineModel import LineModel 425 #model = LineModel() 426 from pageInfo import PageInfo 427 myinfo = PageInfo(self,model) 428 from models import ModelList 429 mylist= ModelList() 430 431 from sans.models.SphereModel import SphereModel 432 from sans.models.SquareWellStructure import SquareWellStructure 433 from sans.models.DebyeModel import DebyeModel 434 from sans.models.LineModel import LineModel 435 name= "shapes" 436 list1= [SphereModel] 437 mylist.set_list( name, list1) 438 439 name= "Shape-independent" 440 list1= [DebyeModel] 441 mylist.set_list( name, list1) 442 443 name= "Structure Factors" 444 list1= [SquareWellStructure] 445 mylist.set_list( name, list1) 446 447 name= "Added models" 448 list1= [LineModel] 449 mylist.set_list( name, list1) 450 451 myinfo.model_list_box = mylist.get_list() 452 453 self.page = ModelPage(self, myinfo) 454 455 456 457 self.Centre() 458 self.Show(True) 459 460 461 462 if __name__=="__main__": 463 app = wx.App() 464 HelpWindow(None, -1, 'HelpWindow') 465 app.MainLoop() 701 466 702 if self.disp_cb_dict[p].GetValue() == True:703 # The user wants this parameter to be averaged.704 # Pop up the file selection dialog.705 path = self._selectDlg()706 707 # If nothing was selected, just return708 if path is None:709 self.disp_cb_dict[p].SetValue(False)710 return711 712 try:713 values,weights = self.read_file(path)714 except:715 wx.PostEvent(self.parent.parent, StatusEvent(status=\716 "Could not read input file"))717 return718 719 # If any of the two arrays is empty, notify the user that we won't720 # proceed721 if values is None or weights is None:722 wx.PostEvent(self.parent.parent, StatusEvent(status=\723 "The loaded %s distrubtion is corrupted or empty" % p))724 return725 726 # Tell the user that we are about to apply the distribution727 wx.PostEvent(self.parent.parent, StatusEvent(status=\728 "Applying loaded %s distribution: %s" % (p, path)))729 730 # Create the dispersion objects731 disp_model = ArrayDispersion()732 disp_model.set_weights(values, weights)733 # Store the object to make it persist outside the scope of this method734 #TODO: refactor model to clean this up?735 self._disp_obj_dict[p] = disp_model736 737 # Set the new model as the dispersion object for the selected parameter738 self.model.set_dispersion(p, disp_model)739 740 741 # Redraw the model742 self._draw_model()743 744 else:745 # The parameter was un-selected. Go back to Gaussian model (with 0 pts)746 disp_model = GaussianDispersion()747 # Store the object to make it persist outside the scope of this method748 #TODO: refactor model to clean this up?749 self._disp_obj_dict[p] = disp_model750 751 # Set the new model as the dispersion object for the selected parameter752 self.model.set_dispersion(p, disp_model)753 754 # Redraw the model755 self._draw_model()756 return757 758 759 760 761 def set_panel_dispers(self, disp_list, type="GaussianModel" ):762 """763 """764 765 self.fittable_param=[]766 self.fixed_param=[]767 768 ix=0769 iy=1770 ### this will become a separate method771 if type== "Select customized Model":772 ix=0773 iy=1774 self.sizer8.Clear(True)775 disp1 = wx.StaticText(self, -1, 'Array Dispersion')776 self.sizer8.Add(disp1,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)777 778 # Look for model parameters to which we can apply an ArrayDispersion model779 # Add a check box for each parameter.780 self.disp_cb_dict = {}781 for p in self.model.dispersion.keys():782 ix+=1783 self.disp_cb_dict[p] = wx.CheckBox(self, -1, p, (10, 10))784 785 wx.EVT_CHECKBOX(self, self.disp_cb_dict[p].GetId(), self.select_disp_angle)786 self.sizer8.Add(self.disp_cb_dict[p], (iy, ix), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)787 788 ix =0789 iy +=1790 self.sizer8.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)791 self.vbox.Layout()792 self.SetScrollbars(20,20,55,40)793 self.Layout()794 self.parent.GetSizer().Layout()795 796 if type== "GaussianModel" :797 798 self.sizer8.Clear(True)799 disp = wx.StaticText(self, -1, 'Dispersion')800 self.sizer8.Add(disp,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)801 ix += 1802 values = wx.StaticText(self, -1, 'Values')803 self.sizer8.Add(values,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)804 ix +=2805 self.text2_3 = wx.StaticText(self, -1, 'Errors')806 self.sizer8.Add(self.text2_3,(iy, ix),(1,1),\807 wx.EXPAND|wx.ADJUST_MINSIZE, 0)808 self.text2_3.Hide()809 810 ix += 1811 npts = wx.StaticText(self, -1, 'Npts')812 self.sizer8.Add(npts,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)813 ix += 1814 nsigmas = wx.StaticText(self, -1, 'Nsigmas')815 self.sizer8.Add(nsigmas,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)816 817 disp_list.sort()818 #print disp_list,self.model.dispersion819 for item in self.model.dispersion.keys():820 name1=item+".width"821 name2=item+".npts"822 name3=item+".nsigmas"823 iy += 1824 for p in self.model.dispersion[item].keys():825 #print "name 1 2 3", name1, name2, name3826 if p=="width":827 ix = 0828 cb = wx.CheckBox(self, -1, name1, (10, 10))829 if self.data !=None:830 cb.SetValue(False)831 wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)832 else:833 cb.Disable()834 self.sizer8.Add( cb,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)835 ix = 1836 value= self.model.getParam(name1)837 ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)838 ctl1.SetValue(str (format_number(value)))839 ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)840 ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)841 self.sizer8.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)842 843 ix = 2844 text2=wx.StaticText(self, -1, '+/-')845 self.sizer8.Add(text2,(iy, ix),(1,1),\846 wx.EXPAND|wx.ADJUST_MINSIZE, 0)847 text2.Hide()848 ix = 3849 ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)850 self.sizer8.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)851 ctl2.Hide()852 self.fittable_param.append([cb,ctl1,text2,ctl2])853 854 855 elif p=="npts":856 ix =4857 value= self.model.getParam(name2)858 Tctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER)859 Tctl.SetValue(str (format_number(value)))860 Tctl.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)861 Tctl.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)862 self.sizer8.Add(Tctl, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)863 self.fixed_param.append([name2, Tctl])864 elif p=="nsigmas":865 ix =5866 value= self.model.getParam(name3)867 Tctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER)868 Tctl.SetValue(str (format_number(value)))869 Tctl.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)870 Tctl.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)871 self.sizer8.Add(Tctl, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)872 self.fixed_param.append([name3, Tctl])873 wx.PostEvent(self.parent.parent, StatusEvent(status=\874 " Selected Distribution: Gaussian"))875 ix =0876 iy +=1877 self.sizer8.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)878 self.vbox.Layout()879 self.SetScrollbars(20,20,55,40)880 self.Layout()881 self.parent.GetSizer().Layout()882 883 def checkFitValues(self,val_min, val_max):884 """885 Check the validity of input values886 """887 flag = True888 min_value = val_min.GetValue()889 max_value = val_max.GetValue()890 # Check for possible values entered891 if min_value.lstrip().rstrip() =="-inf":892 min_value= -numpy.inf893 if max_value.lstrip().rstrip() =="+inf":894 max_value= numpy.inf895 if min_value==-numpy.inf and max_value== numpy.inf:896 val_min.SetBackgroundColour(wx.WHITE)897 val_min.Refresh()898 val_max.SetBackgroundColour(wx.WHITE)899 val_max.Refresh()900 return flag901 elif max_value== numpy.inf:902 try:903 float(min_value)904 val_min.SetBackgroundColour(wx.WHITE)905 val_min.Refresh()906 except:907 flag = False908 val_min.SetBackgroundColour("pink")909 val_min.Refresh()910 return flag911 elif min_value==-numpy.inf:912 try:913 float(max_value)914 val_max.SetBackgroundColour(wx.WHITE)915 val_max.Refresh()916 except:917 flag = False918 val_max.SetBackgroundColour("pink")919 val_max.Refresh()920 return flag921 else:922 if (float(min_value)< float(max_value)):923 val_min.SetBackgroundColour(wx.WHITE)924 val_min.Refresh()925 else:926 flag = False927 val_min.SetBackgroundColour("pink")928 val_min.Refresh()929 return flag930 931 932 def _onparamEnter(self,event):933 """934 when enter value on panel redraw model according to changed935 """936 self.set_model_parameter()937 938 def set_model_parameter(self):939 """940 """941 if len(self.parameters) !=0 and self.model !=None:942 # Flag to register when a parameter has changed.943 is_modified = False944 for item in self.fittable_param:945 try:946 name=str(item[0].GetLabelText())947 value= float(item[1].GetValue())948 # If the value of the parameter has changed,949 # update the model and set the is_modified flag950 if value != self.model.getParam(name):951 self.model.setParam(name,value)952 is_modified = True953 954 except:955 #raise956 wx.PostEvent(self.parent.parent, StatusEvent(status=\957 "Model Drawing Error:wrong value entered : %s"% sys.exc_value))958 return959 960 961 for item in self.fixed_param:962 try:963 name=str(item[0])964 value= float(item[1].GetValue())965 # If the value of the parameter has changed,966 # update the model and set the is_modified flag967 if value != self.model.getParam(name):968 self.model.setParam(name,value)969 is_modified = True970 971 except:972 raise973 wx.PostEvent(self.parent.parent, StatusEvent(status=\974 "Model Drawing Error:wrong value entered : %s"% sys.exc_value))975 976 for item in self.parameters:977 try:978 name=str(item[0].GetLabelText())979 value= float(item[1].GetValue())980 # If the value of the parameter has changed,981 # update the model and set the is_modified flag982 if value != self.model.getParam(name):983 self.model.setParam(name,value)984 is_modified = True985 986 except:987 #raise988 wx.PostEvent(self.parent.parent, StatusEvent(status=\989 "Model Drawing Error:wrong value entered : %s"% sys.exc_value))990 return991 992 993 # Here we should check whether the boundaries have been modified.994 # If qmin and qmax have been modified, update qmin and qmax and995 # set the is_modified flag to True996 from sans.guiframe.utils import check_value997 if check_value( self.qmin, self.qmax):998 if float(self.qmin.GetValue()) != self.qmin_x:999 self.qmin_x = float(self.qmin.GetValue())1000 is_modified = True1001 if float(self.qmax.GetValue()) != self.qmax_x:1002 self.qmax_x = float(self.qmax.GetValue())1003 is_modified = True1004 self.fitrange = True1005 else:1006 self.fitrange = False1007 if float(self.npts.GetValue()) != self.num_points:1008 self.num_points = float(self.npts.GetValue())1009 is_modified = True1010 1011 if is_modified:1012 self._draw_model()1013 1014 def _draw_model(self):1015 """1016 Method to draw or refresh a plotted model.1017 The method will use the data member from the model page1018 to build a call to the fitting perspective manager.1019 1020 [Note to coder: This way future changes will be done in only one place.]1021 """1022 if self.model !=None:1023 self.manager.draw_model(self.model, self.model.name, data=self.data,1024 qmin=self.qmin_x, qmax=self.qmax_x,1025 qstep= self.num_points,1026 enable2D=self.enable2D)1027 1028 def select_param(self,event):1029 """1030 1031 """1032 pass1033 def select_all_param(self,event):1034 """1035 1036 """1037 pass1038 def select_all_param_helper(self):1039 """1040 Allows selecting or delecting button1041 """1042 self.param_toFit=[]1043 if self.parameters !=[]:1044 if self.cb1.GetValue()==True:1045 for item in self.parameters:1046 item[0].SetValue(True)1047 list= [item[0],item[1],item[2],item[3]]1048 self.param_toFit.append(list )1049 if len(self.fittable_param)>0:1050 for item in self.fittable_param:1051 item[0].SetValue(True)1052 list= [item[0],item[1],item[2],item[3]]1053 self.param_toFit.append(list )1054 else:1055 for item in self.parameters:1056 item[0].SetValue(False)1057 for item in self.fittable_param:1058 item[0].SetValue(False)1059 self.param_toFit=[]1060 1061 1062 -
sansview/perspectives/fitting/models.py
rbb18ef1 rc77d859 226 226 list1 = self.shape_indep_list, 227 227 list2 = self.struct_list ) 228 self._fill_menu( menuinfo = ["Added models", added_models, 229 "List of additional models"], 230 list1= self.plugins, 231 list2 = self.struct_list) 228 232 229 233 self._fill_simple_menu( menuinfo= ["Structure Factors",structure_factor, … … 231 235 list1= self.struct_list ) 232 236 233 self._fill_simple_menu( menuinfo = ["Added models", added_models, 234 "List of additional models"], 235 list1= self.plugins) 237 236 238 return 0 237 239 -
sansview/perspectives/fitting/old_fitpage1D.py
r0b99881 rc77d859 140 140 # This sizer contains model list and chisqr value 141 141 #filling sizer4 142 ## structure combox box 143 self.structbox = wx.ComboBox(self, -1) 144 # define combox box 142 145 self.modelbox = wx.ComboBox(self, -1) 146 143 147 self.tcChi = wx.StaticText(self, -1, str(0), style=wx.ALIGN_LEFT) 144 148 self.tcChi.Hide() … … 149 153 self.sizer4.Add(wx.StaticText(self,-1,'Model'),(iy,ix),(1,1)\ 150 154 , wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 155 151 156 ix += 1 152 157 self.sizer4.Add(self.modelbox,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 158 ix +=1 159 self.text_mult= wx.StaticText(self,-1,' x ') 160 self.sizer4.Add(self.text_mult,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 161 ix += 1 162 self.sizer4.Add(self.structbox,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 163 164 165 153 166 ix += 1 154 167 self.sizer4.Add(self.text1_1,(iy,ix),(1,1),\ … … 262 275 # model on which the fit would be performed 263 276 self.model=None 264 277 265 278 self.back_up_model= None 266 279 #dictionary of model name and model class … … 282 295 self.Centre() 283 296 self.Layout() 284 self.GrandParent.GetSizer().Layout() 297 298 self.parent.GetSizer().Layout() 285 299 286 300 def compute_chisqr2D(self): … … 289 303 to the tcChi txtcrl 290 304 """ 291 flag=self.checkFitRange() 305 from sans.guiframe.utils import check_value 306 flag = check_value( self.qmin, self.qmax) 307 #flag=self.checkFitRange() 292 308 res=[] 293 309 if flag== True: … … 322 338 to the tcChi txtcrl 323 339 """ 324 flag=self.checkFitRange() 340 from sans.guiframe.utils import check_value 341 flag = check_value( self.qmin, self.qmax) 342 #flag=self.checkFitRange() 325 343 if flag== True: 326 344 try: … … 367 385 self.parent.GetSizer().Layout() 368 386 369 for item in self.model_list_box.itervalues(): 370 name = item.__name__ 371 if hasattr(item, "name"): 372 name = item.name 373 387 388 name= self.modelbox.GetString(self.modelbox.GetCurrentSelection()) 389 form_factor =self.modelbox.GetClientData(self.modelbox.GetCurrentSelection()) 390 struct_factor =self.structbox.GetClientData(self.structbox.GetCurrentSelection()) 391 392 393 if form_factor!="separator": 394 if struct_factor != None and struct_factor.__name__ != "NoStructure": 395 from sans.models.MultiplicationModel import MultiplicationModel 396 self.model= MultiplicationModel(form_factor(),struct_factor()) 397 else: 398 self.model= form_factor() 399 self.back_up_model= self.model.clone() 400 name= self.model.name 374 401 if name == None: 375 402 self.qmin.Disable() … … 378 405 self.qmin.Enable() 379 406 self.qmax.Enable() 380 381 if name ==event.GetString():382 try:383 self.model=item()384 self.back_up_model= self.model.clone()385 evt = ModelEventbox(model=self.model,name=name)386 wx.PostEvent(self.event_owner, evt)387 self.text1_1.Show()388 self.compute_chisqr()389 self.tcChi.Show()390 except:391 raise #ValueError,"model.name is not equal to model class name"392 break407 evt = ModelEventbox(model=self.model,name=name) 408 wx.PostEvent(self.event_owner, evt) 409 self.text1_1.Show() 410 self.tcChi.Show() 411 self.compute_chisqr() 412 413 414 else: 415 self.model=None 416 msg= " Select non - model value:%s ! Previous Model reloaded "%name 417 wx.PostEvent(self.parent.parent, StatusEvent(status= msg)) 418 419 self.set_panel(self.model) 393 420 394 421 395 422 def onFit(self,event): 396 """ signal for fitting""" 397 398 flag=self.checkFitRange() 399 self.set_manager(self.manager) 400 423 """ 424 signal for fitting .Perform single fit only 425 """ 426 from sans.guiframe.utils import check_value 427 flag = check_value( self.qmin, self.qmax) 428 429 if not flag: 430 msg= "Fitting range invalid" 431 wx.PostEvent(self.parent.parent, StatusEvent(status= msg )) 432 return 433 434 if len(self.param_toFit) <= 0: 435 msg= "Select at least one parameter to fit" 436 wx.PostEvent(self.parent.parent, StatusEvent(status= msg )) 437 return 438 401 439 self.qmin_x=float(self.qmin.GetValue()) 402 440 self.qmax_x =float( self.qmax.GetValue()) 403 if len(self.param_toFit) >0 and flag==True:404 405 406 407 408 409 410 411 412 441 442 self.manager.schedule_for_fit( value=1,fitproblem =None) 443 if hasattr(self.data, "data"): 444 #single fit for Data2D 445 self.manager._on_single_fit(qmin=self.qmin_x,qmax=self.qmax_x, 446 ymin=self.data.ymin, ymax=self.data.ymax, 447 xmin=self.data.xmin,xmax=self.data.xmax) 448 else: 449 #single fit for Data1D 450 self.manager._on_single_fit(qmin=self.qmin_x,qmax=self.qmax_x) 413 451 414 452 self.vbox.Layout() … … 416 454 self.Layout() 417 455 self.parent.GetSizer().Layout() 418 else: 419 wx.PostEvent(self.parent.parent, StatusEvent(status=\ 420 "Select at least one parameter to fit ")) 456 457 421 458 422 423 def _onTextEnter(self,event):424 """425 set a flag to determine if the fitting range entered by the user is valid426 """427 428 try:429 flag=self.checkFitRange()430 if flag==True and self.model!=None:431 self.manager.redraw_model(float(self.xmin.GetValue())\432 ,float(self.xmax.GetValue()))433 except:434 435 wx.PostEvent(self.parent.GrandParent, StatusEvent(status=\436 "Drawing Error:wrong value entered %s"% sys.exc_value))437 438 459 439 460 -
sansview/perspectives/fitting/old_modelpage.py
r0b99881 rc77d859 1 1 import sys 2 2 import wx 3 import wx.lib 3 import wx.lib.newevent 4 4 import numpy 5 5 import copy … … 84 84 #------------------ sizer 4 draw------------------------ 85 85 86 86 ## structure combox box 87 self.structbox = wx.ComboBox(self, -1) 87 88 # define combox box 88 89 self.modelbox = wx.ComboBox(self, -1) 89 # preview selected model name 90 self.prevmodel_name=name 91 #print "model view prev_model",name 92 self.modelbox.SetValue(self.prevmodel_name) 90 93 91 #enable model 2D draw 94 92 self.enable2D= False 93 self.fitrange= True 95 94 #filling sizer2 96 95 ix = 0 … … 100 99 ix += 1 101 100 self.sizer4.Add(self.modelbox,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 101 ix +=1 102 self.text_mult= wx.StaticText(self,-1,' x ') 103 self.sizer4.Add(self.text_mult,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 104 ix += 1 105 self.sizer4.Add(self.structbox,(iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 106 107 if hasattr(model ,"model2"): 108 name= model.model2.name 109 110 self.structbox.SetValue(name) 111 if hasattr(model ,"model1"): 112 name= model.model1.name 113 items = self.modelbox.GetItems() 114 self.modelbox.SetValue(name) 115 else: 116 #print "model view prev_model",name 117 self.modelbox.SetValue( name ) 102 118 ix += 1 103 119 id = wx.NewId() … … 188 204 iy+=1 189 205 self.sizer9.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0) 190 #----------sizer 10 draw------------------------------------------------------ 191 """ 192 id = wx.NewId() 193 self.btClose =wx.Button(self,id,'Close') 194 self.btClose.Bind(wx.EVT_BUTTON, self.onClose,id=id) 195 self.btClose.SetToolTipString("Close page.") 196 197 ix= 3 198 iy= 1 199 self.sizer10.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 200 ix +=1 201 self.sizer10.Add( self.btClose,(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0) 202 ix =0 203 iy+=1 204 self.sizer10.Add((20,20),(iy,ix),(1,1),wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 205 """ 206 206 207 # contains link between model ,all its parameters, and panel organization 207 208 self.parameters=[] … … 219 220 self.set_panel(self.model) 220 221 self.theta_cb=None 221 222 222 223 223 224 self.vbox.Layout() … … 229 230 self.Layout() 230 231 self.parent.GetSizer().Layout() 231 def set_model_description(self, model): 232 233 if model !=None and str(model.description)!=""and self.data==None: 234 self.sizer11.Clear(True) 235 self.box_description= wx.StaticBox(self, -1, 'Model Description') 236 boxsizer1 = wx.StaticBoxSizer(self.box_description, wx.VERTICAL) 237 boxsizer1.SetMinSize((320,20)) 238 self.description = wx.StaticText(self,-1,str(model.description)) 239 boxsizer1.Add(self.description, 0, wx.EXPAND) 240 self.sizer11.Add(boxsizer1,1, wx.EXPAND | wx.ALL, 2) 232 def set_model_description(self, model=None): 233 234 if model !=None: 235 description="description" 236 else: 237 description="" 238 if hasattr(model,description.lower())and self.data==None: 239 self.sizer11.Clear(True) 240 self.box_description= wx.StaticBox(self, -1, 'Model Description') 241 boxsizer1 = wx.StaticBoxSizer(self.box_description, wx.VERTICAL) 242 boxsizer1.SetMinSize((320,20)) 243 self.description = wx.StaticText(self,-1,str(model.description)) 244 boxsizer1.Add(self.description, 0, wx.EXPAND) 245 self.sizer11.Add(boxsizer1,1, wx.EXPAND | wx.ALL, 2) 241 246 242 247 … … 261 266 @param page: the page to populate 262 267 """ 263 id=0 264 self.model_list_box=dict 265 list_name=[] 266 for item in self.model_list_box.itervalues(): 267 name = item.__name__ 268 if hasattr(item, "name"): 269 name = item.name 270 list_name.append(name) 271 list_name.sort() 272 273 for name in list_name: 274 self.modelbox.Insert(name,int(id)) 275 id+=1 276 wx.EVT_COMBOBOX(self.modelbox,-1, self._on_select_model) 268 269 self.model_list_box = dict.get_list() 270 271 for item , mylist in self.model_list_box.iteritems(): 272 separator= "---%s---"%item 273 self.modelbox.Append(separator,"separator") 274 275 for models in mylist: 276 model= models() 277 name = model.__class__.__name__ 278 if hasattr(model, "name"): 279 name = model.name 280 self.modelbox.Append(name,models) 281 wx.EVT_COMBOBOX(self.modelbox,-1, self._on_select_model) 282 if item == "Structure Factors" : 283 for structs in mylist: 284 struct= structs() 285 name = struct.__class__.__name__ 286 if hasattr(struct, "name"): 287 name = struct.name 288 self.structbox.Append(name,structs) 289 wx.EVT_COMBOBOX(self.structbox,-1, self._on_select_model) 290 277 291 return 0 278 292 279 293 280 294 def Set_DipersParam(self, event): 295 if self.model ==None: 296 msg= " Select non - model value:%s !"%self.model 297 wx.PostEvent(self.parent.parent, StatusEvent(status= msg)) 298 return 281 299 if self.enable_disp.GetValue(): 282 300 if len(self.disp_list)==0: … … 417 435 # If the 2D display is not currently enabled, plot the model in 2D 418 436 # and set the enable2D flag. 419 if self.enable2D==False: 420 self.enable2D=True 437 if self.fitrange: 438 self.enable2D = True 439 440 if self.enable2D: 421 441 self._draw_model() 422 442 self.model_view.Disable() 443 423 444 424 445 … … 433 454 434 455 self.set_panel(model) 435 self._draw_model(name) 436 437 # Select the model from the combo box 438 items = self.modelbox.GetItems() 439 for i in range(len(items)): 440 if items[i]==name: 441 self.modelbox.SetSelection(i) 442 self.model_view.SetFocus() 456 self._draw_model() 457 458 if hasattr(model ,"model2"): 459 name= model.model2.name 460 items = self.structbox.GetItems() 461 for i in range(len(items)): 462 if items[i]==name: 463 self.structbox.SetSelection(i) 464 465 if hasattr(model ,"model1"): 466 name= model.model1.name 467 items = self.modelbox.GetItems() 468 for i in range(len(items)): 469 if items[i]==name: 470 self.modelbox.SetSelection(i) 471 else: 472 # Select the model from the combo box 473 items = self.modelbox.GetItems() 474 for i in range(len(items)): 475 if items[i]==name: 476 self.modelbox.SetSelection(i) 477 self.structbox.SetValue("No Structure") 478 479 self.model_view.SetFocus() 443 480 444 481 def _on_select_Disp(self,event): … … 462 499 self.Layout() 463 500 self.parent.GetSizer().Layout() 464 for item in self.model_list_box.itervalues(): 465 name = item.__name__ 466 if hasattr(item, "name"): 467 name = item.name 468 if name ==event.GetString(): 469 model=item() 470 self.model= model 471 self.set_panel(model) 472 self.name= name 473 self.model_view.SetFocus() 474 self.parent.model_page.name=name 475 self.parent.draw_model_name=name 501 form_factor =self.modelbox.GetClientData(self.modelbox.GetCurrentSelection()) 502 struct_factor =self.structbox.GetClientData(self.structbox.GetCurrentSelection()) 503 504 if form_factor!="separator": 505 if struct_factor != None and struct_factor.__name__ != "NoStructure": 506 from sans.models.MultiplicationModel import MultiplicationModel 507 self.model= MultiplicationModel(form_factor(),struct_factor()) 508 else: 509 self.model= form_factor() 510 else: 511 self.model=None 512 msg= " Select non - model value:%s !Please select another model"%name 513 wx.PostEvent(self.parent.parent, StatusEvent(status= msg)) 476 514 477 self._draw_model(name) 478 515 self.set_model_description(self.model) 516 self.set_panel(self.model) 517 self.name= self.model.name 518 self.model_view.SetFocus() 519 self.parent.model_page.name= self.name 520 self.parent.draw_model_name= self.name 521 self._draw_model() 479 522 480 523 def get_model_box(self): … … 506 549 self.param_toFit=[] 507 550 self.fixed_param=[] 508 self.model = model 509 510 self.set_model_description( self.model) 511 512 keys = self.model.getParamList() 513 #list of dispersion paramaters 514 self.disp_list=self.model.getDispParamList() 515 516 keys.sort() 517 ik=0 518 im=1 519 520 iy = 1 521 ix = 0 522 self.cb1 = wx.CheckBox(self, -1,"Select all", (10, 10)) 523 if self.data!=None: 524 wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param) 525 self.cb1.SetValue(False) 526 else: 527 self.cb1.Disable() 528 self.cb1.Hide() 529 530 self.sizer5.Add(self.cb1,(iy, ix),(1,1),\ 531 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 532 ix +=1 533 self.text2_2 = wx.StaticText(self, -1, 'Values') 534 self.sizer5.Add(self.text2_2,(iy, ix),(1,1),\ 535 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 536 ix +=2 537 self.text2_3 = wx.StaticText(self, -1, 'Errors') 538 self.sizer5.Add(self.text2_3,(iy, ix),(1,1),\ 539 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 540 self.text2_3.Hide() 541 542 543 ix +=1 544 self.text2_4 = wx.StaticText(self, -1, 'Units') 545 self.sizer5.Add(self.text2_4,(iy, ix),(1,1),\ 546 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 547 self.text2_4.Hide() 548 disp_list=self.model.getDispParamList() 549 for item in keys: 550 if not item in disp_list: 551 iy += 1 552 ix = 0 553 554 cb = wx.CheckBox(self, -1, item, (10, 10)) 555 if self.data!=None: 556 cb.SetValue(False) 557 wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param) 551 if model !=None: 552 self.model = model 553 554 self.set_model_description( self.model) 555 556 keys = self.model.getParamList() 557 #list of dispersion paramaters 558 self.disp_list=self.model.getDispParamList() 559 560 keys.sort() 561 ik=0 562 im=1 563 564 iy = 1 565 ix = 0 566 self.cb1 = wx.CheckBox(self, -1,"Select all", (10, 10)) 567 if self.data!=None: 568 wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param) 569 self.cb1.SetValue(False) 570 else: 571 self.cb1.Disable() 572 self.cb1.Hide() 573 574 self.sizer5.Add(self.cb1,(iy, ix),(1,1),\ 575 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 576 ix +=1 577 self.text2_2 = wx.StaticText(self, -1, 'Values') 578 self.sizer5.Add(self.text2_2,(iy, ix),(1,1),\ 579 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 580 ix +=2 581 self.text2_3 = wx.StaticText(self, -1, 'Errors') 582 self.sizer5.Add(self.text2_3,(iy, ix),(1,1),\ 583 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 584 self.text2_3.Hide() 585 586 587 ix +=1 588 self.text2_4 = wx.StaticText(self, -1, 'Units') 589 self.sizer5.Add(self.text2_4,(iy, ix),(1,1),\ 590 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 591 self.text2_4.Hide() 592 disp_list=self.model.getDispParamList() 593 for item in keys: 594 if not item in disp_list: 595 iy += 1 596 ix = 0 597 598 cb = wx.CheckBox(self, -1, item, (10, 10)) 599 if self.data!=None: 600 cb.SetValue(False) 601 wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param) 602 else: 603 cb.Disable() 604 self.sizer5.Add( cb,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 605 606 ix += 1 607 value= self.model.getParam(item) 608 ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER) 609 ctl1.SetValue(str (format_number(value))) 610 ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 611 ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter) 612 self.sizer5.Add(ctl1, (iy,ix),(1,1), wx.EXPAND) 613 614 ix += 1 615 text2=wx.StaticText(self, -1, '+/-') 616 self.sizer5.Add(text2,(iy, ix),(1,1),\ 617 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 618 text2.Hide() 619 ix += 1 620 ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER) 621 self.sizer5.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 622 ctl2.Hide() 623 624 ix +=1 625 # Units 626 try: 627 units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT) 628 except: 629 units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT) 630 self.sizer5.Add(units, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 631 632 self.parameters.append([cb,ctl1,text2,ctl2]) 633 634 iy+=1 635 self.sizer5.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 636 637 #Display units text on panel 638 for item in keys: 639 if self.model.details[item][0]!='': 640 self.text2_4.Show() 641 break 558 642 else: 559 cb.Disable() 560 self.sizer5.Add( cb,( iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 561 562 ix += 1 563 value= self.model.getParam(item) 564 ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER) 565 ctl1.SetValue(str (format_number(value))) 566 ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter) 567 ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter) 568 self.sizer5.Add(ctl1, (iy,ix),(1,1), wx.EXPAND) 569 570 ix += 1 571 text2=wx.StaticText(self, -1, '+/-') 572 self.sizer5.Add(text2,(iy, ix),(1,1),\ 573 wx.EXPAND|wx.ADJUST_MINSIZE, 0) 574 text2.Hide() 575 ix += 1 576 ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER) 577 self.sizer5.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 578 ctl2.Hide() 579 580 ix +=1 581 # Units 582 try: 583 units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT) 584 except: 585 units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT) 586 self.sizer5.Add(units, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 587 588 self.parameters.append([cb,ctl1,text2,ctl2]) 589 590 iy+=1 591 self.sizer5.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 592 593 #Display units text on panel 594 for item in keys: 595 if self.model.details[item][0]!='': 596 self.text2_4.Show() 597 break 598 else: 599 self.text2_4.Hide() 600 643 self.text2_4.Hide() 644 601 645 self.vbox.Layout() 602 646 self.SetScrollbars(20,20,55,40) … … 949 993 # If qmin and qmax have been modified, update qmin and qmax and 950 994 # set the is_modified flag to True 951 if float(self.qmin.GetValue()) != self.qmin_x: 952 self.qmin_x = float(self.qmin.GetValue()) 953 is_modified = True 954 if float(self.qmax.GetValue()) != self.qmax_x: 955 self.qmax_x = float(self.qmax.GetValue()) 956 is_modified = True 957 995 from sans.guiframe.utils import check_value 996 if check_value( self.qmin, self.qmax): 997 if float(self.qmin.GetValue()) != self.qmin_x: 998 self.qmin_x = float(self.qmin.GetValue()) 999 is_modified = True 1000 if float(self.qmax.GetValue()) != self.qmax_x: 1001 self.qmax_x = float(self.qmax.GetValue()) 1002 is_modified = True 1003 self.fitrange = True 1004 else: 1005 self.fitrange = False 958 1006 if float(self.npts.GetValue()) != self.num_points: 959 1007 self.num_points = float(self.npts.GetValue()) … … 963 1011 self._draw_model() 964 1012 965 def _draw_model(self , name=None):1013 def _draw_model(self): 966 1014 """ 967 1015 Method to draw or refresh a plotted model. … … 971 1019 [Note to coder: This way future changes will be done in only one place.] 972 1020 """ 973 if name==None: 974 name= self.model.name 975 976 self.manager.draw_model(self.model, name, data=self.data, 977 qmin=self.qmin_x, qmax=self.qmax_x, 978 qstep= self.num_points, 979 enable2D=self.enable2D) 1021 if self.model !=None: 1022 self.manager.draw_model(self.model, self.model.name, data=self.data, 1023 qmin=self.qmin_x, qmax=self.qmax_x, 1024 qstep= self.num_points, 1025 enable2D=self.enable2D) 980 1026 981 1027 def select_param(self,event):
Note: See TracChangeset
for help on using the changeset viewer.