Changeset 2012 for trunk/src/Scantable.cpp
- Timestamp:
- 02/25/11 16:51:50 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/Scantable.cpp
r2005 r2012 67 67 #include "STPolStokes.h" 68 68 #include "STAttr.h" 69 #include "STLineFinder.h" 69 70 #include "MathUtils.h" 70 71 … … 1217 1218 } 1218 1219 **/ 1220 1219 1221 void Scantable::setRestFrequencies( const vector<std::string>& name ) 1220 1222 { … … 1749 1751 Vector<uChar> flags; 1750 1752 flagsCol_.get(uInt(whichrow), flags); 1751 for (int i = 0; i < flags.size(); i++) { 1752 if (i==0) { 1753 flag = flags[i]; 1754 } 1755 else { 1756 flag &= flags[i]; 1757 } 1758 return ((flag >> 7) == 1); 1759 } 1760 } 1761 1762 void Scantable::doPolyBaseline(const std::vector<bool>& mask, int order, int rowno, Fitter& fitter) 1763 { 1753 flag = flags[0]; 1754 for (int i = 1; i < flags.size(); ++i) { 1755 flag &= flags[i]; 1756 } 1757 return ((flag >> 7) == 1); 1758 } 1759 1760 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, bool outLogger, const std::string& blfile) { 1761 ofstream ofs; 1762 String coordInfo; 1763 bool hasSameNchan; 1764 int firstIF; 1765 bool outTextFile = false; 1766 1767 if (blfile != "") { 1768 ofs.open(blfile.c_str(), ios::out | ios::app); 1769 if (ofs) outTextFile = true; 1770 } 1771 1772 if (outLogger || outTextFile) { 1773 coordInfo = getCoordInfo()[0]; 1774 if (coordInfo == "") coordInfo = "channel"; 1775 hasSameNchan = hasSameNchanOverIFs(); 1776 firstIF = getIF(0); 1777 } 1778 1779 //Fitter fitter = Fitter(); 1780 //fitter.setExpression("cspline", nPiece, thresClip, nIterClip); 1781 1782 int nRow = nrow(); 1783 std::vector<bool> chanMask; 1784 1785 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 1786 1787 chanMask = getCompositeChanMask(whichrow, mask); 1788 //fitBaseline(chanMask, whichrow, fitter); 1789 //setSpectrum(fitter.getResidual(), whichrow); 1790 std::vector<int> pieceRanges; 1791 std::vector<float> params; 1792 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, pieceRanges, params, nPiece, thresClip, nIterClip); 1793 setSpectrum(res, whichrow); 1794 1795 if (outLogger || outTextFile) { 1796 std::vector<bool> fixed; 1797 fixed.clear(); 1798 float rms = getRms(chanMask, whichrow); 1799 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 1800 1801 if (outLogger) { 1802 LogIO ols(LogOrigin("Scantable", "cubicSplineBaseline()", WHERE)); 1803 ols << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 1804 } 1805 if (outTextFile) { 1806 ofs << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, true) << flush; 1807 } 1808 } 1809 1810 } 1811 1812 if (outTextFile) ofs.close(); 1813 } 1814 1815 1816 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) 1817 { 1818 ofstream ofs; 1819 String coordInfo; 1820 bool hasSameNchan; 1821 int firstIF; 1822 bool outTextFile = false; 1823 1824 if (blfile != "") { 1825 ofs.open(blfile.c_str(), ios::out | ios::app); 1826 if (ofs) outTextFile = true; 1827 } 1828 1829 if (outLogger || outTextFile) { 1830 coordInfo = getCoordInfo()[0]; 1831 if (coordInfo == "") coordInfo = "channel"; 1832 hasSameNchan = hasSameNchanOverIFs(); 1833 firstIF = getIF(0); 1834 } 1835 1836 //Fitter fitter = Fitter(); 1837 //fitter.setExpression("cspline", nPiece, thresClip, nIterClip); 1838 1839 int nRow = nrow(); 1840 std::vector<bool> chanMask; 1841 int minEdgeSize = getIFNos().size()*2; 1842 STLineFinder lineFinder = STLineFinder(); 1843 lineFinder.setOptions(threshold, 3, chanAvgLimit); 1844 1845 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 1846 1847 //------------------------------------------------------- 1848 //chanMask = getCompositeChanMask(whichrow, mask, edge, minEdgeSize, lineFinder); 1849 //------------------------------------------------------- 1850 int edgeSize = edge.size(); 1851 std::vector<int> currentEdge; 1852 if (edgeSize >= 2) { 1853 int idx = 0; 1854 if (edgeSize > 2) { 1855 if (edgeSize < minEdgeSize) { 1856 throw(AipsError("Length of edge element info is less than that of IFs")); 1857 } 1858 idx = 2 * getIF(whichrow); 1859 } 1860 currentEdge.push_back(edge[idx]); 1861 currentEdge.push_back(edge[idx+1]); 1862 } else { 1863 throw(AipsError("Wrong length of edge element")); 1864 } 1865 lineFinder.setData(getSpectrum(whichrow)); 1866 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 1867 chanMask = lineFinder.getMask(); 1868 //------------------------------------------------------- 1869 1870 1871 //fitBaseline(chanMask, whichrow, fitter); 1872 //setSpectrum(fitter.getResidual(), whichrow); 1873 std::vector<int> pieceRanges; 1874 std::vector<float> params; 1875 std::vector<float> res = doCubicSplineFitting(getSpectrum(whichrow), chanMask, pieceRanges, params, nPiece, thresClip, nIterClip); 1876 setSpectrum(res, whichrow); 1877 1878 if (outLogger || outTextFile) { 1879 std::vector<bool> fixed; 1880 fixed.clear(); 1881 float rms = getRms(chanMask, whichrow); 1882 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 1883 1884 if (outLogger) { 1885 LogIO ols(LogOrigin("Scantable", "autoCubicSplineBaseline()", WHERE)); 1886 ols << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 1887 } 1888 if (outTextFile) { 1889 ofs << formatPiecewiseBaselineParams(pieceRanges, params, fixed, rms, masklist, whichrow, true) << flush; 1890 } 1891 } 1892 1893 } 1894 1895 if (outTextFile) ofs.close(); 1896 } 1897 1898 1899 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) { 1900 if (nPiece < 1) { 1901 throw(AipsError("wrong number of the sections for fitting")); 1902 } 1903 if (data.size() != mask.size()) { 1904 throw(AipsError("data and mask have different size")); 1905 } 1906 1907 int nChan = data.size(); 1908 std::vector<int> maskArray; 1909 std::vector<int> x; 1910 for (int i = 0; i < nChan; ++i) { 1911 maskArray.push_back(mask[i] ? 1 : 0); 1912 if (mask[i]) { 1913 x.push_back(i); 1914 } 1915 } 1916 1917 int nData = x.size(); 1918 int nElement = (int)(floor(floor((double)(nData/nPiece))+0.5)); 1919 1920 std::vector<double> sectionList0, sectionList1, sectionListR; 1921 sectionList0.push_back((double)x[0]); 1922 sectionRanges.clear(); 1923 sectionRanges.push_back(x[0]); 1924 for (int i = 1; i < nPiece; ++i) { 1925 double valX = (double)x[nElement*i]; 1926 sectionList0.push_back(valX); 1927 sectionList1.push_back(valX); 1928 sectionListR.push_back(1.0/valX); 1929 1930 sectionRanges.push_back(x[nElement*i]-1); 1931 sectionRanges.push_back(x[nElement*i]); 1932 } 1933 sectionList1.push_back((double)(x[x.size()-1]+1)); 1934 sectionRanges.push_back(x[x.size()-1]); 1935 1936 std::vector<double> x1, x2, x3, z1, x1z1, x2z1, x3z1, r1; 1937 for (int i = 0; i < nChan; ++i) { 1938 x1.push_back((double)i); 1939 x2.push_back((double)(i*i)); 1940 x3.push_back((double)(i*i*i)); 1941 z1.push_back((double)data[i]); 1942 x1z1.push_back(((double)i)*(double)data[i]); 1943 x2z1.push_back(((double)(i*i))*(double)data[i]); 1944 x3z1.push_back(((double)(i*i*i))*(double)data[i]); 1945 r1.push_back(0.0); 1946 } 1947 1948 int currentNData = nData; 1949 int nDOF = nPiece + 3; //number of parameters to solve, namely, 4+(nPiece-1). 1950 1951 for (int nClip = 0; nClip < nIterClip+1; ++nClip) { 1952 //xMatrix : horizontal concatenation of the least-sq. matrix (left) and an 1953 //identity matrix (right). 1954 //the right part is used to calculate the inverse matrix of the left part. 1955 double xMatrix[nDOF][2*nDOF]; 1956 double zMatrix[nDOF]; 1957 for (int i = 0; i < nDOF; ++i) { 1958 for (int j = 0; j < 2*nDOF; ++j) { 1959 xMatrix[i][j] = 0.0; 1960 } 1961 xMatrix[i][nDOF+i] = 1.0; 1962 zMatrix[i] = 0.0; 1963 } 1964 1965 for (int n = 0; n < nPiece; ++n) { 1966 for (int i = sectionList0[n]; i < sectionList1[n]; ++i) { 1967 if (maskArray[i] == 0) continue; 1968 xMatrix[0][0] += 1.0; 1969 xMatrix[0][1] += x1[i]; 1970 xMatrix[0][2] += x2[i]; 1971 xMatrix[0][3] += x3[i]; 1972 xMatrix[1][1] += x2[i]; 1973 xMatrix[1][2] += x3[i]; 1974 xMatrix[1][3] += x2[i]*x2[i]; 1975 xMatrix[2][2] += x2[i]*x2[i]; 1976 xMatrix[2][3] += x3[i]*x2[i]; 1977 xMatrix[3][3] += x3[i]*x3[i]; 1978 zMatrix[0] += z1[i]; 1979 zMatrix[1] += x1z1[i]; 1980 zMatrix[2] += x2z1[i]; 1981 zMatrix[3] += x3z1[i]; 1982 for (int j = 0; j < n; ++j) { 1983 double q = 1.0 - x1[i]*sectionListR[j]; 1984 q = q*q*q; 1985 xMatrix[0][j+4] += q; 1986 xMatrix[1][j+4] += q*x1[i]; 1987 xMatrix[2][j+4] += q*x2[i]; 1988 xMatrix[3][j+4] += q*x3[i]; 1989 for (int k = 0; k < j; ++k) { 1990 double r = 1.0 - x1[i]*sectionListR[k]; 1991 r = r*r*r; 1992 xMatrix[k+4][j+4] += r*q; 1993 } 1994 xMatrix[j+4][j+4] += q*q; 1995 zMatrix[j+4] += q*z1[i]; 1996 } 1997 } 1998 } 1999 2000 for (int i = 0; i < nDOF; ++i) { 2001 for (int j = 0; j < i; ++j) { 2002 xMatrix[i][j] = xMatrix[j][i]; 2003 } 2004 } 2005 2006 std::vector<double> invDiag; 2007 for (int i = 0; i < nDOF; ++i) { 2008 invDiag.push_back(1.0/xMatrix[i][i]); 2009 for (int j = 0; j < nDOF; ++j) { 2010 xMatrix[i][j] *= invDiag[i]; 2011 } 2012 } 2013 2014 for (int k = 0; k < nDOF; ++k) { 2015 for (int i = 0; i < nDOF; ++i) { 2016 if (i != k) { 2017 double factor1 = xMatrix[k][k]; 2018 double factor2 = xMatrix[i][k]; 2019 for (int j = k; j < 2*nDOF; ++j) { 2020 xMatrix[i][j] *= factor1; 2021 xMatrix[i][j] -= xMatrix[k][j]*factor2; 2022 xMatrix[i][j] /= factor1; 2023 } 2024 } 2025 } 2026 double xDiag = xMatrix[k][k]; 2027 for (int j = k; j < 2*nDOF; ++j) { 2028 xMatrix[k][j] /= xDiag; 2029 } 2030 } 2031 2032 for (int i = 0; i < nDOF; ++i) { 2033 for (int j = 0; j < nDOF; ++j) { 2034 xMatrix[i][nDOF+j] *= invDiag[j]; 2035 } 2036 } 2037 //compute a vector y which consists of the coefficients of the best-fit spline curves 2038 //(a0,a1,a2,a3(,b3,c3,...)), namely, the ones for the leftmost piece and the ones of 2039 //cubic terms for the other pieces (in case nPiece>1). 2040 std::vector<double> y; 2041 for (int i = 0; i < nDOF; ++i) { 2042 y.push_back(0.0); 2043 for (int j = 0; j < nDOF; ++j) { 2044 y[i] += xMatrix[i][nDOF+j]*zMatrix[j]; 2045 } 2046 } 2047 2048 double a0 = y[0]; 2049 double a1 = y[1]; 2050 double a2 = y[2]; 2051 double a3 = y[3]; 2052 params.clear(); 2053 2054 for (int n = 0; n < nPiece; ++n) { 2055 for (int i = sectionList0[n]; i < sectionList1[n]; ++i) { 2056 r1[i] = a0 + a1*x1[i] + a2*x2[i] + a3*x3[i]; 2057 } 2058 params.push_back(a0); 2059 params.push_back(a1); 2060 params.push_back(a2); 2061 params.push_back(a3); 2062 2063 if (n == nPiece-1) break; 2064 2065 double d = y[4+n]; 2066 a0 += d; 2067 a1 -= 3.0*d*sectionListR[n]; 2068 a2 += 3.0*d*sectionListR[n]*sectionListR[n]; 2069 a3 -= d*sectionListR[n]*sectionListR[n]*sectionListR[n]; 2070 } 2071 2072 if ((nClip == nIterClip) || (thresClip <= 0.0)) { 2073 break; 2074 } else { 2075 std::vector<double> rz; 2076 double stdDev = 0.0; 2077 for (int i = 0; i < nChan; ++i) { 2078 double val = abs(r1[i] - z1[i]); 2079 rz.push_back(val); 2080 stdDev += val*val*(double)maskArray[i]; 2081 } 2082 stdDev = sqrt(stdDev/(double)nData); 2083 2084 double thres = stdDev * thresClip; 2085 int newNData = 0; 2086 for (int i = 0; i < nChan; ++i) { 2087 if (rz[i] >= thres) { 2088 maskArray[i] = 0; 2089 } 2090 if (maskArray[i] > 0) { 2091 newNData++; 2092 } 2093 } 2094 if (newNData == currentNData) { 2095 break; //no additional flag. finish iteration. 2096 } else { 2097 currentNData = newNData; 2098 } 2099 } 2100 } 2101 2102 std::vector<float> residual; 2103 for (int i = 0; i < nChan; ++i) { 2104 residual.push_back((float)(z1[i] - r1[i])); 2105 } 2106 return residual; 2107 2108 } 2109 2110 void Scantable::fitBaseline(const std::vector<bool>& mask, int whichrow, Fitter& fitter) 2111 { 2112 std::vector<double> abcsd = getAbcissa(whichrow); 2113 std::vector<float> abcs; 2114 for (int i = 0; i < abcsd.size(); ++i) { 2115 abcs.push_back((float)abcsd[i]); 2116 } 2117 std::vector<float> spec = getSpectrum(whichrow); 2118 2119 fitter.setData(abcs, spec, mask); 2120 fitter.lfit(); 2121 } 2122 2123 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask) 2124 { 2125 std::vector<bool> chanMask = getMask(whichrow); 2126 int chanMaskSize = chanMask.size(); 2127 if (chanMaskSize != inMask.size()) { 2128 throw(AipsError("different mask sizes")); 2129 } 2130 for (int i = 0; i < chanMaskSize; ++i) { 2131 chanMask[i] = chanMask[i] && inMask[i]; 2132 } 2133 2134 return chanMask; 2135 } 2136 2137 /* 2138 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, const int minEdgeSize, STLineFinder& lineFinder) 2139 { 2140 int edgeSize = edge.size(); 2141 std::vector<int> currentEdge; 2142 if (edgeSize >= 2) { 2143 int idx = 0; 2144 if (edgeSize > 2) { 2145 if (edgeSize < minEdgeSize) { 2146 throw(AipsError("Length of edge element info is less than that of IFs")); 2147 } 2148 idx = 2 * getIF(whichrow); 2149 } 2150 currentEdge.push_back(edge[idx]); 2151 currentEdge.push_back(edge[idx+1]); 2152 } else { 2153 throw(AipsError("Wrong length of edge element")); 2154 } 2155 2156 lineFinder.setData(getSpectrum(whichrow)); 2157 lineFinder.findLines(getCompositeChanMask(whichrow, inMask), currentEdge, whichrow); 2158 2159 return lineFinder.getMask(); 2160 } 2161 */ 2162 2163 void Scantable::polyBaseline(const std::vector<bool>& mask, int order, bool outLogger, const std::string& blfile) 2164 { 2165 ofstream ofs; 2166 String coordInfo; 2167 bool hasSameNchan; 2168 int firstIF; 2169 bool outTextFile = false; 2170 2171 if (blfile != "") { 2172 ofs.open(blfile.c_str(), ios::out | ios::app); 2173 if (ofs) outTextFile = true; 2174 } 2175 2176 if (outLogger || outTextFile) { 2177 coordInfo = getCoordInfo()[0]; 2178 if (coordInfo == "") coordInfo = "channel"; 2179 hasSameNchan = hasSameNchanOverIFs(); 2180 firstIF = getIF(0); 2181 } 2182 2183 Fitter fitter = Fitter(); 1764 2184 fitter.setExpression("poly", order); 1765 2185 1766 std::vector<double> abcsd = getAbcissa(rowno); 1767 std::vector<float> abcs; 1768 for (int i = 0; i < abcsd.size(); i++) { 1769 abcs.push_back((float)abcsd[i]); 1770 } 1771 std::vector<float> spec = getSpectrum(rowno); 2186 int nRow = nrow(); 2187 std::vector<bool> chanMask; 2188 2189 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 2190 2191 chanMask = getCompositeChanMask(whichrow, mask); 2192 fitBaseline(chanMask, whichrow, fitter); 2193 setSpectrum(fitter.getResidual(), whichrow); 2194 2195 if (outLogger || outTextFile) { 2196 std::vector<float> params = fitter.getParameters(); 2197 std::vector<bool> fixed = fitter.getFixedParameters(); 2198 float rms = getRms(chanMask, whichrow); 2199 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 2200 2201 if (outLogger) { 2202 LogIO ols(LogOrigin("Scantable", "polyBaseline()", WHERE)); 2203 ols << formatBaselineParams(params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 2204 } 2205 if (outTextFile) { 2206 ofs << formatBaselineParams(params, fixed, rms, masklist, whichrow, true) << flush; 2207 } 2208 } 2209 2210 } 2211 2212 if (outTextFile) ofs.close(); 2213 } 2214 2215 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) 2216 { 2217 ofstream ofs; 2218 String coordInfo; 2219 bool hasSameNchan; 2220 int firstIF; 2221 bool outTextFile = false; 2222 2223 if (blfile != "") { 2224 ofs.open(blfile.c_str(), ios::out | ios::app); 2225 if (ofs) outTextFile = true; 2226 } 2227 2228 if (outLogger || outTextFile) { 2229 coordInfo = getCoordInfo()[0]; 2230 if (coordInfo == "") coordInfo = "channel"; 2231 hasSameNchan = hasSameNchanOverIFs(); 2232 firstIF = getIF(0); 2233 } 2234 2235 Fitter fitter = Fitter(); 2236 fitter.setExpression("poly", order); 2237 2238 int nRow = nrow(); 2239 std::vector<bool> chanMask; 2240 int minEdgeSize = getIFNos().size()*2; 2241 STLineFinder lineFinder = STLineFinder(); 2242 lineFinder.setOptions(threshold, 3, chanAvgLimit); 2243 2244 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 2245 2246 //------------------------------------------------------- 2247 //chanMask = getCompositeChanMask(whichrow, mask, edge, minEdgeSize, lineFinder); 2248 //------------------------------------------------------- 2249 int edgeSize = edge.size(); 2250 std::vector<int> currentEdge; 2251 if (edgeSize >= 2) { 2252 int idx = 0; 2253 if (edgeSize > 2) { 2254 if (edgeSize < minEdgeSize) { 2255 throw(AipsError("Length of edge element info is less than that of IFs")); 2256 } 2257 idx = 2 * getIF(whichrow); 2258 } 2259 currentEdge.push_back(edge[idx]); 2260 currentEdge.push_back(edge[idx+1]); 2261 } else { 2262 throw(AipsError("Wrong length of edge element")); 2263 } 2264 lineFinder.setData(getSpectrum(whichrow)); 2265 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 2266 chanMask = lineFinder.getMask(); 2267 //------------------------------------------------------- 2268 2269 2270 fitBaseline(chanMask, whichrow, fitter); 2271 setSpectrum(fitter.getResidual(), whichrow); 2272 2273 if (outLogger || outTextFile) { 2274 std::vector<float> params = fitter.getParameters(); 2275 std::vector<bool> fixed = fitter.getFixedParameters(); 2276 float rms = getRms(chanMask, whichrow); 2277 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan, firstIF, true); 2278 2279 if (outLogger) { 2280 LogIO ols(LogOrigin("Scantable", "autoPolyBaseline()", WHERE)); 2281 ols << formatBaselineParams(params, fixed, rms, masklist, whichrow, false) << LogIO::POST ; 2282 } 2283 if (outTextFile) { 2284 ofs << formatBaselineParams(params, fixed, rms, masklist, whichrow, true) << flush; 2285 } 2286 } 2287 2288 } 2289 2290 if (outTextFile) ofs.close(); 2291 } 2292 2293 2294 float Scantable::getRms(const std::vector<bool>& mask, int whichrow) { 2295 Vector<Float> spec; 2296 specCol_.get(whichrow, spec); 2297 2298 float mean = 0.0; 2299 float smean = 0.0; 2300 int n = 0; 2301 for (int i = 0; i < spec.nelements(); ++i) { 2302 if (mask[i]) { 2303 mean += spec[i]; 2304 smean += spec[i]*spec[i]; 2305 n++; 2306 } 2307 } 2308 2309 mean /= (float)n; 2310 smean /= (float)n; 2311 2312 return sqrt(smean - mean*mean); 2313 } 2314 2315 2316 std::string Scantable::formatBaselineParamsHeader(int whichrow, const std::string& masklist, bool verbose) const 2317 { 2318 ostringstream oss; 2319 2320 if (verbose) { 2321 for (int i = 0; i < 60; ++i) { 2322 oss << "-"; 2323 } 2324 oss << endl; 2325 oss << " Scan[" << getScan(whichrow) << "]"; 2326 oss << " Beam[" << getBeam(whichrow) << "]"; 2327 oss << " IF[" << getIF(whichrow) << "]"; 2328 oss << " Pol[" << getPol(whichrow) << "]"; 2329 oss << " Cycle[" << getCycle(whichrow) << "]: " << endl; 2330 oss << "Fitter range = " << masklist << endl; 2331 oss << "Baseline parameters" << endl; 2332 oss << flush; 2333 } 2334 2335 return String(oss); 2336 } 2337 2338 std::string Scantable::formatBaselineParamsFooter(float rms, bool verbose) const 2339 { 2340 ostringstream oss; 2341 2342 if (verbose) { 2343 oss << endl; 2344 oss << "Results of baseline fit" << endl; 2345 oss << " rms = " << setprecision(6) << rms << endl; 2346 } 2347 2348 return String(oss); 2349 } 2350 2351 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 2352 { 2353 ostringstream oss; 2354 oss << formatBaselineParamsHeader(whichrow, masklist, verbose); 2355 2356 if ((params.size() > 0) && (ranges.size() > 0)) { 2357 if (((ranges.size() % 2) == 0) && ((params.size() % (ranges.size() / 2)) == 0)) { 2358 int nParam = params.size() / (ranges.size() / 2); 2359 for (uInt j = 0; j < ranges.size(); j+=2) { 2360 oss << "[" << ranges[j] << "," << ranges[j+1] << "]"; 2361 for (uInt i = 0; i < nParam; ++i) { 2362 if (i > 0) { 2363 oss << ","; 2364 } 2365 String fix = ((fixed.size() > 0) && (fixed[i]) && verbose) ? "(fixed)" : ""; 2366 oss << " p" << i << fix << "= " << setprecision(6) << params[j/2*nParam+i]; 2367 } 2368 } 2369 } else { 2370 oss << " "; 2371 } 2372 } else { 2373 oss << " Not fitted"; 2374 } 2375 2376 oss << formatBaselineParamsFooter(rms, verbose); 2377 oss << flush; 2378 2379 return String(oss); 2380 } 2381 2382 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 2383 { 2384 ostringstream oss; 2385 oss << formatBaselineParamsHeader(whichrow, masklist, verbose); 2386 2387 if (params.size() > 0) { 2388 for (uInt i = 0; i < params.size(); ++i) { 2389 if (i > 0) { 2390 oss << ","; 2391 } 2392 String fix = ((fixed.size() > 0) && (fixed[i]) && verbose) ? "(fixed)" : ""; 2393 oss << " p" << i << fix << "= " << setprecision(6) << params[i]; 2394 } 2395 } else { 2396 oss << " Not fitted"; 2397 } 2398 2399 oss << formatBaselineParamsFooter(rms, verbose); 2400 oss << flush; 2401 2402 return String(oss); 2403 } 2404 2405 std::string Scantable::getMaskRangeList(const std::vector<bool>& mask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, int firstIF, bool silent) 2406 { 2407 if (mask.size() < 2) { 2408 throw(AipsError("The mask elements should be > 1")); 2409 } 2410 if (mask.size() != nchan()) { 2411 throw(AipsError("Number of channels in scantable != number of mask elements")); 2412 } 2413 2414 std::vector<int> startIdx = getMaskEdgeIndices(mask, true); 2415 std::vector<int> endIdx = getMaskEdgeIndices(mask, false); 2416 2417 if (startIdx.size() != endIdx.size()) { 2418 throw(AipsError("Numbers of mask start and mask end are not identical")); 2419 } 2420 for (int i = 0; i < startIdx.size(); ++i) { 2421 if (startIdx[i] > endIdx[i]) { 2422 throw(AipsError("Mask start index > mask end index")); 2423 } 2424 } 2425 2426 if (!silent) { 2427 LogIO logOs(LogOrigin("Scantable", "getMaskRangeList()", WHERE)); 2428 logOs << LogIO::WARN << "The current mask window unit is " << coordInfo; 2429 if (!hasSameNchan) { 2430 logOs << endl << "This mask is only valid for IF=" << firstIF; 2431 } 2432 logOs << LogIO::POST; 2433 } 2434 2435 std::vector<double> abcissa = getAbcissa(whichrow); 2436 ostringstream oss; 2437 oss.setf(ios::fixed); 2438 oss << setprecision(1) << "["; 2439 for (int i = 0; i < startIdx.size(); ++i) { 2440 std::vector<float> aMaskRange; 2441 aMaskRange.push_back((float)abcissa[startIdx[i]]); 2442 aMaskRange.push_back((float)abcissa[endIdx[i]]); 2443 sort(aMaskRange.begin(), aMaskRange.end()); 2444 if (i > 0) oss << ","; 2445 oss << "[" << aMaskRange[0] << "," << aMaskRange[1] << "]"; 2446 } 2447 oss << "]" << flush; 2448 2449 return String(oss); 2450 } 2451 2452 bool Scantable::hasSameNchanOverIFs() 2453 { 2454 int nIF = nif(-1); 2455 int nCh; 2456 int totalPositiveNChan = 0; 2457 int nPositiveNChan = 0; 2458 2459 for (int i = 0; i < nIF; ++i) { 2460 nCh = nchan(i); 2461 if (nCh > 0) { 2462 totalPositiveNChan += nCh; 2463 nPositiveNChan++; 2464 } 2465 } 2466 2467 return (totalPositiveNChan == (nPositiveNChan * nchan(0))); 2468 } 2469 2470 std::vector<int> Scantable::getMaskEdgeIndices(const std::vector<bool>& mask, bool getStartIndices) 2471 { 2472 if (mask.size() < 2) { 2473 throw(AipsError("The mask elements should be > 1")); 2474 } 2475 if (mask.size() != nchan()) { 2476 throw(AipsError("Number of channels in scantable != number of mask elements")); 2477 } 2478 2479 std::vector<int> out; 2480 int endIdx = mask.size() - 1; 2481 2482 if (getStartIndices) { 2483 if (mask[0]) { 2484 out.push_back(0); 2485 } 2486 for (int i = 0; i < endIdx; ++i) { 2487 if ((!mask[i]) && mask[i+1]) { 2488 out.push_back(i+1); 2489 } 2490 } 2491 } else { 2492 for (int i = 0; i < endIdx; ++i) { 2493 if (mask[i] && (!mask[i+1])) { 2494 out.push_back(i); 2495 } 2496 } 2497 if (mask[endIdx]) { 2498 out.push_back(endIdx); 2499 } 2500 } 2501 2502 return out; 2503 } 2504 2505 2506 /* 2507 STFitEntry Scantable::polyBaseline(const std::vector<bool>& mask, int order, int rowno) 2508 { 2509 Fitter fitter = Fitter(); 2510 fitter.setExpression("poly", order); 2511 1772 2512 std::vector<bool> fmask = getMask(rowno); 1773 2513 if (fmask.size() != mask.size()) { 1774 2514 throw(AipsError("different mask sizes")); 1775 2515 } 1776 for (int i = 0; i < fmask.size(); i++) {2516 for (int i = 0; i < fmask.size(); ++i) { 1777 2517 fmask[i] = fmask[i] && mask[i]; 1778 2518 } 1779 fitter.setData(abcs, spec, fmask); 1780 1781 fitter.lfit(); 1782 } 1783 1784 void Scantable::polyBaselineBatch(const std::vector<bool>& mask, int order) 1785 { 1786 Fitter fitter = Fitter(); 1787 for (uInt rowno=0; rowno < nrow(); ++rowno) { 1788 doPolyBaseline(mask, order, rowno, fitter); 1789 setSpectrum(fitter.getResidual(), rowno); 1790 } 1791 } 1792 1793 STFitEntry Scantable::polyBaseline(const std::vector<bool>& mask, int order, int rowno) 1794 { 1795 Fitter fitter = Fitter(); 1796 doPolyBaseline(mask, order, rowno, fitter); 2519 2520 fitBaseline(fmask, rowno, fitter); 1797 2521 setSpectrum(fitter.getResidual(), rowno); 1798 2522 return fitter.getFitEntry(); 1799 2523 } 2524 */ 1800 2525 1801 2526 }
Note: See TracChangeset
for help on using the changeset viewer.