Changeset 2047 for trunk/python
- Timestamp:
- 03/15/11 18:31:04 (14 years ago)
- Location:
- trunk/python
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/python/asapfitter.py
r1938 r2047 73 73 Set the function to be fit. 74 74 Parameters: 75 poly: use a polynomial of the order given with nonlinear least squares fit 76 lpoly: use polynomial of the order given with linear least squares fit 77 gauss: fit the number of gaussian specified 78 lorentz: fit the number of lorentzian specified 75 poly: use a polynomial of the order given with nonlinear least squares fit 76 lpoly: use polynomial of the order given with linear least squares fit 77 gauss: fit the number of gaussian specified 78 lorentz: fit the number of lorentzian specified 79 sinusoid: fit the number of sinusoid specified 79 80 Example: 80 81 fitter.set_function(poly=3) # will fit a 3rd order polynomial via nonlinear method … … 82 83 fitter.set_function(gauss=2) # will fit two gaussians 83 84 fitter.set_function(lorentz=2) # will fit two lorentzians 85 fitter.set_function(sinusoid=3) # will fit three sinusoids 84 86 """ 85 87 #default poly order 0 … … 109 111 self.components = [ 3 for i in range(n) ] 110 112 self.uselinear = False 113 elif kwargs.has_key('sinusoid'): 114 n = kwargs.get('sinusoid') 115 self.fitfunc = 'sinusoid' 116 self.fitfuncs = [ 'sinusoid' for i in range(n) ] 117 self.components = [ 3 for i in range(n) ] 118 self.uselinear = False 111 119 else: 112 120 msg = "Invalid function type." … … 204 212 fixed: a vector of which parameters are to be held fixed 205 213 (default is none) 206 component: in case of multiple gaussians/lorentzians ,207 the index of the component214 component: in case of multiple gaussians/lorentzians/sinusoidals, 215 the index of the target component 208 216 """ 209 217 component = None … … 220 228 msg = "Please specify a fitting function first." 221 229 raise RuntimeError(msg) 222 if (self.fitfunc == "gauss" or self.fitfunc == 'lorentz') and component is not None:230 if (self.fitfunc == "gauss" or self.fitfunc == "lorentz" or self.fitfunc == "sinusoid") and component is not None: 223 231 if not self.fitted and sum(self.fitter.getparameters()) == 0: 224 232 pars = _n_bools(len(self.components)*3, False) 225 fxd = _n_bools(len(pars), False)233 fxd = _n_bools(len(pars), False) 226 234 else: 227 235 pars = list(self.fitter.getparameters()) 228 fxd = list(self.fitter.getfixedparameters())236 fxd = list(self.fitter.getfixedparameters()) 229 237 i = 3*component 230 238 pars[i:i+3] = params 231 fxd[i:i+3] = fixed239 fxd[i:i+3] = fixed 232 240 params = pars 233 fixed = fxd241 fixed = fxd 234 242 self.fitter.setparameters(params) 235 243 if fixed is not None: … … 290 298 d = {'params':[peak, centre, fwhm], 291 299 'fixed':[peakfixed, centrefixed, fwhmfixed]} 300 self.set_parameters(d, component) 301 else: 302 msg = "Please select a valid component." 303 raise ValueError(msg) 304 305 @asaplog_post_dec 306 def set_sinusoid_parameters(self, ampl, period, x0, 307 amplfixed=0, periodfixed=0, 308 x0fixed=0, 309 component=0): 310 """ 311 Set the Parameters of a 'Sinusoidal' component, set with set_function. 312 Parameters: 313 ampl, period, x0: The sinusoidal parameters 314 amplfixed, 315 periodfixed, 316 x0fixed: Optional parameters to indicate if 317 the paramters should be held fixed during 318 the fitting process. The default is to keep 319 all parameters flexible. 320 component: The number of the component (Default is the 321 component 0) 322 """ 323 if self.fitfunc != "sinusoid": 324 msg = "Function only operates on Sinusoidal components." 325 raise ValueError(msg) 326 if 0 <= component < len(self.components): 327 d = {'params':[ampl, period, x0], 328 'fixed': [amplfixed, periodfixed, x0fixed]} 292 329 self.set_parameters(d, component) 293 330 else: … … 338 375 cerrs = errs 339 376 if component is not None: 340 if self.fitfunc == "gauss" or self.fitfunc == "lorentz" :377 if self.fitfunc == "gauss" or self.fitfunc == "lorentz" or self.fitfunc == "sinusoid": 341 378 i = 3*component 342 379 if i < len(errs): … … 361 398 area = [] 362 399 if component is not None: 363 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 400 if self.fitfunc == "poly" or self.fitfunc == "lpoly": 401 cpars = pars 402 cfixed = fixed 403 cerrs = errs 404 else: 364 405 i = 3*component 365 406 cpars = pars[i:i+3] 366 407 cfixed = fixed[i:i+3] 367 408 cerrs = errs[i:i+3] 368 a = self.get_area(component) 369 area = [a for i in range(3)] 370 else: 371 cpars = pars 372 cfixed = fixed 373 cerrs = errs 409 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 410 a = self.get_area(component) 411 area = [a for i in range(3)] 374 412 else: 375 413 cpars = pars … … 378 416 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 379 417 for c in range(len(self.components)): 380 a = self.get_area(c)381 area += [a for i in range(3)]418 a = self.get_area(c) 419 area += [a for i in range(3)] 382 420 fpars = self._format_pars(cpars, cfixed, errors and cerrs, area) 383 421 asaplog.push(fpars) … … 387 425 def _format_pars(self, pars, fixed, errors, area): 388 426 out = '' 389 if self.fitfunc == 'poly':427 if self.fitfunc == "poly" or self.fitfunc == "lpoly": 390 428 c = 0 391 429 for i in range(len(pars)): 392 430 fix = "" 393 431 if len(fixed) and fixed[i]: fix = "(fixed)" 394 if errors : 395 out += ' p%d%s= %3.6f (%1.6f),' % (c,fix,pars[i], errors[i]) 396 else: 397 out += ' p%d%s= %3.6f,' % (c,fix,pars[i]) 432 out += " p%d%s= %3.6f" % (c, fix, pars[i]) 433 if errors : out += " (%1.6f)" % errors[i] 434 out += "," 398 435 c+=1 399 436 out = out[:-1] # remove trailing ',' 400 el if self.fitfunc == 'gauss' or self.fitfunc == 'lorentz':437 else: 401 438 i = 0 402 439 c = 0 403 aunit = '' 404 ounit = '' 440 if self.fitfunc == "gauss" or self.fitfunc == "lorentz": 441 pnam = ["peak", "centre", "FWHM"] 442 elif self.fitfunc == "sinusoid": 443 pnam = ["amplitude", "period", "x0"] 444 aunit = "" 445 ounit = "" 405 446 if self.data: 406 447 aunit = self.data.get_unit() 407 448 ounit = self.data.get_fluxunit() 408 449 while i < len(pars): 409 if len(area): 410 out += ' %2d: peak = %3.3f %s , centre = %3.3f %s, FWHM = %3.3f %s\n area = %3.3f %s %s\n' % (c,pars[i],ounit,pars[i+1],aunit,pars[i+2],aunit, area[i],ounit,aunit) 411 else: 412 out += ' %2d: peak = %3.3f %s , centre = %3.3f %s, FWHM = %3.3f %s\n' % (c,pars[i],ounit,pars[i+1],aunit,pars[i+2],aunit,ounit,aunit) 450 fix0 = fix1 = fix2 = "" 451 if i < len(fixed)-2: 452 if fixed[i]: fix0 = "(fixed)" 453 if fixed[i+1]: fix1 = "(fixed)" 454 if fixed[i+2]: fix2 = "(fixed)" 455 out += " %2d: " % c 456 out += "%s%s = %3.3f %s, " % (pnam[0], fix0, pars[i], ounit) 457 out += "%s%s = %3.3f %s, " % (pnam[1], fix1, pars[i+1], aunit) 458 out += "%s%s = %3.3f %s\n" % (pnam[2], fix2, pars[i+2], aunit) 459 if len(area): out += " area = %3.3f %s %s\n" % (area[i], ounit, aunit) 413 460 c+=1 414 461 i+=3 -
trunk/python/scantable.py
r2029 r2047 2070 2070 2071 2071 @asaplog_post_dec 2072 def sinusoid_baseline(self, insitu=None, mask=None, minnwave=None, maxnwave=None, 2073 clipthresh=None, clipniter=None, plot=None, outlog=None, blfile=None): 2074 """\ 2075 Return a scan which has been baselined (all rows) by cubic spline function (piecewise cubic polynomial). 2076 Parameters: 2077 insitu: If False a new scantable is returned. 2078 Otherwise, the scaling is done in-situ 2079 The default is taken from .asaprc (False) 2080 mask: An optional mask 2081 minnwave: Minimum wave number in spectral window (default is 0) 2082 maxnwave: Maximum wave number in spectral window (default is 3) 2083 clipthresh: Clipping threshold. (default is 3.0, unit: sigma) 2084 clipniter: maximum number of iteration of 'clipthresh'-sigma clipping (default is 1) 2085 plot: *** CURRENTLY UNAVAILABLE, ALWAYS FALSE *** 2086 plot the fit and the residual. In this each 2087 indivual fit has to be approved, by typing 'y' 2088 or 'n' 2089 outlog: Output the coefficients of the best-fit 2090 function to logger (default is False) 2091 blfile: Name of a text file in which the best-fit 2092 parameter values to be written 2093 (default is "": no file/logger output) 2094 2095 Example: 2096 # return a scan baselined by a combination of sinusoidal curves having 2097 # wave numbers in spectral window from 1 to 10, 2098 # also with 3-sigma clipping, iteration up to 4 times 2099 bscan = scan.sinusoid_baseline(maxnwave=10,clipthresh=3.0,clipniter=4) 2100 """ 2101 2102 varlist = vars() 2103 2104 if insitu is None: insitu = rcParams["insitu"] 2105 if insitu: 2106 workscan = self 2107 else: 2108 workscan = self.copy() 2109 2110 nchan = workscan.nchan() 2111 2112 if mask is None: mask = [True for i in xrange(nchan)] 2113 if minnwave is None: minnwave = 0 2114 if maxnwave is None: maxnwave = 3 2115 if clipthresh is None: clipthresh = 3.0 2116 if clipniter is None: clipniter = 1 2117 if plot is None: plot = False 2118 if outlog is None: outlog = False 2119 if blfile is None: blfile = "" 2120 2121 outblfile = (blfile != "") and os.path.exists(os.path.expanduser(os.path.expandvars(blfile))) 2122 2123 try: 2124 #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method. 2125 workscan._sinusoid_baseline(mask, minnwave, maxnwave, clipthresh, clipniter, outlog, blfile) 2126 2127 workscan._add_history("sinusoid_baseline", varlist) 2128 2129 if insitu: 2130 self._assign(workscan) 2131 else: 2132 return workscan 2133 2134 except RuntimeError, e: 2135 msg = "The fit failed, possibly because it didn't converge." 2136 if rcParams["verbose"]: 2137 asaplog.push(str(e)) 2138 asaplog.push(str(msg)) 2139 return 2140 else: 2141 raise RuntimeError(str(e)+'\n'+msg) 2142 2143 2144 def auto_sinusoid_baseline(self, insitu=None, mask=None, minnwave=None, maxnwave=None, 2145 clipthresh=None, clipniter=None, edge=None, threshold=None, 2146 chan_avg_limit=None, plot=None, outlog=None, blfile=None): 2147 """\ 2148 Return a scan which has been baselined (all rows) by cubic spline 2149 function (piecewise cubic polynomial). 2150 Spectral lines are detected first using linefinder and masked out 2151 to avoid them affecting the baseline solution. 2152 2153 Parameters: 2154 insitu: if False a new scantable is returned. 2155 Otherwise, the scaling is done in-situ 2156 The default is taken from .asaprc (False) 2157 mask: an optional mask retreived from scantable 2158 minnwave: Minimum wave number in spectral window (default is 0) 2159 maxnwave: Maximum wave number in spectral window (default is 3) 2160 clipthresh: Clipping threshold. (default is 3.0, unit: sigma) 2161 clipniter: maximum number of iteration of 'clipthresh'-sigma clipping (default is 1) 2162 edge: an optional number of channel to drop at 2163 the edge of spectrum. If only one value is 2164 specified, the same number will be dropped 2165 from both sides of the spectrum. Default 2166 is to keep all channels. Nested tuples 2167 represent individual edge selection for 2168 different IFs (a number of spectral channels 2169 can be different) 2170 threshold: the threshold used by line finder. It is 2171 better to keep it large as only strong lines 2172 affect the baseline solution. 2173 chan_avg_limit: 2174 a maximum number of consequtive spectral 2175 channels to average during the search of 2176 weak and broad lines. The default is no 2177 averaging (and no search for weak lines). 2178 If such lines can affect the fitted baseline 2179 (e.g. a high order polynomial is fitted), 2180 increase this parameter (usually values up 2181 to 8 are reasonable). Most users of this 2182 method should find the default value sufficient. 2183 plot: *** CURRENTLY UNAVAILABLE, ALWAYS FALSE *** 2184 plot the fit and the residual. In this each 2185 indivual fit has to be approved, by typing 'y' 2186 or 'n' 2187 outlog: Output the coefficients of the best-fit 2188 function to logger (default is False) 2189 blfile: Name of a text file in which the best-fit 2190 parameter values to be written 2191 (default is "": no file/logger output) 2192 2193 Example: 2194 bscan = scan.auto_sinusoid_baseline(maxnwave=10, insitu=False) 2195 """ 2196 2197 varlist = vars() 2198 2199 if insitu is None: insitu = rcParams['insitu'] 2200 if insitu: 2201 workscan = self 2202 else: 2203 workscan = self.copy() 2204 2205 nchan = workscan.nchan() 2206 2207 if mask is None: mask = [True for i in xrange(nchan)] 2208 if minnwave is None: minnwave = 0 2209 if maxnwave is None: maxnwave = 3 2210 if clipthresh is None: clipthresh = 3.0 2211 if clipniter is None: clipniter = 1 2212 if edge is None: edge = (0, 0) 2213 if threshold is None: threshold = 3 2214 if chan_avg_limit is None: chan_avg_limit = 1 2215 if plot is None: plot = False 2216 if outlog is None: outlog = False 2217 if blfile is None: blfile = "" 2218 2219 outblfile = (blfile != "") and os.path.exists(os.path.expanduser(os.path.expandvars(blfile))) 2220 2221 from asap.asaplinefind import linefinder 2222 from asap import _is_sequence_or_number as _is_valid 2223 2224 if not (isinstance(edge, list) or isinstance(edge, tuple)): edge = [ edge ] 2225 individualedge = False; 2226 if len(edge) > 1: individualedge = isinstance(edge[0], list) or isinstance(edge[0], tuple) 2227 2228 if individualedge: 2229 for edgepar in edge: 2230 if not _is_valid(edgepar, int): 2231 raise ValueError, "Each element of the 'edge' tuple has \ 2232 to be a pair of integers or an integer." 2233 else: 2234 if not _is_valid(edge, int): 2235 raise ValueError, "Parameter 'edge' has to be an integer or a \ 2236 pair of integers specified as a tuple. \ 2237 Nested tuples are allowed \ 2238 to make individual selection for different IFs." 2239 2240 if len(edge) > 1: 2241 curedge = edge 2242 else: 2243 curedge = edge + edge 2244 2245 try: 2246 #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method. 2247 if individualedge: 2248 curedge = [] 2249 for i in xrange(len(edge)): 2250 curedge += edge[i] 2251 2252 workscan._auto_sinusoid_baseline(mask, minnwave, maxnwave, clipthresh, clipniter, curedge, threshold, chan_avg_limit, outlog, blfile) 2253 2254 workscan._add_history("auto_sinusoid_baseline", varlist) 2255 2256 if insitu: 2257 self._assign(workscan) 2258 else: 2259 return workscan 2260 2261 except RuntimeError, e: 2262 msg = "The fit failed, possibly because it didn't converge." 2263 if rcParams["verbose"]: 2264 asaplog.push(str(e)) 2265 asaplog.push(str(msg)) 2266 return 2267 else: 2268 raise RuntimeError(str(e)+'\n'+msg) 2269 2270 2271 @asaplog_post_dec 2072 2272 def cspline_baseline(self, insitu=None, mask=None, npiece=None, clipthresh=None, clipniter=None, plot=None, outlog=None, blfile=None): 2073 2273 """\
Note:
See TracChangeset
for help on using the changeset viewer.