Changeset 2047
- Timestamp:
- 03/15/11 18:31:04 (14 years ago)
- Location:
- trunk
- Files:
-
- 7 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 """\ -
trunk/src/STFitter.cpp
r1932 r2047 39 39 #include <scimath/Functionals/Gaussian1D.h> 40 40 #include "Lorentzian1D.h" 41 #include <scimath/Functionals/Sinusoid1D.h> 41 42 #include <scimath/Functionals/Polynomial.h> 42 43 #include <scimath/Mathematics/AutoDiff.h> … … 149 150 funccomponents_.push_back(3); 150 151 } 151 } else if (expr == "poly") {152 funcs_.resize(1);153 funcnames_.clear();154 funccomponents_.clear();155 funcs_[0] = new Polynomial<Float>(ncomp);156 funcnames_.push_back(expr);157 funccomponents_.push_back(ncomp);158 152 } else if (expr == "lorentz") { 159 153 if (ncomp < 1) throw (AipsError("Need at least one lorentzian to fit.")); … … 166 160 funccomponents_.push_back(3); 167 161 } 162 } else if (expr == "sinusoid") { 163 if (ncomp < 1) throw (AipsError("Need at least one sinusoid to fit.")); 164 funcs_.resize(ncomp); 165 funcnames_.clear(); 166 funccomponents_.clear(); 167 for (Int k=0; k<ncomp; ++k) { 168 funcs_[k] = new Sinusoid1D<Float>(); 169 funcnames_.push_back(expr); 170 funccomponents_.push_back(3); 171 } 172 } else if (expr == "poly") { 173 funcs_.resize(1); 174 funcnames_.clear(); 175 funccomponents_.clear(); 176 funcs_[0] = new Polynomial<Float>(ncomp); 177 funcnames_.push_back(expr); 178 funccomponents_.push_back(ncomp); 168 179 } else { 169 //cerr << " compiled functions not yet implemented" << endl;170 180 LogIO os( LogOrigin( "Fitter", "setExpression()", WHERE ) ) ; 171 181 os << LogIO::WARN << " compiled functions not yet implemented" << LogIO::POST; … … 244 254 } 245 255 } 256 } else if (dynamic_cast<Lorentzian1D<Float>* >(funcs_[0]) != 0) { 257 uInt count = 0; 258 for (uInt j=0; j < funcs_.nelements(); ++j) { 259 for (uInt i=0; i < funcs_[j]->nparameters(); ++i) { 260 (funcs_[j]->parameters())[i] = tmppar[count]; 261 parameters_[count] = tmppar[count]; 262 ++count; 263 } 264 } 265 } else if (dynamic_cast<Sinusoid1D<Float>* >(funcs_[0]) != 0) { 266 uInt count = 0; 267 for (uInt j=0; j < funcs_.nelements(); ++j) { 268 for (uInt i=0; i < funcs_[j]->nparameters(); ++i) { 269 (funcs_[j]->parameters())[i] = tmppar[count]; 270 parameters_[count] = tmppar[count]; 271 ++count; 272 } 273 } 246 274 } else if (dynamic_cast<Polynomial<Float>* >(funcs_[0]) != 0) { 247 275 for (uInt i=0; i < funcs_[0]->nparameters(); ++i) { 248 276 parameters_[i] = tmppar[i]; 249 277 (funcs_[0]->parameters())[i] = tmppar[i]; 250 }251 } else if (dynamic_cast<Lorentzian1D<Float>* >(funcs_[0]) != 0) {252 uInt count = 0;253 for (uInt j=0; j < funcs_.nelements(); ++j) {254 for (uInt i=0; i < funcs_[j]->nparameters(); ++i) {255 (funcs_[j]->parameters())[i] = tmppar[count];256 parameters_[count] = tmppar[count];257 ++count;258 }259 278 } 260 279 } … … 286 305 } 287 306 } 307 } else if (dynamic_cast<Lorentzian1D<Float>* >(funcs_[0]) != 0) { 308 uInt count = 0; 309 for (uInt j=0; j < funcs_.nelements(); ++j) { 310 for (uInt i=0; i < funcs_[j]->nparameters(); ++i) { 311 funcs_[j]->mask(i) = !fixed[count]; 312 fixedpar_[count] = fixed[count]; 313 ++count; 314 } 315 } 316 } else if (dynamic_cast<Sinusoid1D<Float>* >(funcs_[0]) != 0) { 317 uInt count = 0; 318 for (uInt j=0; j < funcs_.nelements(); ++j) { 319 for (uInt i=0; i < funcs_[j]->nparameters(); ++i) { 320 funcs_[j]->mask(i) = !fixed[count]; 321 fixedpar_[count] = fixed[count]; 322 ++count; 323 } 324 } 288 325 } else if (dynamic_cast<Polynomial<Float>* >(funcs_[0]) != 0) { 289 326 for (uInt i=0; i < funcs_[0]->nparameters(); ++i) { 290 327 fixedpar_[i] = fixed[i]; 291 328 funcs_[0]->mask(i) = !fixed[i]; 292 }293 } else if (dynamic_cast<Lorentzian1D<Float>* >(funcs_[0]) != 0) {294 uInt count = 0;295 for (uInt j=0; j < funcs_.nelements(); ++j) {296 for (uInt i=0; i < funcs_[j]->nparameters(); ++i) {297 funcs_[j]->mask(i) = !fixed[count];298 fixedpar_[count] = fixed[count];299 ++count;300 }301 329 } 302 330 } -
trunk/src/Scantable.cpp
r2036 r2047 882 882 uInt row = uInt(whichrow); 883 883 stpol->setSpectra(getPolMatrix(row)); 884 Float fang,fhand ,parang;884 Float fang,fhand; 885 885 fang = focusTable_.getTotalAngle(mfocusidCol_(row)); 886 886 fhand = focusTable_.getFeedHand(mfocusidCol_(row)); … … 1749 1749 } 1750 1750 1751 bool Scantable::getFlagtraFast( int whichrow)1751 bool Scantable::getFlagtraFast(uInt whichrow) 1752 1752 { 1753 1753 uChar flag; 1754 1754 Vector<uChar> flags; 1755 flagsCol_.get( uInt(whichrow), flags);1755 flagsCol_.get(whichrow, flags); 1756 1756 flag = flags[0]; 1757 for ( int i = 1; i < flags.size(); ++i) {1757 for (uInt i = 1; i < flags.size(); ++i) { 1758 1758 flag &= flags[i]; 1759 1759 } … … 1761 1761 } 1762 1762 1763 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, bool outLogger, const std::string& blfile) { 1763 void Scantable::polyBaseline(const std::vector<bool>& mask, int order, bool outLogger, const std::string& blfile) 1764 { 1764 1765 ofstream ofs; 1765 1766 String coordInfo; 1766 bool hasSameNchan; 1767 int firstIF; 1767 bool hasSameNchan = true; 1768 1768 bool outTextFile = false; 1769 1769 … … 1777 1777 if (coordInfo == "") coordInfo = "channel"; 1778 1778 hasSameNchan = hasSameNchanOverIFs(); 1779 firstIF = getIF(0); 1780 } 1781 1782 //Fitter fitter = Fitter(); 1783 //fitter.setExpression("cspline", nPiece, thresClip, nIterClip); 1779 } 1780 1781 Fitter fitter = Fitter(); 1782 fitter.setExpression("poly", order); 1784 1783 1785 1784 int nRow = nrow(); … … 1787 1786 1788 1787 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 1789 1790 1788 chanMask = getCompositeChanMask(whichrow, mask); 1791 //fitBaseline(chanMask, whichrow, fitter); 1792 //setSpectrum(fitter.getResidual(), whichrow); 1793 std::vector<int> pieceRanges; 1794 std::vector<float> params; 1795 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, pieceRanges, params, nPiece, thresClip, nIterClip); 1796 setSpectrum(res, whichrow); 1797 1798 if (outLogger || outTextFile) { 1799 std::vector<bool> fixed; 1800 fixed.clear(); 1801 float rms = getRms(chanMask, whichrow); 1802 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 1803 1804 if (outLogger) { 1805 LogIO ols(LogOrigin("Scantable", "cubicSplineBaseline()", WHERE)); 1806 ols << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 1807 } 1808 if (outTextFile) { 1809 ofs << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, true) << flush; 1810 } 1811 } 1812 1789 fitBaseline(chanMask, whichrow, fitter); 1790 setSpectrum(fitter.getResidual(), whichrow); 1791 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "polyBaseline()", fitter); 1813 1792 } 1814 1793 … … 1816 1795 } 1817 1796 1818 1819 void Scantable::autoCubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool outLogger, const std::string& blfile) 1797 void Scantable::autoPolyBaseline(const std::vector<bool>& mask, int order, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool outLogger, const std::string& blfile) 1820 1798 { 1821 1799 ofstream ofs; 1822 1800 String coordInfo; 1823 bool hasSameNchan; 1824 int firstIF; 1801 bool hasSameNchan = true; 1825 1802 bool outTextFile = false; 1826 1803 … … 1834 1811 if (coordInfo == "") coordInfo = "channel"; 1835 1812 hasSameNchan = hasSameNchanOverIFs(); 1836 firstIF = getIF(0); 1837 } 1838 1839 //Fitter fitter = Fitter(); 1840 //fitter.setExpression("cspline", nPiece, thresClip, nIterClip); 1813 } 1814 1815 Fitter fitter = Fitter(); 1816 fitter.setExpression("poly", order); 1841 1817 1842 1818 int nRow = nrow(); … … 1871 1847 //------------------------------------------------------- 1872 1848 1873 1874 //fitBaseline(chanMask, whichrow, fitter); 1849 fitBaseline(chanMask, whichrow, fitter); 1850 setSpectrum(fitter.getResidual(), whichrow); 1851 1852 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoPolyBaseline()", fitter); 1853 } 1854 1855 if (outTextFile) ofs.close(); 1856 } 1857 1858 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, bool outLogger, const std::string& blfile) { 1859 ofstream ofs; 1860 String coordInfo; 1861 bool hasSameNchan = true; 1862 bool outTextFile = false; 1863 1864 if (blfile != "") { 1865 ofs.open(blfile.c_str(), ios::out | ios::app); 1866 if (ofs) outTextFile = true; 1867 } 1868 1869 if (outLogger || outTextFile) { 1870 coordInfo = getCoordInfo()[0]; 1871 if (coordInfo == "") coordInfo = "channel"; 1872 hasSameNchan = hasSameNchanOverIFs(); 1873 } 1874 1875 //Fitter fitter = Fitter(); 1876 //fitter.setExpression("cspline", nPiece); 1877 1878 int nRow = nrow(); 1879 std::vector<bool> chanMask; 1880 1881 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 1882 chanMask = getCompositeChanMask(whichrow, mask); 1883 //fitBaseline(chanMask, whichrow, fitter, thresClip, nIterClip); 1875 1884 //setSpectrum(fitter.getResidual(), whichrow); 1876 1885 std::vector<int> pieceRanges; … … 1878 1887 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, pieceRanges, params, nPiece, thresClip, nIterClip); 1879 1888 setSpectrum(res, whichrow); 1880 1881 if (outLogger || outTextFile) { 1882 std::vector<bool> fixed; 1883 fixed.clear(); 1884 float rms = getRms(chanMask, whichrow); 1885 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 1886 1887 if (outLogger) { 1888 LogIO ols(LogOrigin("Scantable", "autoCubicSplineBaseline()", WHERE)); 1889 ols << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 1890 } 1891 if (outTextFile) { 1892 ofs << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, true) << flush; 1893 } 1894 } 1895 1889 // 1890 1891 std::vector<bool> fixed; 1892 fixed.clear(); 1893 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "cubicSplineBaseline()", pieceRanges, params, fixed); 1896 1894 } 1897 1895 … … 1899 1897 } 1900 1898 1899 void Scantable::autoCubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool outLogger, const std::string& blfile) 1900 { 1901 ofstream ofs; 1902 String coordInfo; 1903 bool hasSameNchan = true; 1904 bool outTextFile = false; 1905 1906 if (blfile != "") { 1907 ofs.open(blfile.c_str(), ios::out | ios::app); 1908 if (ofs) outTextFile = true; 1909 } 1910 1911 if (outLogger || outTextFile) { 1912 coordInfo = getCoordInfo()[0]; 1913 if (coordInfo == "") coordInfo = "channel"; 1914 hasSameNchan = hasSameNchanOverIFs(); 1915 } 1916 1917 //Fitter fitter = Fitter(); 1918 //fitter.setExpression("cspline", nPiece); 1919 1920 int nRow = nrow(); 1921 std::vector<bool> chanMask; 1922 int minEdgeSize = getIFNos().size()*2; 1923 STLineFinder lineFinder = STLineFinder(); 1924 lineFinder.setOptions(threshold, 3, chanAvgLimit); 1925 1926 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 1927 1928 //------------------------------------------------------- 1929 //chanMask = getCompositeChanMask(whichrow, mask, edge, minEdgeSize, lineFinder); 1930 //------------------------------------------------------- 1931 int edgeSize = edge.size(); 1932 std::vector<int> currentEdge; 1933 if (edgeSize >= 2) { 1934 int idx = 0; 1935 if (edgeSize > 2) { 1936 if (edgeSize < minEdgeSize) { 1937 throw(AipsError("Length of edge element info is less than that of IFs")); 1938 } 1939 idx = 2 * getIF(whichrow); 1940 } 1941 currentEdge.push_back(edge[idx]); 1942 currentEdge.push_back(edge[idx+1]); 1943 } else { 1944 throw(AipsError("Wrong length of edge element")); 1945 } 1946 lineFinder.setData(getSpectrum(whichrow)); 1947 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 1948 chanMask = lineFinder.getMask(); 1949 //------------------------------------------------------- 1950 1951 1952 //fitBaseline(chanMask, whichrow, fitter, thresClip, nIterClip); 1953 //setSpectrum(fitter.getResidual(), whichrow); 1954 std::vector<int> pieceRanges; 1955 std::vector<float> params; 1956 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, pieceRanges, params, nPiece, thresClip, nIterClip); 1957 setSpectrum(res, whichrow); 1958 // 1959 1960 std::vector<bool> fixed; 1961 fixed.clear(); 1962 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoCubicSplineBaseline()", pieceRanges, params, fixed); 1963 } 1964 1965 if (outTextFile) ofs.close(); 1966 } 1901 1967 1902 1968 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, const std::vector<bool>& mask, std::vector<int>& sectionRanges, std::vector<float>& params, int nPiece, float thresClip, int nIterClip) { … … 1921 1987 int nElement = (int)(floor(floor((double)(nData/nPiece))+0.5)); 1922 1988 1923 std::vector<double> sectionList0, sectionList1, sectionListR; 1924 sectionList0.push_back((double)x[0]); 1989 std::vector<int> sectionList0, sectionList1; 1990 std::vector<double> sectionListR; 1991 sectionList0.push_back(x[0]); 1925 1992 sectionRanges.clear(); 1926 1993 sectionRanges.push_back(x[0]); 1927 1994 for (int i = 1; i < nPiece; ++i) { 1928 double valX = (double)x[nElement*i];1995 int valX = x[nElement*i]; 1929 1996 sectionList0.push_back(valX); 1930 1997 sectionList1.push_back(valX); 1931 sectionListR.push_back(1.0/ valX);1932 1933 sectionRanges.push_back( x[nElement*i]-1);1934 sectionRanges.push_back( x[nElement*i]);1935 } 1936 sectionList1.push_back( (double)(x[x.size()-1]+1));1998 sectionListR.push_back(1.0/(double)valX); 1999 2000 sectionRanges.push_back(valX-1); 2001 sectionRanges.push_back(valX); 2002 } 2003 sectionList1.push_back(x[x.size()-1]+1); 1937 2004 sectionRanges.push_back(x[x.size()-1]); 1938 2005 … … 2111 2178 } 2112 2179 2113 void Scantable::fitBaseline(const std::vector<bool>& mask, int whichrow, Fitter& fitter) 2114 { 2115 std::vector<double> abcsd = getAbcissa(whichrow); 2116 std::vector<float> abcs; 2117 for (int i = 0; i < abcsd.size(); ++i) { 2118 abcs.push_back((float)abcsd[i]); 2119 } 2120 std::vector<float> spec = getSpectrum(whichrow); 2121 2122 fitter.setData(abcs, spec, mask); 2123 fitter.lfit(); 2124 } 2125 2126 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask) 2127 { 2128 std::vector<bool> chanMask = getMask(whichrow); 2129 int chanMaskSize = chanMask.size(); 2130 if (chanMaskSize != inMask.size()) { 2131 throw(AipsError("different mask sizes")); 2132 } 2133 for (int i = 0; i < chanMaskSize; ++i) { 2134 chanMask[i] = chanMask[i] && inMask[i]; 2135 } 2136 2137 return chanMask; 2138 } 2139 2140 /* 2141 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, const int minEdgeSize, STLineFinder& lineFinder) 2142 { 2143 int edgeSize = edge.size(); 2144 std::vector<int> currentEdge; 2145 if (edgeSize >= 2) { 2146 int idx = 0; 2147 if (edgeSize > 2) { 2148 if (edgeSize < minEdgeSize) { 2149 throw(AipsError("Length of edge element info is less than that of IFs")); 2150 } 2151 idx = 2 * getIF(whichrow); 2152 } 2153 currentEdge.push_back(edge[idx]); 2154 currentEdge.push_back(edge[idx+1]); 2155 } else { 2156 throw(AipsError("Wrong length of edge element")); 2157 } 2158 2159 lineFinder.setData(getSpectrum(whichrow)); 2160 lineFinder.findLines(getCompositeChanMask(whichrow, inMask), currentEdge, whichrow); 2161 2162 return lineFinder.getMask(); 2163 } 2164 */ 2165 2166 void Scantable::polyBaseline(const std::vector<bool>& mask, int order, bool outLogger, const std::string& blfile) 2167 { 2180 void Scantable::sinusoidBaseline(const std::vector<bool>& mask, int nMinWavesInSW, int nMaxWavesInSW, float thresClip, int nIterClip, bool outLogger, const std::string& blfile) { 2168 2181 ofstream ofs; 2169 2182 String coordInfo; 2170 bool hasSameNchan; 2171 int firstIF; 2183 bool hasSameNchan = true; 2172 2184 bool outTextFile = false; 2173 2185 … … 2181 2193 if (coordInfo == "") coordInfo = "channel"; 2182 2194 hasSameNchan = hasSameNchanOverIFs(); 2183 firstIF = getIF(0); 2184 } 2185 2186 Fitter fitter = Fitter(); 2187 fitter.setExpression("poly", order); 2195 } 2196 2197 //Fitter fitter = Fitter(); 2198 //fitter.setExpression("sinusoid", nMaxWavesInSW); 2188 2199 2189 2200 int nRow = nrow(); … … 2191 2202 2192 2203 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 2193 2194 2204 chanMask = getCompositeChanMask(whichrow, mask); 2195 fitBaseline(chanMask, whichrow, fitter); 2196 setSpectrum(fitter.getResidual(), whichrow); 2197 2198 if (outLogger || outTextFile) { 2199 std::vector<float> params = fitter.getParameters(); 2200 std::vector<bool> fixed = fitter.getFixedParameters(); 2201 float rms = getRms(chanMask, whichrow); 2202 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 2203 2204 if (outLogger) { 2205 LogIO ols(LogOrigin("Scantable", "polyBaseline()", WHERE)); 2206 ols << formatBaselineParams(params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 2207 } 2208 if (outTextFile) { 2209 ofs << formatBaselineParams(params, fixed, rms, masklist, whichrow, true) << flush; 2210 } 2211 } 2212 2205 //fitBaseline(chanMask, whichrow, fitter, thresClip, nIterClip); 2206 //setSpectrum(fitter.getResidual(), whichrow); 2207 std::vector<int> pieceRanges; 2208 std::vector<float> params; 2209 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nMinWavesInSW, nMaxWavesInSW, params, thresClip, nIterClip); 2210 setSpectrum(res, whichrow); 2211 // 2212 2213 std::vector<bool> fixed; 2214 fixed.clear(); 2215 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "sinusoidBaseline()", pieceRanges, params, fixed); 2213 2216 } 2214 2217 … … 2216 2219 } 2217 2220 2218 void Scantable::auto PolyBaseline(const std::vector<bool>& mask, int order, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool outLogger, const std::string& blfile)2221 void Scantable::autoSinusoidBaseline(const std::vector<bool>& mask, int nMinWavesInSW, int nMaxWavesInSW, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool outLogger, const std::string& blfile) 2219 2222 { 2220 2223 ofstream ofs; 2221 2224 String coordInfo; 2222 bool hasSameNchan; 2223 int firstIF; 2225 bool hasSameNchan = true; 2224 2226 bool outTextFile = false; 2225 2227 … … 2233 2235 if (coordInfo == "") coordInfo = "channel"; 2234 2236 hasSameNchan = hasSameNchanOverIFs(); 2235 firstIF = getIF(0); 2236 } 2237 2238 Fitter fitter = Fitter(); 2239 fitter.setExpression("poly", order); 2237 } 2238 2239 //Fitter fitter = Fitter(); 2240 //fitter.setExpression("sinusoid", nMaxWavesInSW); 2240 2241 2241 2242 int nRow = nrow(); … … 2271 2272 2272 2273 2273 fitBaseline(chanMask, whichrow, fitter); 2274 setSpectrum(fitter.getResidual(), whichrow); 2275 2276 if (outLogger || outTextFile) { 2277 std::vector<float> params = fitter.getParameters(); 2278 std::vector<bool> fixed = fitter.getFixedParameters(); 2279 float rms = getRms(chanMask, whichrow); 2280 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 2281 2282 if (outLogger) { 2283 LogIO ols(LogOrigin("Scantable", "autoPolyBaseline()", WHERE)); 2284 ols << formatBaselineParams(params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 2285 } 2286 if (outTextFile) { 2287 ofs << formatBaselineParams(params, fixed, rms, masklist, whichrow, true) << flush; 2288 } 2289 } 2290 2274 //fitBaseline(chanMask, whichrow, fitter, thresClip, nIterClip); 2275 //setSpectrum(fitter.getResidual(), whichrow); 2276 std::vector<int> pieceRanges; 2277 std::vector<float> params; 2278 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nMinWavesInSW, nMaxWavesInSW, params, thresClip, nIterClip); 2279 setSpectrum(res, whichrow); 2280 // 2281 2282 std::vector<bool> fixed; 2283 fixed.clear(); 2284 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoSinusoidBaseline()", pieceRanges, params, fixed); 2291 2285 } 2292 2286 … … 2294 2288 } 2295 2289 2290 std::vector<float> Scantable::doSinusoidFitting(const std::vector<float>& data, const std::vector<bool>& mask, int nMinWavesInSW, int nMaxWavesInSW, std::vector<float>& params, float thresClip, int nIterClip) { 2291 if (nMaxWavesInSW < 1) { 2292 throw(AipsError("maximum wave number must be a positive value")); 2293 } 2294 if (data.size() != mask.size()) { 2295 throw(AipsError("data and mask have different size")); 2296 } 2297 2298 int nChan = data.size(); 2299 std::vector<int> maskArray; 2300 std::vector<int> x; 2301 for (int i = 0; i < nChan; ++i) { 2302 maskArray.push_back(mask[i] ? 1 : 0); 2303 if (mask[i]) { 2304 x.push_back(i); 2305 } 2306 } 2307 2308 int nData = x.size(); 2309 2310 std::vector<double> x1, x2, x3, z1, x1z1, x2z1, x3z1, r1; 2311 for (int i = 0; i < nChan; ++i) { 2312 x1.push_back((double)i); 2313 x2.push_back((double)(i*i)); 2314 x3.push_back((double)(i*i*i)); 2315 z1.push_back((double)data[i]); 2316 x1z1.push_back(((double)i)*(double)data[i]); 2317 x2z1.push_back(((double)(i*i))*(double)data[i]); 2318 x3z1.push_back(((double)(i*i*i))*(double)data[i]); 2319 r1.push_back(0.0); 2320 } 2321 2322 int currentNData = nData; 2323 int nDOF = nMaxWavesInSW + 1; //number of parameters to solve. 2324 2325 for (int nClip = 0; nClip < nIterClip+1; ++nClip) { 2326 //xMatrix : horizontal concatenation of the least-sq. matrix (left) and an 2327 //identity matrix (right). 2328 //the right part is used to calculate the inverse matrix of the left part. 2329 double xMatrix[nDOF][2*nDOF]; 2330 double zMatrix[nDOF]; 2331 for (int i = 0; i < nDOF; ++i) { 2332 for (int j = 0; j < 2*nDOF; ++j) { 2333 xMatrix[i][j] = 0.0; 2334 } 2335 xMatrix[i][nDOF+i] = 1.0; 2336 zMatrix[i] = 0.0; 2337 } 2338 2339 for (int i = 0; i < currentNData; ++i) { 2340 if (maskArray[i] == 0) continue; 2341 xMatrix[0][0] += 1.0; 2342 xMatrix[0][1] += x1[i]; 2343 xMatrix[0][2] += x2[i]; 2344 xMatrix[0][3] += x3[i]; 2345 xMatrix[1][1] += x2[i]; 2346 xMatrix[1][2] += x3[i]; 2347 xMatrix[1][3] += x2[i]*x2[i]; 2348 xMatrix[2][2] += x2[i]*x2[i]; 2349 xMatrix[2][3] += x3[i]*x2[i]; 2350 xMatrix[3][3] += x3[i]*x3[i]; 2351 zMatrix[0] += z1[i]; 2352 zMatrix[1] += x1z1[i]; 2353 zMatrix[2] += x2z1[i]; 2354 zMatrix[3] += x3z1[i]; 2355 } 2356 2357 for (int i = 0; i < nDOF; ++i) { 2358 for (int j = 0; j < i; ++j) { 2359 xMatrix[i][j] = xMatrix[j][i]; 2360 } 2361 } 2362 2363 std::vector<double> invDiag; 2364 for (int i = 0; i < nDOF; ++i) { 2365 invDiag.push_back(1.0/xMatrix[i][i]); 2366 for (int j = 0; j < nDOF; ++j) { 2367 xMatrix[i][j] *= invDiag[i]; 2368 } 2369 } 2370 2371 for (int k = 0; k < nDOF; ++k) { 2372 for (int i = 0; i < nDOF; ++i) { 2373 if (i != k) { 2374 double factor1 = xMatrix[k][k]; 2375 double factor2 = xMatrix[i][k]; 2376 for (int j = k; j < 2*nDOF; ++j) { 2377 xMatrix[i][j] *= factor1; 2378 xMatrix[i][j] -= xMatrix[k][j]*factor2; 2379 xMatrix[i][j] /= factor1; 2380 } 2381 } 2382 } 2383 double xDiag = xMatrix[k][k]; 2384 for (int j = k; j < 2*nDOF; ++j) { 2385 xMatrix[k][j] /= xDiag; 2386 } 2387 } 2388 2389 for (int i = 0; i < nDOF; ++i) { 2390 for (int j = 0; j < nDOF; ++j) { 2391 xMatrix[i][nDOF+j] *= invDiag[j]; 2392 } 2393 } 2394 //compute a vector y which consists of the coefficients of the sinusoids forming the 2395 //best-fit curves (a0,b0,a1,b1,...), namely, a* and b* are of sine and cosine functions, 2396 //respectively. 2397 std::vector<double> y; 2398 for (int i = 0; i < nDOF; ++i) { 2399 y.push_back(0.0); 2400 for (int j = 0; j < nDOF; ++j) { 2401 y[i] += xMatrix[i][nDOF+j]*zMatrix[j]; 2402 } 2403 } 2404 2405 double a0 = y[0]; 2406 double a1 = y[1]; 2407 double a2 = y[2]; 2408 double a3 = y[3]; 2409 params.clear(); 2410 2411 for (int i = 0; i < nChan; ++i) { 2412 r1[i] = a0 + a1*x1[i] + a2*x2[i] + a3*x3[i]; 2413 } 2414 params.push_back(a0); 2415 params.push_back(a1); 2416 params.push_back(a2); 2417 params.push_back(a3); 2418 2419 2420 if ((nClip == nIterClip) || (thresClip <= 0.0)) { 2421 break; 2422 } else { 2423 std::vector<double> rz; 2424 double stdDev = 0.0; 2425 for (int i = 0; i < nChan; ++i) { 2426 double val = abs(r1[i] - z1[i]); 2427 rz.push_back(val); 2428 stdDev += val*val*(double)maskArray[i]; 2429 } 2430 stdDev = sqrt(stdDev/(double)nData); 2431 2432 double thres = stdDev * thresClip; 2433 int newNData = 0; 2434 for (int i = 0; i < nChan; ++i) { 2435 if (rz[i] >= thres) { 2436 maskArray[i] = 0; 2437 } 2438 if (maskArray[i] > 0) { 2439 newNData++; 2440 } 2441 } 2442 if (newNData == currentNData) { 2443 break; //no additional flag. finish iteration. 2444 } else { 2445 currentNData = newNData; 2446 } 2447 } 2448 } 2449 2450 std::vector<float> residual; 2451 for (int i = 0; i < nChan; ++i) { 2452 residual.push_back((float)(z1[i] - r1[i])); 2453 } 2454 return residual; 2455 2456 } 2457 2458 void Scantable::fitBaseline(const std::vector<bool>& mask, int whichrow, Fitter& fitter) 2459 { 2460 std::vector<double> abcsd = getAbcissa(whichrow); 2461 std::vector<float> abcs; 2462 for (uInt i = 0; i < abcsd.size(); ++i) { 2463 abcs.push_back((float)abcsd[i]); 2464 } 2465 std::vector<float> spec = getSpectrum(whichrow); 2466 2467 fitter.setData(abcs, spec, mask); 2468 fitter.lfit(); 2469 } 2470 2471 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask) 2472 { 2473 std::vector<bool> chanMask = getMask(whichrow); 2474 uInt chanMaskSize = chanMask.size(); 2475 if (chanMaskSize != inMask.size()) { 2476 throw(AipsError("different mask sizes")); 2477 } 2478 for (uInt i = 0; i < chanMaskSize; ++i) { 2479 chanMask[i] = chanMask[i] && inMask[i]; 2480 } 2481 2482 return chanMask; 2483 } 2484 2485 /* 2486 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, const int minEdgeSize, STLineFinder& lineFinder) 2487 { 2488 int edgeSize = edge.size(); 2489 std::vector<int> currentEdge; 2490 if (edgeSize >= 2) { 2491 int idx = 0; 2492 if (edgeSize > 2) { 2493 if (edgeSize < minEdgeSize) { 2494 throw(AipsError("Length of edge element info is less than that of IFs")); 2495 } 2496 idx = 2 * getIF(whichrow); 2497 } 2498 currentEdge.push_back(edge[idx]); 2499 currentEdge.push_back(edge[idx+1]); 2500 } else { 2501 throw(AipsError("Wrong length of edge element")); 2502 } 2503 2504 lineFinder.setData(getSpectrum(whichrow)); 2505 lineFinder.findLines(getCompositeChanMask(whichrow, inMask), currentEdge, whichrow); 2506 2507 return lineFinder.getMask(); 2508 } 2509 */ 2510 2511 /* for poly. the variations of outputFittingResult() should be merged into one eventually (2011/3/10 WK) */ 2512 void Scantable::outputFittingResult(bool outLogger, bool outTextFile, const std::vector<bool>& chanMask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, ofstream& ofs, const casa::String& funcName, Fitter& fitter) { 2513 if (outLogger || outTextFile) { 2514 std::vector<float> params = fitter.getParameters(); 2515 std::vector<bool> fixed = fitter.getFixedParameters(); 2516 float rms = getRms(chanMask, whichrow); 2517 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan); 2518 2519 if (outLogger) { 2520 LogIO ols(LogOrigin("Scantable", funcName, WHERE)); 2521 ols << formatBaselineParams(params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 2522 } 2523 if (outTextFile) { 2524 ofs << formatBaselineParams(params, fixed, rms, masklist, whichrow, true) << flush; 2525 } 2526 } 2527 } 2528 2529 /* for cspline. will be merged once cspline is available in fitter (2011/3/10 WK) */ 2530 void Scantable::outputFittingResult(bool outLogger, bool outTextFile, const std::vector<bool>& chanMask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, ofstream& ofs, const casa::String& funcName, const std::vector<int>& pieceEdges, const std::vector<float>& params, const std::vector<bool>& fixed) { 2531 if (outLogger || outTextFile) { 2532 float rms = getRms(chanMask, whichrow); 2533 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan); 2534 2535 if (outLogger) { 2536 LogIO ols(LogOrigin("Scantable", funcName, WHERE)); 2537 ols << formatPiecewiseBaselineParams(pieceEdges, params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 2538 } 2539 if (outTextFile) { 2540 ofs << formatPiecewiseBaselineParams(pieceEdges, params, fixed, rms, masklist, whichrow, true) << flush; 2541 } 2542 } 2543 } 2544 2545 /* for sinusoid. will be merged once sinusoid is available in fitter (2011/3/10 WK) */ 2546 void Scantable::outputFittingResult(bool outLogger, bool outTextFile, const std::vector<bool>& chanMask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, ofstream& ofs, const casa::String& funcName, const std::vector<float>& params, const std::vector<bool>& fixed) { 2547 if (outLogger || outTextFile) { 2548 float rms = getRms(chanMask, whichrow); 2549 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan); 2550 2551 if (outLogger) { 2552 LogIO ols(LogOrigin("Scantable", funcName, WHERE)); 2553 ols << formatBaselineParams(params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 2554 } 2555 if (outTextFile) { 2556 ofs << formatBaselineParams(params, fixed, rms, masklist, whichrow, true) << flush; 2557 } 2558 } 2559 } 2296 2560 2297 2561 float Scantable::getRms(const std::vector<bool>& mask, int whichrow) { … … 2302 2566 float smean = 0.0; 2303 2567 int n = 0; 2304 for ( int i = 0; i < spec.nelements(); ++i) {2568 for (uInt i = 0; i < spec.nelements(); ++i) { 2305 2569 if (mask[i]) { 2306 2570 mean += spec[i]; … … 2344 2608 2345 2609 if (verbose) { 2346 oss << endl;2347 2610 oss << "Results of baseline fit" << endl; 2348 2611 oss << " rms = " << setprecision(6) << rms << endl; … … 2352 2615 } 2353 2616 2354 std::string Scantable::format PiecewiseBaselineParams(const std::vector<int>& ranges,const std::vector<float>& params, const std::vector<bool>& fixed, float rms, const std::string& masklist, int whichrow, bool verbose) const2617 std::string Scantable::formatBaselineParams(const std::vector<float>& params, const std::vector<bool>& fixed, float rms, const std::string& masklist, int whichrow, bool verbose) const 2355 2618 { 2356 2619 ostringstream oss; 2357 2620 oss << formatBaselineParamsHeader(whichrow, masklist, verbose); 2358 2621 2622 if (params.size() > 0) { 2623 for (uInt i = 0; i < params.size(); ++i) { 2624 if (i > 0) { 2625 oss << ","; 2626 } 2627 std::string fix = ((fixed.size() > 0) && (fixed[i]) && verbose) ? "(fixed)" : ""; 2628 float vParam = params[i]; 2629 std::string equals = "= " + (String)((vParam < 0.0) ? "" : " "); 2630 oss << " p" << i << fix << equals << setprecision(6) << vParam; 2631 } 2632 } else { 2633 oss << " Not fitted"; 2634 } 2635 oss << endl; 2636 2637 oss << formatBaselineParamsFooter(rms, verbose); 2638 oss << flush; 2639 2640 return String(oss); 2641 } 2642 2643 std::string Scantable::formatPiecewiseBaselineParams(const std::vector<int>& ranges, const std::vector<float>& params, const std::vector<bool>& fixed, float rms, const std::string& masklist, int whichrow, bool verbose) const 2644 { 2645 ostringstream oss; 2646 oss << formatBaselineParamsHeader(whichrow, masklist, verbose); 2647 2359 2648 if ((params.size() > 0) && (ranges.size() > 0)) { 2360 2649 if (((ranges.size() % 2) == 0) && ((params.size() % (ranges.size() / 2)) == 0)) { 2361 int nParam = params.size() / (ranges.size() / 2); 2650 uInt nParam = params.size() / (ranges.size() / 2); 2651 stringstream ss; 2652 ss << ranges[ranges.size()-1] << flush; 2653 int wRange = ss.str().size()*2+5; 2654 ss.str(""); 2362 2655 for (uInt j = 0; j < ranges.size(); j+=2) { 2363 oss << "[" << ranges[j] << "," << ranges[j+1] << "]"; 2656 ss << " [" << ranges[j] << "," << ranges[j+1] << "]" << flush; 2657 oss << setw(wRange) << left << ss.str(); 2658 ss.str(""); 2364 2659 for (uInt i = 0; i < nParam; ++i) { 2365 2660 if (i > 0) { 2366 2661 oss << ","; 2367 2662 } 2368 String fix = ((fixed.size() > 0) && (fixed[i]) && verbose) ? "(fixed)" : ""; 2369 oss << " p" << i << fix << "= " << setprecision(6) << params[j/2*nParam+i]; 2663 std::string fix = ((fixed.size() > 0) && (fixed[i]) && verbose) ? "(fixed)" : ""; 2664 float vParam = params[j/2*nParam+i]; 2665 std::string equals = "= " + (String)((vParam < 0.0) ? "" : " "); 2666 oss << " p" << i << fix << equals << setprecision(6) << vParam; 2370 2667 } 2668 oss << endl; 2371 2669 } 2372 2670 } else { 2373 oss << " " ;2671 oss << " " << endl; 2374 2672 } 2375 2673 } else { 2376 oss << " Not fitted" ;2674 oss << " Not fitted" << endl; 2377 2675 } 2378 2676 2379 2677 oss << formatBaselineParamsFooter(rms, verbose); 2380 2678 oss << flush; 2381 2382 return String(oss);2383 }2384 2385 std::string Scantable::formatBaselineParams(const std::vector<float>& params, const std::vector<bool>& fixed, float rms, const std::string& masklist, int whichrow, bool verbose) const2386 {2387 ostringstream oss;2388 oss << formatBaselineParamsHeader(whichrow, masklist, verbose);2389 2390 if (params.size() > 0) {2391 for (uInt i = 0; i < params.size(); ++i) {2392 if (i > 0) {2393 oss << ",";2394 }2395 String fix = ((fixed.size() > 0) && (fixed[i]) && verbose) ? "(fixed)" : "";2396 oss << " p" << i << fix << "= " << setprecision(6) << params[i];2397 }2398 } else {2399 oss << " Not fitted";2400 }2401 2402 oss << formatBaselineParamsFooter(rms, verbose);2403 oss << flush;2404 2405 return String(oss);2406 }2407 2408 std::string Scantable::getMaskRangeList(const std::vector<bool>& mask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, int firstIF, bool silent)2409 {2410 if (mask.size() < 2) {2411 throw(AipsError("The mask elements should be > 1"));2412 }2413 if (mask.size() != nchan()) {2414 throw(AipsError("Number of channels in scantable != number of mask elements"));2415 }2416 2417 std::vector<int> startIdx = getMaskEdgeIndices(mask, true);2418 std::vector<int> endIdx = getMaskEdgeIndices(mask, false);2419 2420 if (startIdx.size() != endIdx.size()) {2421 throw(AipsError("Numbers of mask start and mask end are not identical"));2422 }2423 for (int i = 0; i < startIdx.size(); ++i) {2424 if (startIdx[i] > endIdx[i]) {2425 throw(AipsError("Mask start index > mask end index"));2426 }2427 }2428 2429 if (!silent) {2430 LogIO logOs(LogOrigin("Scantable", "getMaskRangeList()", WHERE));2431 logOs << LogIO::WARN << "The current mask window unit is " << coordInfo;2432 if (!hasSameNchan) {2433 logOs << endl << "This mask is only valid for IF=" << firstIF;2434 }2435 logOs << LogIO::POST;2436 }2437 2438 std::vector<double> abcissa = getAbcissa(whichrow);2439 ostringstream oss;2440 oss.setf(ios::fixed);2441 oss << setprecision(1) << "[";2442 for (int i = 0; i < startIdx.size(); ++i) {2443 std::vector<float> aMaskRange;2444 aMaskRange.push_back((float)abcissa[startIdx[i]]);2445 aMaskRange.push_back((float)abcissa[endIdx[i]]);2446 sort(aMaskRange.begin(), aMaskRange.end());2447 if (i > 0) oss << ",";2448 oss << "[" << aMaskRange[0] << "," << aMaskRange[1] << "]";2449 }2450 oss << "]" << flush;2451 2679 2452 2680 return String(oss); … … 2471 2699 } 2472 2700 2473 std:: vector<int> Scantable::getMaskEdgeIndices(const std::vector<bool>& mask, bool getStartIndices)2701 std::string Scantable::getMaskRangeList(const std::vector<bool>& mask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, bool verbose) 2474 2702 { 2475 2703 if (mask.size() < 2) { 2476 2704 throw(AipsError("The mask elements should be > 1")); 2477 2705 } 2478 if (mask.size() != nchan()) { 2706 int IF = getIF(whichrow); 2707 if (mask.size() != (uInt)nchan(IF)) { 2479 2708 throw(AipsError("Number of channels in scantable != number of mask elements")); 2480 2709 } 2481 2710 2482 std::vector<int> out; 2483 int endIdx = mask.size() - 1; 2484 2485 if (getStartIndices) { 2486 if (mask[0]) { 2487 out.push_back(0); 2488 } 2489 for (int i = 0; i < endIdx; ++i) { 2490 if ((!mask[i]) && mask[i+1]) { 2491 out.push_back(i+1); 2492 } 2493 } 2494 } else { 2495 for (int i = 0; i < endIdx; ++i) { 2496 if (mask[i] && (!mask[i+1])) { 2497 out.push_back(i); 2498 } 2499 } 2500 if (mask[endIdx]) { 2501 out.push_back(endIdx); 2502 } 2711 if (verbose) { 2712 LogIO logOs(LogOrigin("Scantable", "getMaskRangeList()", WHERE)); 2713 logOs << LogIO::WARN << "The current mask window unit is " << coordInfo; 2714 if (!hasSameNchan) { 2715 logOs << endl << "This mask is only valid for IF=" << IF; 2716 } 2717 logOs << LogIO::POST; 2718 } 2719 2720 std::vector<double> abcissa = getAbcissa(whichrow); 2721 std::vector<int> edge = getMaskEdgeIndices(mask); 2722 2723 ostringstream oss; 2724 oss.setf(ios::fixed); 2725 oss << setprecision(1) << "["; 2726 for (uInt i = 0; i < edge.size(); i+=2) { 2727 if (i > 0) oss << ","; 2728 oss << "[" << (float)abcissa[edge[i]] << "," << (float)abcissa[edge[i+1]] << "]"; 2729 } 2730 oss << "]" << flush; 2731 2732 return String(oss); 2733 } 2734 2735 std::vector<int> Scantable::getMaskEdgeIndices(const std::vector<bool>& mask) 2736 { 2737 if (mask.size() < 2) { 2738 throw(AipsError("The mask elements should be > 1")); 2739 } 2740 2741 std::vector<int> out, startIndices, endIndices; 2742 int maskSize = mask.size(); 2743 2744 startIndices.clear(); 2745 endIndices.clear(); 2746 2747 if (mask[0]) { 2748 startIndices.push_back(0); 2749 } 2750 for (int i = 1; i < maskSize; ++i) { 2751 if ((!mask[i-1]) && mask[i]) { 2752 startIndices.push_back(i); 2753 } else if (mask[i-1] && (!mask[i])) { 2754 endIndices.push_back(i-1); 2755 } 2756 } 2757 if (mask[maskSize-1]) { 2758 endIndices.push_back(maskSize-1); 2759 } 2760 2761 if (startIndices.size() != endIndices.size()) { 2762 throw(AipsError("Inconsistent Mask Size: bad data?")); 2763 } 2764 for (uInt i = 0; i < startIndices.size(); ++i) { 2765 if (startIndices[i] > endIndices[i]) { 2766 throw(AipsError("Mask start index > mask end index")); 2767 } 2768 } 2769 2770 out.clear(); 2771 for (uInt i = 0; i < startIndices.size(); ++i) { 2772 out.push_back(startIndices[i]); 2773 out.push_back(endIndices[i]); 2503 2774 } 2504 2775 -
trunk/src/Scantable.h
r2012 r2047 493 493 void regridChannel( int nchan, double dnu, int irow ) ; 494 494 495 bool getFlagtraFast( int whichrow);495 bool getFlagtraFast(casa::uInt whichrow); 496 496 497 497 void polyBaseline(const std::vector<bool>& mask, … … 521 521 bool outLogger=false, 522 522 const std::string& blfile=""); 523 void sinusoidBaseline(const std::vector<bool>& mask, 524 int nMinWavesInSW, 525 int nMaxWavesInSW, 526 float thresClip, 527 int nIterClip, 528 bool outLogger=false, 529 const std::string& blfile=""); 530 void autoSinusoidBaseline(const std::vector<bool>& mask, 531 int nMinWavesInSW, 532 int nMaxWavesInSW, 533 float thresClip, 534 int nIterClip, 535 const std::vector<int>& edge, 536 float threshold=3.0, 537 int chanAvgLimit=1, 538 bool outLogger=false, 539 const std::string& blfile=""); 523 540 float getRms(const std::vector<bool>& mask, int whichrow); 524 541 std::string formatBaselineParams(const std::vector<float>& params, … … 657 674 float thresClip=3.0, 658 675 int nIterClip=1); 676 std::vector<float> doSinusoidFitting(const std::vector<float>& data, 677 const std::vector<bool>& mask, 678 int nMinWavesInSW, 679 int nMaxWavesInSW, 680 std::vector<float>& params, 681 float thresClip=3.0, 682 int nIterClip=1); 659 683 bool hasSameNchanOverIFs(); 660 684 std::string getMaskRangeList(const std::vector<bool>& mask, 661 685 int whichrow, 662 686 const casa::String& coordInfo, 663 bool hasSameNchan, 664 int firstIF, 665 bool silent=false); 666 std::vector<int> getMaskEdgeIndices(const std::vector<bool>& mask, bool getStartIndices=true); 687 bool hasSameNchan, 688 bool verbose=false); 689 std::vector<int> getMaskEdgeIndices(const std::vector<bool>& mask); 667 690 std::string formatBaselineParamsHeader(int whichrow, const std::string& masklist, bool verbose) const; 668 691 std::string formatBaselineParamsFooter(float rms, bool verbose) const; 669 692 std::vector<bool> getCompositeChanMask(int whichrow, const std::vector<bool>& inMask); 670 693 //std::vector<bool> getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, const int minEdgeSize, STLineFinder& lineFinder); 694 void outputFittingResult(bool outLogger, bool outTextFile, const std::vector<bool>& chanMask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, std::ofstream& ofs, const casa::String& funcName, Fitter& fitter); 695 void outputFittingResult(bool outLogger, bool outTextFile, const std::vector<bool>& chanMask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, std::ofstream& ofs, const casa::String& funcName, const std::vector<int>& pieceEdges, const std::vector<float>& params, const std::vector<bool>& fixed); 696 void outputFittingResult(bool outLogger, bool outTextFile, const std::vector<bool>& chanMask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, std::ofstream& ofs, const casa::String& funcName, const std::vector<float>& params, const std::vector<bool>& fixed); 671 697 672 698 void applyChanFlag( casa::uInt whichrow, const std::vector<bool>& msk, casa::uChar flagval); -
trunk/src/ScantableWrapper.h
r2012 r2047 269 269 { table_->autoCubicSplineBaseline(mask, npiece, clipthresh, clipniter, edge, threshold, chan_avg_limit, outlog, blfile); } 270 270 271 void sinusoidBaseline(const std::vector<bool>& mask, int minnwave, int maxnwave, float clipthresh, int clipniter, bool outlog=false, const std::string& blfile="") 272 { table_->sinusoidBaseline(mask, minnwave, maxnwave, clipthresh, clipniter, outlog, blfile); } 273 274 void autoSinusoidBaseline(const std::vector<bool>& mask, int minnwave, int maxnwave, float clipthresh, int clipniter, const std::vector<int>& edge, float threshold=5.0, int chan_avg_limit=1, bool outlog=false, const std::string& blfile="") 275 { table_->autoSinusoidBaseline(mask, minnwave, maxnwave, clipthresh, clipniter, edge, threshold, chan_avg_limit, outlog, blfile); } 276 271 277 float getRms(const std::vector<bool>& mask, int whichrow) 272 278 { return table_->getRms(mask, whichrow); } … … 279 285 280 286 bool getFlagtraFast(int whichrow=0) const 281 { return table_->getFlagtraFast( whichrow); }287 { return table_->getFlagtraFast(casa::uInt(whichrow)); } 282 288 283 289 -
trunk/src/python_Scantable.cpp
r2012 r2047 146 146 .def("_cspline_baseline", &ScantableWrapper::cubicSplineBaseline) 147 147 .def("_auto_cspline_baseline", &ScantableWrapper::autoCubicSplineBaseline) 148 .def("_sinusoid_baseline", &ScantableWrapper::sinusoidBaseline) 149 .def("_auto_sinusoid_baseline", &ScantableWrapper::autoSinusoidBaseline) 148 150 .def("get_rms", &ScantableWrapper::getRms) 149 151 .def("format_blparams_row", &ScantableWrapper::formatBaselineParams)
Note:
See TracChangeset
for help on using the changeset viewer.