Changeset 1779 for branches/mergetest/python/asapfitter.py
- Timestamp:
- 07/29/10 19:13:46 (14 years ago)
- Location:
- branches/mergetest
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/mergetest
- Property svn:mergeinfo changed
-
branches/mergetest/python/asapfitter.py
r1739 r1779 1 1 import _asap 2 2 from asap import rcParams 3 from asap import print_log _dec3 from asap import print_log, print_log_dec 4 4 from asap import _n_bools 5 5 from asap import mask_and 6 from asap import asaplog 6 7 7 8 class fitter: … … 59 60 msg = "Please give a correct scan" 60 61 if rcParams['verbose']: 61 print msg 62 #print msg 63 asaplog.push(msg) 64 print_log('ERROR') 62 65 return 63 66 else: … … 79 82 lpoly: use polynomial of the order given with linear least squares fit 80 83 gauss: fit the number of gaussian specified 84 lorentz: fit the number of lorentzian specified 81 85 Example: 82 fitter.set_function(gauss=2) # will fit two gaussians83 86 fitter.set_function(poly=3) # will fit a 3rd order polynomial via nonlinear method 84 87 fitter.set_function(lpoly=3) # will fit a 3rd order polynomial via linear method 88 fitter.set_function(gauss=2) # will fit two gaussians 89 fitter.set_function(lorentz=2) # will fit two lorentzians 85 90 """ 86 91 #default poly order 0 … … 102 107 self.components = [ 3 for i in range(n) ] 103 108 self.uselinear = False 109 elif kwargs.has_key('lorentz'): 110 n = kwargs.get('lorentz') 111 self.fitfunc = 'lorentz' 112 self.fitfuncs = [ 'lorentz' for i in range(n) ] 113 self.components = [ 3 for i in range(n) ] 114 self.uselinear = False 104 115 else: 105 116 msg = "Invalid function type." 106 117 if rcParams['verbose']: 107 print msg 118 #print msg 119 asaplog.push(msg) 120 print_log('ERROR') 108 121 return 109 122 else: … … 114 127 return 115 128 116 @print_log_dec129 #@print_log_dec 117 130 def fit(self, row=0, estimate=False): 118 131 """ … … 135 148 msg = "Fitter not yet initialised. Please set data & fit function" 136 149 if rcParams['verbose']: 137 print msg 150 #print msg 151 asaplog.push(msg) 152 print_log('ERROR') 138 153 return 139 154 else: … … 145 160 self.y = self.data._getspectrum(row) 146 161 self.mask = mask_and(self.mask, self.data._getmask(row)) 147 from asap import asaplog148 162 asaplog.push("Fitting:") 149 163 i = row … … 155 169 asaplog.push(out,False) 156 170 self.fitter.setdata(self.x, self.y, self.mask) 157 if self.fitfunc == 'gauss' :171 if self.fitfunc == 'gauss' or self.fitfunc == 'lorentz': 158 172 ps = self.fitter.getparameters() 159 173 if len(ps) == 0 or estimate: … … 171 185 except RuntimeError, msg: 172 186 if rcParams['verbose']: 173 print msg 187 #print msg 188 print_log() 189 asaplog.push(str(msg)) 190 print_log('ERROR') 174 191 else: 175 192 raise 176 193 self._fittedrow = row 177 194 self.fitted = True 195 print_log() 178 196 return 179 197 … … 204 222 self.data._addfit(fit,self._fittedrow) 205 223 206 @print_log_dec224 #@print_log_dec 207 225 def set_parameters(self,*args,**kwargs): 208 226 """ … … 228 246 msg = "Please specify a fitting function first." 229 247 if rcParams['verbose']: 230 print msg 248 #print msg 249 asaplog.push(msg) 250 print_log('ERROR') 231 251 return 232 252 else: 233 253 raise RuntimeError(msg) 234 if self.fitfunc == "gauss"and component is not None:254 if (self.fitfunc == "gauss" or self.fitfunc == 'lorentz') and component is not None: 235 255 if not self.fitted and sum(self.fitter.getparameters()) == 0: 236 256 pars = _n_bools(len(self.components)*3, False) … … 247 267 if fixed is not None: 248 268 self.fitter.setfixedparameters(fixed) 269 print_log() 249 270 return 250 271 … … 269 290 msg = "Function only operates on Gaussian components." 270 291 if rcParams['verbose']: 271 print msg 292 #print msg 293 asaplog.push(msg) 294 print_log('ERROR') 272 295 return 273 296 else: … … 280 303 msg = "Please select a valid component." 281 304 if rcParams['verbose']: 282 print msg 305 #print msg 306 asaplog.push(msg) 307 print_log('ERROR') 283 308 return 284 309 else: 285 310 raise ValueError(msg) 286 311 312 def set_lorentz_parameters(self, peak, centre, fwhm, 313 peakfixed=0, centrefixed=0, 314 fwhmfixed=0, 315 component=0): 316 """ 317 Set the Parameters of a 'Lorentzian' component, set with set_function. 318 Parameters: 319 peak, centre, fwhm: The gaussian parameters 320 peakfixed, 321 centrefixed, 322 fwhmfixed: Optional parameters to indicate if 323 the paramters should be held fixed during 324 the fitting process. The default is to keep 325 all parameters flexible. 326 component: The number of the component (Default is the 327 component 0) 328 """ 329 if self.fitfunc != "lorentz": 330 msg = "Function only operates on Lorentzian components." 331 if rcParams['verbose']: 332 #print msg 333 asaplog.push(msg) 334 print_log('ERROR') 335 return 336 else: 337 raise ValueError(msg) 338 if 0 <= component < len(self.components): 339 d = {'params':[peak, centre, fwhm], 340 'fixed':[peakfixed, centrefixed, fwhmfixed]} 341 self.set_parameters(d, component) 342 else: 343 msg = "Please select a valid component." 344 if rcParams['verbose']: 345 #print msg 346 asaplog.push(msg) 347 print_log('ERROR') 348 return 349 else: 350 raise ValueError(msg) 351 287 352 def get_area(self, component=None): 288 353 """ 289 Return the area under the fitted gaussian component.290 Parameters: 291 component: the gaussian component selection,354 Return the area under the fitted gaussian/lorentzian component. 355 Parameters: 356 component: the gaussian/lorentzian component selection, 292 357 default (None) is the sum of all components 293 358 Note: 294 This will only work for gaussian fits.359 This will only work for gaussian/lorentzian fits. 295 360 """ 296 361 if not self.fitted: return 297 if self.fitfunc == "gauss" :362 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 298 363 pars = list(self.fitter.getparameters()) 299 364 from math import log,pi,sqrt 300 fac = sqrt(pi/log(16.0)) 365 if self.fitfunc == "gauss": 366 fac = sqrt(pi/log(16.0)) 367 elif self.fitfunc == "lorentz": 368 fac = pi/2.0 301 369 areas = [] 302 370 for i in range(len(self.components)): … … 321 389 msg = "Not yet fitted." 322 390 if rcParams['verbose']: 323 print msg 391 #print msg 392 asaplog.push(msg) 393 print_log('ERROR') 324 394 return 325 395 else: … … 328 398 cerrs = errs 329 399 if component is not None: 330 if self.fitfunc == "gauss" :400 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 331 401 i = 3*component 332 402 if i < len(errs): … … 344 414 msg = "Not yet fitted." 345 415 if rcParams['verbose']: 346 print msg 416 #print msg 417 asaplog.push(msg) 418 print_log('ERROR') 347 419 return 348 420 else: … … 353 425 area = [] 354 426 if component is not None: 355 if self.fitfunc == "gauss" :427 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 356 428 i = 3*component 357 429 cpars = pars[i:i+3] … … 368 440 cfixed = fixed 369 441 cerrs = errs 370 if self.fitfunc == "gauss" :442 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 371 443 for c in range(len(self.components)): 372 444 a = self.get_area(c) … … 374 446 fpars = self._format_pars(cpars, cfixed, errors and cerrs, area) 375 447 if rcParams['verbose']: 376 print fpars 448 #print fpars 449 asaplog.push(fpars) 450 print_log() 377 451 return {'params':cpars, 'fixed':cfixed, 'formatted': fpars, 378 452 'errors':cerrs} … … 391 465 c+=1 392 466 out = out[:-1] # remove trailing ',' 393 elif self.fitfunc == 'gauss' :467 elif self.fitfunc == 'gauss' or self.fitfunc == 'lorentz': 394 468 i = 0 395 469 c = 0 … … 415 489 fixed = self.fitter.getfixedparameters() 416 490 if rcParams['verbose']: 417 print self._format_pars(pars,fixed,None) 491 #print self._format_pars(pars,fixed,None) 492 asaplog.push(self._format_pars(pars,fixed,None)) 493 print_log() 418 494 return pars 419 495 … … 425 501 msg = "Not yet fitted." 426 502 if rcParams['verbose']: 427 print msg 503 #print msg 504 asaplog.push(msg) 505 print_log('ERROR') 428 506 return 429 507 else: … … 438 516 msg = "Not yet fitted." 439 517 if rcParams['verbose']: 440 print msg 518 #print msg 519 asaplog.push(msg) 520 print_log('ERROR') 441 521 return 442 522 else: … … 444 524 ch2 = self.fitter.getchi2() 445 525 if rcParams['verbose']: 446 print 'Chi^2 = %3.3f' % (ch2) 526 #print 'Chi^2 = %3.3f' % (ch2) 527 asaplog.push( 'Chi^2 = %3.3f' % (ch2) ) 528 print_log() 447 529 return ch2 448 530 … … 454 536 msg = "Not yet fitted." 455 537 if rcParams['verbose']: 456 print msg 538 #print msg 539 asaplog.push(msg) 540 print_log('ERROR') 457 541 return 458 542 else: … … 460 544 return self.fitter.getfit() 461 545 462 @print_log_dec546 #@print_log_dec 463 547 def commit(self): 464 548 """ … … 468 552 msg = "Not yet fitted." 469 553 if rcParams['verbose']: 470 print msg 554 #print msg 555 asaplog.push(msg) 556 print_log('ERROR') 471 557 return 472 558 else: … … 476 562 msg = "Not a scantable" 477 563 if rcParams['verbose']: 478 print msg 564 #print msg 565 asaplog.push(msg) 566 print_log('ERROR') 479 567 return 480 568 else: … … 482 570 scan = self.data.copy() 483 571 scan._setspectrum(self.fitter.getresidual()) 572 print_log() 484 573 return scan 485 574 486 @print_log_dec575 #@print_log_dec 487 576 def plot(self, residual=False, components=None, plotparms=False, 488 577 filename=None): … … 525 614 526 615 colours = ["#777777","#dddddd","red","orange","purple","green","magenta", "cyan"] 616 nomask=True 617 for i in range(len(m)): 618 nomask = nomask and m[i] 619 label0='Masked Region' 620 label1='Spectrum' 621 if ( nomask ): 622 label0=label1 623 else: 624 y = ma.masked_array( self.y, mask = m ) 625 self._p.palette(1,colours) 626 self._p.set_line( label = label1 ) 627 self._p.plot( self.x, y ) 527 628 self._p.palette(0,colours) 528 self._p.set_line(label= 'Spectrum')629 self._p.set_line(label=label0) 529 630 y = ma.masked_array(self.y,mask=logical_not(m)) 530 631 self._p.plot(self.x, y) 531 632 if residual: 532 self._p.palette( 1)633 self._p.palette(7) 533 634 self._p.set_line(label='Residual') 534 635 y = ma.masked_array(self.get_residual(), … … 571 672 if (not rcParams['plotter.gui']): 572 673 self._p.save(filename) 573 574 @print_log_dec 674 print_log() 675 676 #@print_log_dec 575 677 def auto_fit(self, insitu=None, plot=False): 576 678 """ … … 583 685 msg = "Data is not a scantable" 584 686 if rcParams['verbose']: 585 print msg 687 #print msg 688 asaplog.push(msg) 689 print_log('ERROR') 586 690 return 587 691 else: … … 593 697 scan = self.data 594 698 rows = xrange(scan.nrow()) 595 from asap import asaplog 699 # Save parameters of baseline fits as a class attribute. 700 # NOTICE: This does not reflect changes in scantable! 701 if len(rows) > 0: self.blpars=[] 596 702 asaplog.push("Fitting:") 597 703 for r in rows: … … 608 714 self.fit() 609 715 x = self.get_parameters() 716 fpar = self.get_parameters() 610 717 if plot: 611 718 self.plot(residual=True) 612 719 x = raw_input("Accept fit ([y]/n): ") 613 720 if x.upper() == 'N': 721 self.blpars.append(None) 614 722 continue 615 723 scan._setspectrum(self.fitter.getresidual(), r) 724 self.blpars.append(fpar) 616 725 if plot: 617 726 self._p.unmap() 618 727 self._p = None 728 print_log() 619 729 return scan
Note:
See TracChangeset
for help on using the changeset viewer.