Changeset 2081
- Timestamp:
- 03/30/11 21:30:28 (14 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/python/scantable.py
r2047 r2081 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) 2072 def sinusoid_baseline(self, insitu=None, mask=None, nwave=None, maxwavelength=None, 2073 clipthresh=None, clipniter=None, plot=None, getresidual=None, outlog=None, blfile=None): 2074 """\ 2075 Return a scan which has been baselined (all rows) by sinusoidal functions. 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 nwave: the maximum wave number of sinusoids within 2082 maxwavelength * (spectral range). 2083 The default is 3 (i.e., sinusoids with wave 2084 number of 0(=constant), 1, 2, and 3 are 2085 used for fitting). Also it is possible to 2086 explicitly specify all the wave numbers to 2087 be used, by giving a list including them 2088 (e.g. [0,1,2,15,16]). 2089 maxwavelength: the longest sinusoidal wavelength. The 2090 default is 1.0 (unit: spectral range). 2091 clipthresh: Clipping threshold. (default is 3.0, unit: sigma) 2092 clipniter: maximum number of iteration of 'clipthresh'-sigma clipping (default is 1) 2093 plot: *** CURRENTLY UNAVAILABLE, ALWAYS FALSE *** 2094 plot the fit and the residual. In this each 2095 indivual fit has to be approved, by typing 'y' 2096 or 'n' 2097 getresidual: if False, returns best-fit values instead of 2098 residual. (default is True) 2099 outlog: Output the coefficients of the best-fit 2100 function to logger (default is False) 2101 blfile: Name of a text file in which the best-fit 2102 parameter values to be written 2103 (default is "": no file/logger output) 2094 2104 2095 2105 Example: 2096 2106 # return a scan baselined by a combination of sinusoidal curves having 2097 # wave numbers in spectral window from 1to 10,2107 # wave numbers in spectral window up to 10, 2098 2108 # also with 3-sigma clipping, iteration up to 4 times 2099 bscan = scan.sinusoid_baseline(maxnwave=10,clipthresh=3.0,clipniter=4) 2109 bscan = scan.sinusoid_baseline(nwave=10,clipthresh=3.0,clipniter=4) 2110 2111 Note: 2112 The best-fit parameter values output in logger and/or blfile are now 2113 based on specunit of 'channel'. 2100 2114 """ 2101 2115 … … 2110 2124 nchan = workscan.nchan() 2111 2125 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 2126 if mask is None: mask = [True for i in xrange(nchan)] 2127 if nwave is None: nwave = 3 2128 if maxwavelength is None: maxwavelength = 1.0 2129 if clipthresh is None: clipthresh = 3.0 2130 if clipniter is None: clipniter = 1 2131 if plot is None: plot = False 2132 if getresidual is None: getresidual = True 2133 if outlog is None: outlog = False 2134 if blfile is None: blfile = "" 2135 2136 if isinstance(nwave, int): 2137 in_nwave = nwave 2138 nwave = [] 2139 for i in xrange(in_nwave+1): nwave.append(i) 2140 2121 2141 outblfile = (blfile != "") and os.path.exists(os.path.expanduser(os.path.expandvars(blfile))) 2122 2142 2123 2143 try: 2124 #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic splinefitting is implemented as a fitter method.2125 workscan._sinusoid_baseline(mask, minnwave, maxnwave, clipthresh, clipniter, outlog, blfile)2144 #CURRENTLY, PLOT=true is UNAVAILABLE UNTIL sinusoidal fitting is implemented as a fitter method. 2145 workscan._sinusoid_baseline(mask, nwave, maxwavelength, clipthresh, clipniter, getresidual, outlog, blfile) 2126 2146 2127 2147 workscan._add_history("sinusoid_baseline", varlist) … … 2142 2162 2143 2163 2144 def auto_sinusoid_baseline(self, insitu=None, mask=None, minnwave=None, maxnwave=None,2164 def auto_sinusoid_baseline(self, insitu=None, mask=None, nwave=None, maxwavelength=None, 2145 2165 clipthresh=None, clipniter=None, edge=None, threshold=None, 2146 chan_avg_limit=None, plot=None, outlog=None, blfile=None):2166 chan_avg_limit=None, plot=None, getresidual=None, outlog=None, blfile=None): 2147 2167 """\ 2148 2168 Return a scan which has been baselined (all rows) by cubic spline … … 2152 2172 2153 2173 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) 2174 insitu: if False a new scantable is returned. 2175 Otherwise, the scaling is done in-situ 2176 The default is taken from .asaprc (False) 2177 mask: an optional mask retreived from scantable 2178 nwave: the maximum wave number of sinusoids within 2179 maxwavelength * (spectral range). 2180 The default is 3 (i.e., sinusoids with wave 2181 number of 0(=constant), 1, 2, and 3 are 2182 used for fitting). Also it is possible to 2183 explicitly specify all the wave numbers to 2184 be used, by giving a list including them 2185 (e.g. [0,1,2,15,16]). 2186 maxwavelength: the longest sinusoidal wavelength. The 2187 default is 1.0 (unit: spectral range). 2188 clipthresh: Clipping threshold. (default is 3.0, unit: sigma) 2189 clipniter: maximum number of iteration of 'clipthresh'-sigma clipping (default is 1) 2190 edge: an optional number of channel to drop at 2191 the edge of spectrum. If only one value is 2192 specified, the same number will be dropped 2193 from both sides of the spectrum. Default 2194 is to keep all channels. Nested tuples 2195 represent individual edge selection for 2196 different IFs (a number of spectral channels 2197 can be different) 2198 threshold: the threshold used by line finder. It is 2199 better to keep it large as only strong lines 2200 affect the baseline solution. 2201 chan_avg_limit:a maximum number of consequtive spectral 2202 channels to average during the search of 2203 weak and broad lines. The default is no 2204 averaging (and no search for weak lines). 2205 If such lines can affect the fitted baseline 2206 (e.g. a high order polynomial is fitted), 2207 increase this parameter (usually values up 2208 to 8 are reasonable). Most users of this 2209 method should find the default value sufficient. 2210 plot: *** CURRENTLY UNAVAILABLE, ALWAYS FALSE *** 2211 plot the fit and the residual. In this each 2212 indivual fit has to be approved, by typing 'y' 2213 or 'n' 2214 getresidual: if False, returns best-fit values instead of 2215 residual. (default is True) 2216 outlog: Output the coefficients of the best-fit 2217 function to logger (default is False) 2218 blfile: Name of a text file in which the best-fit 2219 parameter values to be written 2220 (default is "": no file/logger output) 2192 2221 2193 2222 Example: 2194 bscan = scan.auto_sinusoid_baseline(maxnwave=10, insitu=False) 2223 bscan = scan.auto_sinusoid_baseline(nwave=10, insitu=False) 2224 2225 Note: 2226 The best-fit parameter values output in logger and/or blfile are now 2227 based on specunit of 'channel'. 2195 2228 """ 2196 2229 … … 2205 2238 nchan = workscan.nchan() 2206 2239 2207 if mask is None: mask= [True for i in xrange(nchan)]2208 if minnwave is None: minnwave = 02209 if max nwave is None: maxnwave = 32210 if clipthresh is None: clipthresh= 3.02211 if clipniter is None: clipniter= 12212 if edge is None: edge = (0,0)2213 if threshold is None: threshold= 32240 if mask is None: mask = [True for i in xrange(nchan)] 2241 if nwave is None: nwave = 3 2242 if maxwavelength is None: maxwavelength = 1.0 2243 if clipthresh is None: clipthresh = 3.0 2244 if clipniter is None: clipniter = 1 2245 if edge is None: edge = (0,0) 2246 if threshold is None: threshold = 3 2214 2247 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 = "" 2248 if plot is None: plot = False 2249 if getresidual is None: getresidual = True 2250 if outlog is None: outlog = False 2251 if blfile is None: blfile = "" 2218 2252 2219 2253 outblfile = (blfile != "") and os.path.exists(os.path.expanduser(os.path.expandvars(blfile))) … … 2221 2255 from asap.asaplinefind import linefinder 2222 2256 from asap import _is_sequence_or_number as _is_valid 2257 2258 if isinstance(nwave, int): 2259 in_nwave = nwave 2260 nwave = [] 2261 for i in xrange(in_nwave+1): nwave.append(i) 2223 2262 2224 2263 if not (isinstance(edge, list) or isinstance(edge, tuple)): edge = [ edge ] … … 2244 2283 2245 2284 try: 2246 #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic splinefitting is implemented as a fitter method.2285 #CURRENTLY, PLOT=true is UNAVAILABLE UNTIL sinusoidal fitting is implemented as a fitter method. 2247 2286 if individualedge: 2248 2287 curedge = [] … … 2250 2289 curedge += edge[i] 2251 2290 2252 workscan._auto_sinusoid_baseline(mask, minnwave, maxnwave, clipthresh, clipniter, curedge, threshold, chan_avg_limit, outlog, blfile)2291 workscan._auto_sinusoid_baseline(mask, nwave, maxwavelength, clipthresh, clipniter, curedge, threshold, chan_avg_limit, getresidual, outlog, blfile) 2253 2292 2254 2293 workscan._add_history("auto_sinusoid_baseline", varlist) … … 2295 2334 # also with 3-sigma clipping, iteration up to 4 times 2296 2335 bscan = scan.cspline_baseline(npiece=2,clipthresh=3.0,clipniter=4) 2336 2337 Note: 2338 The best-fit parameter values output in logger and/or blfile are now 2339 based on specunit of 'channel'. 2297 2340 """ 2298 2341 … … 2388 2431 Example: 2389 2432 bscan = scan.auto_cspline_baseline(npiece=3, insitu=False) 2433 2434 Note: 2435 The best-fit parameter values output in logger and/or blfile are now 2436 based on specunit of 'channel'. 2390 2437 """ 2391 2438 -
trunk/src/STLineFinder.cpp
r2012 r2081 1203 1203 vel = scan->getAbcissa(last_row_used); 1204 1204 } else { 1205 for ( int i = 0; i < spectrum.nelements(); ++i)1205 for (uInt i = 0; i < spectrum.nelements(); ++i) 1206 1206 vel.push_back((double)i); 1207 1207 } -
trunk/src/Scantable.cpp
r2080 r2081 1778 1778 { 1779 1779 ofstream ofs; 1780 String coordInfo ;1780 String coordInfo = ""; 1781 1781 bool hasSameNchan = true; 1782 1782 bool outTextFile = false; … … 1795 1795 Fitter fitter = Fitter(); 1796 1796 fitter.setExpression("poly", order); 1797 //fitter.setIterClipping(thresClip, nIterClip); 1797 1798 1798 1799 int nRow = nrow(); … … 1812 1813 { 1813 1814 ofstream ofs; 1814 String coordInfo ;1815 String coordInfo = ""; 1815 1816 bool hasSameNchan = true; 1816 1817 bool outTextFile = false; … … 1829 1830 Fitter fitter = Fitter(); 1830 1831 fitter.setExpression("poly", order); 1832 //fitter.setIterClipping(thresClip, nIterClip); 1831 1833 1832 1834 int nRow = nrow(); … … 1870 1872 } 1871 1873 1872 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, bool outLogger, const std::string& blfile) { 1874 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, bool outLogger, const std::string& blfile) 1875 { 1873 1876 ofstream ofs; 1874 String coordInfo ;1877 String coordInfo = ""; 1875 1878 bool hasSameNchan = true; 1876 1879 bool outTextFile = false; … … 1889 1892 //Fitter fitter = Fitter(); 1890 1893 //fitter.setExpression("cspline", nPiece); 1894 //fitter.setIterClipping(thresClip, nIterClip); 1891 1895 1892 1896 int nRow = nrow(); … … 1895 1899 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 1896 1900 chanMask = getCompositeChanMask(whichrow, mask); 1897 //fitBaseline(chanMask, whichrow, fitter , thresClip, nIterClip);1901 //fitBaseline(chanMask, whichrow, fitter); 1898 1902 //setSpectrum(fitter.getResidual(), whichrow); 1899 std::vector<int> piece Ranges;1903 std::vector<int> pieceEdges; 1900 1904 std::vector<float> params; 1901 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, pieceRanges, params, nPiece, thresClip, nIterClip, true);1905 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, nPiece, pieceEdges, params, thresClip, nIterClip, true); 1902 1906 setSpectrum(res, whichrow); 1903 1907 // 1904 1908 1905 std::vector<bool> fixed; 1906 fixed.clear(); 1907 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "cubicSplineBaseline()", pieceRanges, params, fixed); 1909 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "cubicSplineBaseline()", pieceEdges, params); 1908 1910 } 1909 1911 … … 1914 1916 { 1915 1917 ofstream ofs; 1916 String coordInfo ;1918 String coordInfo = ""; 1917 1919 bool hasSameNchan = true; 1918 1920 bool outTextFile = false; … … 1931 1933 //Fitter fitter = Fitter(); 1932 1934 //fitter.setExpression("cspline", nPiece); 1935 //fitter.setIterClipping(thresClip, nIterClip); 1933 1936 1934 1937 int nRow = nrow(); … … 1964 1967 1965 1968 1966 //fitBaseline(chanMask, whichrow, fitter , thresClip, nIterClip);1969 //fitBaseline(chanMask, whichrow, fitter); 1967 1970 //setSpectrum(fitter.getResidual(), whichrow); 1968 std::vector<int> piece Ranges;1971 std::vector<int> pieceEdges; 1969 1972 std::vector<float> params; 1970 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, pieceRanges, params, nPiece, thresClip, nIterClip, true);1973 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, nPiece, pieceEdges, params, thresClip, nIterClip, true); 1971 1974 setSpectrum(res, whichrow); 1972 1975 // 1973 1976 1974 std::vector<bool> fixed; 1975 fixed.clear(); 1976 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoCubicSplineBaseline()", pieceRanges, params, fixed); 1977 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoCubicSplineBaseline()", pieceEdges, params); 1977 1978 } 1978 1979 … … 1980 1981 } 1981 1982 1982 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, const std::vector<bool>& mask, std::vector<int>& idxEdge, std::vector<float>& params, int nPiece, float thresClip, int nIterClip, bool getResidual) { 1983 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, const std::vector<bool>& mask, int nPiece, std::vector<int>& idxEdge, std::vector<float>& params, float thresClip, int nIterClip, bool getResidual) 1984 { 1985 if (data.size() != mask.size()) { 1986 throw(AipsError("data and mask sizes are not identical")); 1987 } 1983 1988 if (nPiece < 1) { 1984 1989 throw(AipsError("wrong number of the sections for fitting")); 1985 }1986 if (data.size() != mask.size()) {1987 throw(AipsError("data and mask have different size"));1988 1990 } 1989 1991 … … 1998 2000 } 1999 2001 2000 int nData = x.size(); 2001 int nElement = (int)(floor(floor((double)(nData/nPiece))+0.5)); 2002 int initNData = x.size(); 2003 2004 int nElement = (int)(floor(floor((double)(initNData/nPiece))+0.5)); 2002 2005 std::vector<double> invEdge; 2003 2004 2006 idxEdge.clear(); 2005 2007 idxEdge.push_back(x[0]); 2006 2007 2008 for (int i = 1; i < nPiece; ++i) { 2008 2009 int valX = x[nElement*i]; … … 2010 2011 invEdge.push_back(1.0/(double)valX); 2011 2012 } 2012 2013 2013 idxEdge.push_back(x[x.size()-1]+1); 2014 2014 2015 std::vector<double> x1, x2, x3, z1, x1z1, x2z1, x3z1, r1; 2015 int nData = initNData; 2016 int nDOF = nPiece + 3; //number of parameters to solve, namely, 4+(nPiece-1). 2017 2018 std::vector<double> x1, x2, x3, z1, x1z1, x2z1, x3z1, r1, residual; 2016 2019 for (int i = 0; i < nChan; ++i) { 2017 2020 double di = (double)i; … … 2025 2028 x3z1.push_back(dD*di*di*di); 2026 2029 r1.push_back(0.0); 2027 } 2028 2029 int currentNData = nData; 2030 int nDOF = nPiece + 3; //number of parameters to solve, namely, 4+(nPiece-1). 2030 residual.push_back(0.0); 2031 } 2031 2032 2032 2033 for (int nClip = 0; nClip < nIterClip+1; ++nClip) { … … 2142 2143 for (int i = idxEdge[n]; i < idxEdge[n+1]; ++i) { 2143 2144 r1[i] = a0 + a1*x1[i] + a2*x2[i] + a3*x3[i]; 2145 residual[i] = z1[i] - r1[i]; 2144 2146 } 2145 2147 params.push_back(a0); … … 2161 2163 break; 2162 2164 } else { 2163 std::vector<double> rz;2164 2165 double stdDev = 0.0; 2165 2166 for (int i = 0; i < nChan; ++i) { 2166 double val = abs(r1[i] - z1[i]); 2167 rz.push_back(val); 2168 stdDev += val*val*(double)maskArray[i]; 2167 stdDev += residual[i]*residual[i]*(double)maskArray[i]; 2169 2168 } 2170 2169 stdDev = sqrt(stdDev/(double)nData); … … 2173 2172 int newNData = 0; 2174 2173 for (int i = 0; i < nChan; ++i) { 2175 if ( rz[i]>= thres) {2174 if (abs(residual[i]) >= thres) { 2176 2175 maskArray[i] = 0; 2177 2176 } … … 2180 2179 } 2181 2180 } 2182 if (newNData == currentNData) {2181 if (newNData == nData) { 2183 2182 break; //no more flag to add. iteration stops. 2184 2183 } else { 2185 currentNData = newNData;2184 nData = newNData; 2186 2185 } 2187 2186 } … … 2191 2190 if (getResidual) { 2192 2191 for (int i = 0; i < nChan; ++i) { 2193 result.push_back((float) (z1[i] - r1[i]));2192 result.push_back((float)residual[i]); 2194 2193 } 2195 2194 } else { … … 2202 2201 } 2203 2202 2204 void Scantable::sinusoidBaseline(const std::vector<bool>& mask, int nMinWavesInSW, int nMaxWavesInSW, float thresClip, int nIterClip, bool outLogger, const std::string& blfile) { 2203 void Scantable::sinusoidBaseline(const std::vector<bool>& mask, const std::vector<int>& nWaves, float maxWaveLength, float thresClip, int nIterClip, bool getResidual, bool outLogger, const std::string& blfile) 2204 { 2205 2205 ofstream ofs; 2206 String coordInfo ;2206 String coordInfo = ""; 2207 2207 bool hasSameNchan = true; 2208 2208 bool outTextFile = false; … … 2220 2220 2221 2221 //Fitter fitter = Fitter(); 2222 //fitter.setExpression("sinusoid", nMaxWavesInSW); 2222 //fitter.setExpression("sinusoid", nWaves); 2223 //fitter.setIterClipping(thresClip, nIterClip); 2223 2224 2224 2225 int nRow = nrow(); … … 2227 2228 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 2228 2229 chanMask = getCompositeChanMask(whichrow, mask); 2229 //fitBaseline(chanMask, whichrow, fitter , thresClip, nIterClip);2230 //fitBaseline(chanMask, whichrow, fitter); 2230 2231 //setSpectrum(fitter.getResidual(), whichrow); 2231 std::vector<int> pieceRanges;2232 2232 std::vector<float> params; 2233 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nMinWavesInSW, nMaxWavesInSW, params, thresClip, nIterClip, true); 2233 //std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nWaves, params, thresClip, nIterClip, true); 2234 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nWaves, maxWaveLength, params, thresClip, nIterClip, getResidual); 2234 2235 setSpectrum(res, whichrow); 2235 2236 // 2236 2237 2237 std::vector<bool> fixed; 2238 fixed.clear(); 2239 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "sinusoidBaseline()", pieceRanges, params, fixed); 2238 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "sinusoidBaseline()", params); 2240 2239 } 2241 2240 … … 2243 2242 } 2244 2243 2245 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)2244 void Scantable::autoSinusoidBaseline(const std::vector<bool>& mask, const std::vector<int>& nWaves, float maxWaveLength, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool getResidual, bool outLogger, const std::string& blfile) 2246 2245 { 2247 2246 ofstream ofs; 2248 String coordInfo ;2247 String coordInfo = ""; 2249 2248 bool hasSameNchan = true; 2250 2249 bool outTextFile = false; … … 2262 2261 2263 2262 //Fitter fitter = Fitter(); 2264 //fitter.setExpression("sinusoid", nMaxWavesInSW); 2263 //fitter.setExpression("sinusoid", nWaves); 2264 //fitter.setIterClipping(thresClip, nIterClip); 2265 2265 2266 2266 int nRow = nrow(); … … 2296 2296 2297 2297 2298 //fitBaseline(chanMask, whichrow, fitter , thresClip, nIterClip);2298 //fitBaseline(chanMask, whichrow, fitter); 2299 2299 //setSpectrum(fitter.getResidual(), whichrow); 2300 std::vector<int> pieceRanges;2301 2300 std::vector<float> params; 2302 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, n MinWavesInSW, nMaxWavesInSW, params, thresClip, nIterClip, true);2301 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nWaves, maxWaveLength, params, thresClip, nIterClip, getResidual); 2303 2302 setSpectrum(res, whichrow); 2304 2303 // 2305 2304 2306 std::vector<bool> fixed; 2307 fixed.clear(); 2308 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoSinusoidBaseline()", pieceRanges, params, fixed); 2305 outputFittingResult(outLogger, outTextFile, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoSinusoidBaseline()", params); 2309 2306 } 2310 2307 … … 2312 2309 } 2313 2310 2314 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, bool getResidual) { 2311 std::vector<float> Scantable::doSinusoidFitting(const std::vector<float>& data, const std::vector<bool>& mask, const std::vector<int>& waveNumbers, float maxWaveLength, std::vector<float>& params, float thresClip, int nIterClip, bool getResidual) 2312 { 2315 2313 if (data.size() != mask.size()) { 2316 throw(AipsError("data and mask have different size")); 2317 } 2318 if ((nMinWavesInSW < 0) || (nMaxWavesInSW < 0)) { 2314 throw(AipsError("data and mask sizes are not identical")); 2315 } 2316 if (data.size() < 2) { 2317 throw(AipsError("data size is too short")); 2318 } 2319 if (waveNumbers.size() == 0) { 2320 throw(AipsError("missing wave number info")); 2321 } 2322 std::vector<int> nWaves; // sorted and uniqued array of wave numbers 2323 nWaves.reserve(waveNumbers.size()); 2324 copy(waveNumbers.begin(), waveNumbers.end(), back_inserter(nWaves)); 2325 sort(nWaves.begin(), nWaves.end()); 2326 std::vector<int>::iterator end_it = unique(nWaves.begin(), nWaves.end()); 2327 nWaves.erase(end_it, nWaves.end()); 2328 2329 int minNWaves = nWaves[0]; 2330 if (minNWaves < 0) { 2319 2331 throw(AipsError("wave number must be positive or zero (i.e. constant)")); 2320 } else { 2321 if (nMaxWavesInSW < nMinWavesInSW) { 2322 int temp = nMaxWavesInSW; 2323 nMaxWavesInSW = nMinWavesInSW; 2324 nMinWavesInSW = temp; 2325 } 2326 } 2332 } 2333 bool hasConstantTerm = (minNWaves == 0); 2327 2334 2328 2335 int nChan = data.size(); … … 2336 2343 } 2337 2344 2338 int nData = x.size(); 2339 2340 std::vector<double> x1, x2, x3, z1, x1z1, x2z1, x3z1, r1; 2345 int initNData = x.size(); 2346 2347 int nData = initNData; 2348 int nDOF = nWaves.size() * 2 - (hasConstantTerm ? 1 : 0); //number of parameters to solve. 2349 2350 const double PI = 6.0 * asin(0.5); // PI (= 3.141592653...) 2351 double baseXFactor = 2.0*PI/(double)maxWaveLength/(double)(nChan-1); //the denominator (nChan-1) should be changed to (xdata[nChan-1]-xdata[0]) for accepting x-values given in velocity or frequency when this function is moved to fitter. 2352 2353 // xArray : contains elemental values for computing the least-square matrix. 2354 // xArray.size() is nDOF and xArray[*].size() is nChan. 2355 // Each xArray element are as follows: 2356 // xArray[0] = {1.0, 1.0, 1.0, ..., 1.0}, 2357 // xArray[2n-1] = {sin(nPI/L*x[0]), sin(nPI/L*x[1]), ..., sin(nPI/L*x[nChan])}, 2358 // xArray[2n] = {cos(nPI/L*x[0]), cos(nPI/L*x[1]), ..., cos(nPI/L*x[nChan])}, 2359 // where (1 <= n <= nMaxWavesInSW), 2360 // or, 2361 // xArray[2n-1] = {sin(wn[n]PI/L*x[0]), sin(wn[n]PI/L*x[1]), ..., sin(wn[n]PI/L*x[nChan])}, 2362 // xArray[2n] = {cos(wn[n]PI/L*x[0]), cos(wn[n]PI/L*x[1]), ..., cos(wn[n]PI/L*x[nChan])}, 2363 // where wn[n] denotes waveNumbers[n] (1 <= n <= waveNumbers.size()). 2364 std::vector<std::vector<double> > xArray; 2365 if (hasConstantTerm) { 2366 std::vector<double> xu; 2367 for (int j = 0; j < nChan; ++j) { 2368 xu.push_back(1.0); 2369 } 2370 xArray.push_back(xu); 2371 } 2372 for (uInt i = (hasConstantTerm ? 1 : 0); i < nWaves.size(); ++i) { 2373 double xFactor = baseXFactor*(double)nWaves[i]; 2374 std::vector<double> xs, xc; 2375 xs.clear(); 2376 xc.clear(); 2377 for (int j = 0; j < nChan; ++j) { 2378 xs.push_back(sin(xFactor*(double)j)); 2379 xc.push_back(cos(xFactor*(double)j)); 2380 } 2381 xArray.push_back(xs); 2382 xArray.push_back(xc); 2383 } 2384 2385 std::vector<double> z1, r1, residual; 2341 2386 for (int i = 0; i < nChan; ++i) { 2342 double di = (double)i; 2343 double dD = (double)data[i]; 2344 x1.push_back(di); 2345 x2.push_back(di*di); 2346 x3.push_back(di*di*di); 2347 z1.push_back(dD); 2348 x1z1.push_back(di*dD); 2349 x2z1.push_back(di*di*dD); 2350 x3z1.push_back(di*di*di*dD); 2387 z1.push_back((double)data[i]); 2351 2388 r1.push_back(0.0); 2352 } 2353 2354 int currentNData = nData; 2355 int nDOF = nMaxWavesInSW + 1; //number of parameters to solve. 2389 residual.push_back(0.0); 2390 } 2356 2391 2357 2392 for (int nClip = 0; nClip < nIterClip+1; ++nClip) { 2358 //xMatrix : horizontal concatenation of the least-sq. matrix (left) and an 2359 //identity matrix (right). 2360 //the right part is used to calculate the inverse matrix of the left part. 2393 // xMatrix : horizontal concatenation of 2394 // the least-sq. matrix (left) and an 2395 // identity matrix (right). 2396 // the right part is used to calculate the inverse matrix of the left part. 2361 2397 double xMatrix[nDOF][2*nDOF]; 2362 2398 double zMatrix[nDOF]; … … 2369 2405 } 2370 2406 2371 for (int i = 0; i < currentNData; ++i) { 2372 if (maskArray[i] == 0) continue; 2373 xMatrix[0][0] += 1.0; 2374 xMatrix[0][1] += x1[i]; 2375 xMatrix[0][2] += x2[i]; 2376 xMatrix[0][3] += x3[i]; 2377 xMatrix[1][1] += x2[i]; 2378 xMatrix[1][2] += x3[i]; 2379 xMatrix[1][3] += x2[i]*x2[i]; 2380 xMatrix[2][2] += x2[i]*x2[i]; 2381 xMatrix[2][3] += x3[i]*x2[i]; 2382 xMatrix[3][3] += x3[i]*x3[i]; 2383 zMatrix[0] += z1[i]; 2384 zMatrix[1] += x1z1[i]; 2385 zMatrix[2] += x2z1[i]; 2386 zMatrix[3] += x3z1[i]; 2407 for (int k = 0; k < nChan; ++k) { 2408 if (maskArray[k] == 0) continue; 2409 2410 for (int i = 0; i < nDOF; ++i) { 2411 for (int j = i; j < nDOF; ++j) { 2412 xMatrix[i][j] += xArray[i][k] * xArray[j][k]; 2413 } 2414 zMatrix[i] += z1[k] * xArray[i][k]; 2415 } 2387 2416 } 2388 2417 … … 2425 2454 } 2426 2455 //compute a vector y which consists of the coefficients of the sinusoids forming the 2427 //best-fit curves (a0, b0,a1,b1,...), namely, a* and b* are of sine and cosine functions,2428 // respectively.2456 //best-fit curves (a0,s1,c1,s2,c2,...), where a0 is constant and s* and c* are of sine 2457 //and cosine functions, respectively. 2429 2458 std::vector<double> y; 2459 params.clear(); 2430 2460 for (int i = 0; i < nDOF; ++i) { 2431 2461 y.push_back(0.0); … … 2433 2463 y[i] += xMatrix[i][nDOF+j]*zMatrix[j]; 2434 2464 } 2435 } 2436 2437 double a0 = y[0]; 2438 double a1 = y[1]; 2439 double a2 = y[2]; 2440 double a3 = y[3]; 2441 params.clear(); 2465 params.push_back(y[i]); 2466 } 2442 2467 2443 2468 for (int i = 0; i < nChan; ++i) { 2444 r1[i] = a0 + a1*x1[i] + a2*x2[i] + a3*x3[i]; 2445 } 2446 params.push_back(a0); 2447 params.push_back(a1); 2448 params.push_back(a2); 2449 params.push_back(a3); 2450 2469 r1[i] = y[0]; 2470 for (int j = 1; j < nDOF; ++j) { 2471 r1[i] += y[j]*xArray[j][i]; 2472 } 2473 residual[i] = z1[i] - r1[i]; 2474 } 2451 2475 2452 2476 if ((nClip == nIterClip) || (thresClip <= 0.0)) { 2453 2477 break; 2454 2478 } else { 2455 std::vector<double> rz;2456 2479 double stdDev = 0.0; 2457 2480 for (int i = 0; i < nChan; ++i) { 2458 double val = abs(r1[i] - z1[i]); 2459 rz.push_back(val); 2460 stdDev += val*val*(double)maskArray[i]; 2481 stdDev += residual[i]*residual[i]*(double)maskArray[i]; 2461 2482 } 2462 2483 stdDev = sqrt(stdDev/(double)nData); … … 2465 2486 int newNData = 0; 2466 2487 for (int i = 0; i < nChan; ++i) { 2467 if ( rz[i]>= thres) {2488 if (abs(residual[i]) >= thres) { 2468 2489 maskArray[i] = 0; 2469 2490 } … … 2472 2493 } 2473 2494 } 2474 if (newNData == currentNData) {2475 break; //no additional flag. finish iteration.2495 if (newNData == nData) { 2496 break; //no more flag to add. iteration stops. 2476 2497 } else { 2477 currentNData = newNData;2498 nData = newNData; 2478 2499 } 2479 2500 } … … 2483 2504 if (getResidual) { 2484 2505 for (int i = 0; i < nChan; ++i) { 2485 result.push_back((float) (z1[i] - r1[i]));2506 result.push_back((float)residual[i]); 2486 2507 } 2487 2508 } else { … … 2496 2517 void Scantable::fitBaseline(const std::vector<bool>& mask, int whichrow, Fitter& fitter) 2497 2518 { 2498 std::vector<double> abcsd= getAbcissa(whichrow);2499 std::vector<float> abc s;2500 for (uInt i = 0; i < abcsd.size(); ++i) {2501 abc s.push_back((float)abcsd[i]);2519 std::vector<double> dAbcissa = getAbcissa(whichrow); 2520 std::vector<float> abcissa; 2521 for (uInt i = 0; i < dAbcissa.size(); ++i) { 2522 abcissa.push_back((float)dAbcissa[i]); 2502 2523 } 2503 2524 std::vector<float> spec = getSpectrum(whichrow); 2504 2525 2505 fitter.setData(abc s, spec, mask);2526 fitter.setData(abcissa, spec, mask); 2506 2527 fitter.lfit(); 2507 2528 } … … 2566 2587 2567 2588 /* for cspline. will be merged once cspline is available in fitter (2011/3/10 WK) */ 2568 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>& edge, const std::vector<float>& params , const std::vector<bool>& fixed) {2589 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>& edge, const std::vector<float>& params) { 2569 2590 if (outLogger || outTextFile) { 2570 2591 float rms = getRms(chanMask, whichrow); 2571 2592 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan); 2593 std::vector<bool> fixed; 2594 fixed.clear(); 2572 2595 2573 2596 if (outLogger) { … … 2582 2605 2583 2606 /* for sinusoid. will be merged once sinusoid is available in fitter (2011/3/10 WK) */ 2584 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) {2607 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) { 2585 2608 if (outLogger || outTextFile) { 2586 2609 float rms = getRms(chanMask, whichrow); 2587 2610 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan); 2611 std::vector<bool> fixed; 2612 fixed.clear(); 2588 2613 2589 2614 if (outLogger) { -
trunk/src/Scantable.h
r2064 r2081 522 522 const std::string& blfile=""); 523 523 void sinusoidBaseline(const std::vector<bool>& mask, 524 int nMinWavesInSW,525 int nMaxWavesInSW,524 const std::vector<int>& nWaves, 525 float maxWaveLength, 526 526 float thresClip, 527 527 int nIterClip, 528 bool getResidual=true, 528 529 bool outLogger=false, 529 530 const std::string& blfile=""); 530 531 void autoSinusoidBaseline(const std::vector<bool>& mask, 531 int nMinWavesInSW,532 int nMaxWavesInSW,532 const std::vector<int>& nWaves, 533 float maxWaveLength, 533 534 float thresClip, 534 535 int nIterClip, … … 536 537 float threshold=3.0, 537 538 int chanAvgLimit=1, 539 bool getResidual=true, 538 540 bool outLogger=false, 539 541 const std::string& blfile=""); … … 672 674 std::vector<float> doCubicSplineFitting(const std::vector<float>& data, 673 675 const std::vector<bool>& mask, 676 int nPiece, 674 677 std::vector<int>& idxEdge, 675 678 std::vector<float>& params, 676 int nPiece=2,677 679 float thresClip=3.0, 678 680 int nIterClip=1, … … 680 682 std::vector<float> doSinusoidFitting(const std::vector<float>& data, 681 683 const std::vector<bool>& mask, 682 int nMinWavesInSW,683 int nMaxWavesInSW,684 const std::vector<int>& waveNumbers, 685 float maxWaveLength, 684 686 std::vector<float>& params, 685 687 float thresClip=3.0, … … 698 700 //std::vector<bool> getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, const int minEdgeSize, STLineFinder& lineFinder); 699 701 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); 700 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>& edge, const std::vector<float>& params , const std::vector<bool>& fixed);701 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);702 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>& edge, const std::vector<float>& params); 703 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); 702 704 703 705 void applyChanFlag( casa::uInt whichrow, const std::vector<bool>& msk, casa::uChar flagval); -
trunk/src/ScantableWrapper.h
r2047 r2081 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); }271 void sinusoidBaseline(const std::vector<bool>& mask, const std::vector<int>& nwave, float maxwavelength, float clipthresh, int clipniter, bool getresidual=true, bool outlog=false, const std::string& blfile="") 272 { table_->sinusoidBaseline(mask, nwave, maxwavelength, clipthresh, clipniter, getresidual, outlog, blfile); } 273 274 void autoSinusoidBaseline(const std::vector<bool>& mask, const std::vector<int>& nwave, float maxwavelength, float clipthresh, int clipniter, const std::vector<int>& edge, float threshold=5.0, int chan_avg_limit=1, bool getresidual=true, bool outlog=false, const std::string& blfile="") 275 { table_->autoSinusoidBaseline(mask, nwave, maxwavelength, clipthresh, clipniter, edge, threshold, chan_avg_limit, getresidual, outlog, blfile); } 276 276 277 277 float getRms(const std::vector<bool>& mask, int whichrow)
Note:
See TracChangeset
for help on using the changeset viewer.