- Timestamp:
- 09/04/12 18:58:06 (12 years ago)
- Location:
- trunk/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/Scantable.cpp
r2644 r2645 2602 2602 } 2603 2603 2604 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 2605 { 2606 /************* 2607 double totTimeStart, totTimeEnd, blTimeStart, blTimeEnd, ioTimeStart, ioTimeEnd, msTimeStart, msTimeEnd, seTimeStart, seTimeEnd, otTimeStart, otTimeEnd, prTimeStart, prTimeEnd; 2608 double elapseMs = 0.0; 2609 double elapseSe = 0.0; 2610 double elapseOt = 0.0; 2611 double elapsePr = 0.0; 2612 double elapseBl = 0.0; 2613 double elapseIo = 0.0; 2614 totTimeStart = mathutil::gettimeofday_sec(); 2615 *************/ 2616 2604 void Scantable::chebyshevBaseline(const std::vector<bool>& mask, int order, float thresClip, int nIterClip, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 2605 { 2617 2606 try { 2618 2607 ofstream ofs; … … 2634 2623 } 2635 2624 2636 //Fitter fitter = Fitter();2637 //fitter.setExpression("cspline", nPiece);2638 //fitter.setIterClipping(thresClip, nIterClip);2639 2640 2625 bool showProgress; 2641 2626 int minNRow; … … 2645 2630 std::vector<bool> chanMask; 2646 2631 2647 //--------------------------------2648 2632 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 2649 /******************2650 ioTimeStart = mathutil::gettimeofday_sec();2651 **/2652 2633 std::vector<float> sp = getSpectrum(whichrow); 2653 /**2654 ioTimeEnd = mathutil::gettimeofday_sec();2655 elapseIo += (double)(ioTimeEnd - ioTimeStart);2656 msTimeStart = mathutil::gettimeofday_sec();2657 ******************/2658 2659 2634 chanMask = getCompositeChanMask(whichrow, mask); 2660 2661 /** 2662 msTimeEnd = mathutil::gettimeofday_sec(); 2663 elapseMs += (double)(msTimeEnd - msTimeStart); 2664 blTimeStart = mathutil::gettimeofday_sec(); 2665 **/ 2666 2667 //fitBaseline(chanMask, whichrow, fitter); 2668 //setSpectrum((getResidual ? fitter.getResidual() : fitter.getFit()), whichrow); 2669 std::vector<int> pieceEdges(nPiece+1); 2670 std::vector<float> params(nPiece*4); 2635 std::vector<float> params(order+1); 2671 2636 int nClipped = 0; 2672 std::vector<float> res = doCubicSplineFitting(sp, chanMask, nPiece, pieceEdges, params, nClipped, thresClip, nIterClip, getResidual); 2673 2674 /** 2675 blTimeEnd = mathutil::gettimeofday_sec(); 2676 elapseBl += (double)(blTimeEnd - blTimeStart); 2677 seTimeStart = mathutil::gettimeofday_sec(); 2678 **/ 2679 2637 std::vector<float> res = doChebyshevFitting(sp, chanMask, order, params, nClipped, thresClip, nIterClip, getResidual); 2680 2638 2681 2639 setSpectrum(res, whichrow); 2682 // 2683 2684 /** 2685 seTimeEnd = mathutil::gettimeofday_sec(); 2686 elapseSe += (double)(seTimeEnd - seTimeStart); 2687 otTimeStart = mathutil::gettimeofday_sec(); 2688 **/ 2689 2690 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "cubicSplineBaseline()", pieceEdges, params, nClipped); 2691 2692 /** 2693 otTimeEnd = mathutil::gettimeofday_sec(); 2694 elapseOt += (double)(otTimeEnd - otTimeStart); 2695 prTimeStart = mathutil::gettimeofday_sec(); 2696 **/ 2697 2640 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "chebyshevBaseline()", params, nClipped); 2698 2641 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 2699 2700 /****************** 2701 prTimeEnd = mathutil::gettimeofday_sec(); 2702 elapsePr += (double)(prTimeEnd - prTimeStart); 2703 ******************/ 2704 } 2705 //-------------------------------- 2642 } 2706 2643 2707 2644 if (outTextFile) ofs.close(); … … 2710 2647 throw; 2711 2648 } 2712 /*************** 2713 totTimeEnd = mathutil::gettimeofday_sec(); 2714 std::cout << "io : " << elapseIo << " (sec.)" << endl; 2715 std::cout << "ms : " << elapseMs << " (sec.)" << endl; 2716 std::cout << "bl : " << elapseBl << " (sec.)" << endl; 2717 std::cout << "se : " << elapseSe << " (sec.)" << endl; 2718 std::cout << "ot : " << elapseOt << " (sec.)" << endl; 2719 std::cout << "pr : " << elapsePr << " (sec.)" << endl; 2720 std::cout << "total : " << (double)(totTimeEnd - totTimeStart) << " (sec.)" << endl; 2721 ***************/ 2722 } 2723 2724 void Scantable::autoCubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 2649 } 2650 2651 void Scantable::autoChebyshevBaseline(const std::vector<bool>& mask, int order, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 2725 2652 { 2726 2653 try { … … 2742 2669 hasSameNchan = hasSameNchanOverIFs(); 2743 2670 } 2744 2745 //Fitter fitter = Fitter();2746 //fitter.setExpression("cspline", nPiece);2747 //fitter.setIterClipping(thresClip, nIterClip);2748 2671 2749 2672 int nRow = nrow(); … … 2787 2710 //fitBaseline(chanMask, whichrow, fitter); 2788 2711 //setSpectrum((getResidual ? fitter.getResidual() : fitter.getFit()), whichrow); 2789 std::vector<int> pieceEdges(nPiece+1); 2790 std::vector<float> params(nPiece*4); 2712 std::vector<float> params(order+1); 2791 2713 int nClipped = 0; 2792 std::vector<float> res = doC ubicSplineFitting(sp, chanMask, nPiece, pieceEdges, params, nClipped, thresClip, nIterClip, getResidual);2714 std::vector<float> res = doChebyshevFitting(sp, chanMask, order, params, nClipped, thresClip, nIterClip, getResidual); 2793 2715 setSpectrum(res, whichrow); 2794 // 2795 2796 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoCubicSplineBaseline()", pieceEdges, params, nClipped); 2716 2717 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoChebyshevBaseline()", params, nClipped); 2797 2718 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 2798 2719 } … … 2805 2726 } 2806 2727 2807 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, int& nClipped, float thresClip, int nIterClip, bool getResidual) 2728 /* 2729 double Scantable::getChebyshevPolynomial(int n, double x) { 2730 if ((x < -1.0)||(x > 1.0)) { 2731 throw(AipsError("out of definition range (-1 <= x <= 1).")); 2732 } else if (n < 0) { 2733 throw(AipsError("the order must be zero or positive.")); 2734 } else if (n == 0) { 2735 return 1.0; 2736 } else if (n == 1) { 2737 return x; 2738 } else { 2739 return 2.0*x*getChebyshevPolynomial(n-1, x) - getChebyshevPolynomial(n-2, x); 2740 } 2741 } 2742 */ 2743 double Scantable::getChebyshevPolynomial(int n, double x) { 2744 if ((x < -1.0)||(x > 1.0)) { 2745 throw(AipsError("out of definition range (-1 <= x <= 1).")); 2746 } else if (n < 0) { 2747 throw(AipsError("the order must be zero or positive.")); 2748 } else if (n == 0) { 2749 return 1.0; 2750 } else if (n == 1) { 2751 return x; 2752 } else { 2753 double res = 0.0; 2754 for (int m = 0; m <= n/2; ++m) { 2755 double c = 1.0; 2756 if (m > 0) { 2757 for (int i = 1; i <= m; ++i) { 2758 c *= (double)(n-2*m+i)/(double)i; 2759 } 2760 } 2761 res += (m%2 == 0 ? 1.0 : -1.0)*(double)n/(double)(n-m)*pow(2.0*x, (double)(n-2*m-1))/2.0*c; 2762 } 2763 return res; 2764 } 2765 } 2766 2767 std::vector<float> Scantable::doChebyshevFitting(const std::vector<float>& data, const std::vector<bool>& mask, int order, std::vector<float>& params, int& nClipped, float thresClip, int nIterClip, bool getResidual) 2808 2768 { 2809 2769 if (data.size() != mask.size()) { 2810 2770 throw(AipsError("data and mask sizes are not identical")); 2811 2771 } 2812 if ( nPiece < 1) {2813 throw(AipsError(" number of the sections must be one or more"));2772 if (order < 0) { 2773 throw(AipsError("maximum order of Chebyshev polynomial must not be negative.")); 2814 2774 } 2815 2775 2816 2776 int nChan = data.size(); 2817 std::vector<int> maskArray(nChan); 2818 std::vector<int> x(nChan); 2819 int j = 0; 2777 std::vector<int> maskArray; 2778 std::vector<int> x; 2820 2779 for (int i = 0; i < nChan; ++i) { 2821 maskArray [i] = mask[i] ? 1 : 0;2780 maskArray.push_back(mask[i] ? 1 : 0); 2822 2781 if (mask[i]) { 2823 x[j] = i; 2824 j++; 2825 } 2826 } 2827 int initNData = j; 2828 2829 if (initNData < nPiece) { 2830 throw(AipsError("too few non-flagged channels")); 2831 } 2832 2833 int nElement = (int)(floor(floor((double)(initNData/nPiece))+0.5)); 2834 std::vector<double> invEdge(nPiece-1); 2835 idxEdge[0] = x[0]; 2836 for (int i = 1; i < nPiece; ++i) { 2837 int valX = x[nElement*i]; 2838 idxEdge[i] = valX; 2839 invEdge[i-1] = 1.0/(double)valX; 2840 } 2841 idxEdge[nPiece] = x[initNData-1]+1; 2782 x.push_back(i); 2783 } 2784 } 2785 2786 int initNData = x.size(); 2842 2787 2843 2788 int nData = initNData; 2844 int nDOF = nPiece + 3; //number of parameters to solve, namely, 4+(nPiece-1). 2845 2846 std::vector<double> x1(nChan), x2(nChan), x3(nChan); 2847 std::vector<double> z1(nChan), x1z1(nChan), x2z1(nChan), x3z1(nChan); 2848 std::vector<double> r1(nChan), residual(nChan); 2789 int nDOF = order + 1; //number of parameters to solve. 2790 2791 // xArray : contains elemental values for computing the least-square matrix. 2792 // xArray.size() is nDOF and xArray[*].size() is nChan. 2793 // Each xArray element are as follows: 2794 // xArray[0] = {T0(-1), T0(2/(nChan-1)-1), T0(4/(nChan-1)-1), ..., T0(1)}, 2795 // xArray[n-1] = ..., 2796 // xArray[n] = {Tn(-1), Tn(2/(nChan-1)-1), Tn(4/(nChan-1)-1), ..., Tn(1)} 2797 // where (0 <= n <= order), 2798 std::vector<std::vector<double> > xArray; 2799 for (int i = 0; i < nDOF; ++i) { 2800 double xFactor = 2.0/(double)(nChan - 1); 2801 std::vector<double> xs; 2802 xs.clear(); 2803 for (int j = 0; j < nChan; ++j) { 2804 xs.push_back(getChebyshevPolynomial(i, xFactor*(double)j-1.0)); 2805 } 2806 xArray.push_back(xs); 2807 } 2808 2809 std::vector<double> z1, r1, residual; 2849 2810 for (int i = 0; i < nChan; ++i) { 2850 double di = (double)i; 2851 double dD = (double)data[i]; 2852 x1[i] = di; 2853 x2[i] = di*di; 2854 x3[i] = di*di*di; 2855 z1[i] = dD; 2856 x1z1[i] = dD*di; 2857 x2z1[i] = dD*di*di; 2858 x3z1[i] = dD*di*di*di; 2859 r1[i] = 0.0; 2860 residual[i] = 0.0; 2811 z1.push_back((double)data[i]); 2812 r1.push_back(0.0); 2813 residual.push_back(0.0); 2861 2814 } 2862 2815 … … 2876 2829 } 2877 2830 2878 for (int n = 0; n < nPiece; ++n) { 2879 int nUseDataInPiece = 0; 2880 for (int i = idxEdge[n]; i < idxEdge[n+1]; ++i) { 2881 2882 if (maskArray[i] == 0) continue; 2883 2884 xMatrix[0][0] += 1.0; 2885 xMatrix[0][1] += x1[i]; 2886 xMatrix[0][2] += x2[i]; 2887 xMatrix[0][3] += x3[i]; 2888 xMatrix[1][1] += x2[i]; 2889 xMatrix[1][2] += x3[i]; 2890 xMatrix[1][3] += x2[i]*x2[i]; 2891 xMatrix[2][2] += x2[i]*x2[i]; 2892 xMatrix[2][3] += x3[i]*x2[i]; 2893 xMatrix[3][3] += x3[i]*x3[i]; 2894 zMatrix[0] += z1[i]; 2895 zMatrix[1] += x1z1[i]; 2896 zMatrix[2] += x2z1[i]; 2897 zMatrix[3] += x3z1[i]; 2898 2899 for (int j = 0; j < n; ++j) { 2900 double q = 1.0 - x1[i]*invEdge[j]; 2901 q = q*q*q; 2902 xMatrix[0][j+4] += q; 2903 xMatrix[1][j+4] += q*x1[i]; 2904 xMatrix[2][j+4] += q*x2[i]; 2905 xMatrix[3][j+4] += q*x3[i]; 2906 for (int k = 0; k < j; ++k) { 2907 double r = 1.0 - x1[i]*invEdge[k]; 2908 r = r*r*r; 2909 xMatrix[k+4][j+4] += r*q; 2910 } 2911 xMatrix[j+4][j+4] += q*q; 2912 zMatrix[j+4] += q*z1[i]; 2831 int nUseData = 0; 2832 for (int k = 0; k < nChan; ++k) { 2833 if (maskArray[k] == 0) continue; 2834 2835 for (int i = 0; i < nDOF; ++i) { 2836 for (int j = i; j < nDOF; ++j) { 2837 xMatrix[i][j] += xArray[i][k] * xArray[j][k]; 2913 2838 } 2914 2915 nUseDataInPiece++; 2916 } 2917 2918 if (nUseDataInPiece < 1) { 2919 std::vector<string> suffixOfPieceNumber(4); 2920 suffixOfPieceNumber[0] = "th"; 2921 suffixOfPieceNumber[1] = "st"; 2922 suffixOfPieceNumber[2] = "nd"; 2923 suffixOfPieceNumber[3] = "rd"; 2924 int idxNoDataPiece = (n % 10 <= 3) ? n : 0; 2925 ostringstream oss; 2926 oss << "all channels clipped or masked in " << n << suffixOfPieceNumber[idxNoDataPiece]; 2927 oss << " piece of the spectrum. can't execute fitting anymore."; 2928 throw(AipsError(String(oss))); 2929 } 2839 zMatrix[i] += z1[k] * xArray[i][k]; 2840 } 2841 2842 nUseData++; 2843 } 2844 2845 if (nUseData < 1) { 2846 throw(AipsError("all channels clipped or masked. can't execute fitting anymore.")); 2930 2847 } 2931 2848 … … 2936 2853 } 2937 2854 2938 std::vector<double> invDiag (nDOF);2855 std::vector<double> invDiag; 2939 2856 for (int i = 0; i < nDOF; ++i) { 2940 invDiag [i] = 1.0/xMatrix[i][i];2857 invDiag.push_back(1.0/xMatrix[i][i]); 2941 2858 for (int j = 0; j < nDOF; ++j) { 2942 2859 xMatrix[i][j] *= invDiag[i]; … … 2967 2884 } 2968 2885 } 2969 //compute a vector y which consists of the coefficients of the best-fit spline curves 2970 //(a0,a1,a2,a3(,b3,c3,...)), namely, the ones for the leftmost piece and the ones of 2971 //cubic terms for the other pieces (in case nPiece>1). 2972 std::vector<double> y(nDOF); 2886 //compute a vector y which consists of the coefficients of the sinusoids forming the 2887 //best-fit curves (a0,s1,c1,s2,c2,...), where a0 is constant and s* and c* are of sine 2888 //and cosine functions, respectively. 2889 std::vector<double> y; 2890 params.clear(); 2973 2891 for (int i = 0; i < nDOF; ++i) { 2974 y [i] = 0.0;2892 y.push_back(0.0); 2975 2893 for (int j = 0; j < nDOF; ++j) { 2976 2894 y[i] += xMatrix[i][nDOF+j]*zMatrix[j]; 2977 2895 } 2978 } 2979 2980 double a0 = y[0]; 2981 double a1 = y[1]; 2982 double a2 = y[2]; 2983 double a3 = y[3]; 2984 2985 int j = 0; 2986 for (int n = 0; n < nPiece; ++n) { 2987 for (int i = idxEdge[n]; i < idxEdge[n+1]; ++i) { 2988 r1[i] = a0 + a1*x1[i] + a2*x2[i] + a3*x3[i]; 2989 } 2990 params[j] = a0; 2991 params[j+1] = a1; 2992 params[j+2] = a2; 2993 params[j+3] = a3; 2994 j += 4; 2995 2996 if (n == nPiece-1) break; 2997 2998 double d = y[4+n]; 2999 double iE = invEdge[n]; 3000 a0 += d; 3001 a1 -= 3.0*d*iE; 3002 a2 += 3.0*d*iE*iE; 3003 a3 -= d*iE*iE*iE; 3004 } 3005 3006 //subtract constant value for masked regions at the edge of spectrum 3007 if (idxEdge[0] > 0) { 3008 int n = idxEdge[0]; 3009 for (int i = 0; i < idxEdge[0]; ++i) { 3010 //--cubic extrapolate-- 3011 //r1[i] = params[0] + params[1]*x1[i] + params[2]*x2[i] + params[3]*x3[i]; 3012 //--linear extrapolate-- 3013 //r1[i] = (r1[n+1] - r1[n])/(x1[n+1] - x1[n])*(x1[i] - x1[n]) + r1[n]; 3014 //--constant-- 3015 r1[i] = r1[n]; 3016 } 3017 } 3018 if (idxEdge[nPiece] < nChan) { 3019 int n = idxEdge[nPiece]-1; 3020 for (int i = idxEdge[nPiece]; i < nChan; ++i) { 3021 //--cubic extrapolate-- 3022 //int m = 4*(nPiece-1); 3023 //r1[i] = params[m] + params[m+1]*x1[i] + params[m+2]*x2[i] + params[m+3]*x3[i]; 3024 //--linear extrapolate-- 3025 //r1[i] = (r1[n-1] - r1[n])/(x1[n-1] - x1[n])*(x1[i] - x1[n]) + r1[n]; 3026 //--constant-- 3027 r1[i] = r1[n]; 3028 } 2896 params.push_back(y[i]); 3029 2897 } 3030 2898 3031 2899 for (int i = 0; i < nChan; ++i) { 2900 r1[i] = y[0]; 2901 for (int j = 1; j < nDOF; ++j) { 2902 r1[i] += y[j]*xArray[j][i]; 2903 } 3032 2904 residual[i] = z1[i] - r1[i]; 3033 2905 } … … 3062 2934 nClipped = initNData - nData; 3063 2935 3064 std::vector<float> result (nChan);2936 std::vector<float> result; 3065 2937 if (getResidual) { 3066 2938 for (int i = 0; i < nChan; ++i) { 3067 result [i] = (float)residual[i];2939 result.push_back((float)residual[i]); 3068 2940 } 3069 2941 } else { 3070 2942 for (int i = 0; i < nChan; ++i) { 3071 result [i] = (float)r1[i];2943 result.push_back((float)r1[i]); 3072 2944 } 3073 2945 } … … 3076 2948 } 3077 2949 3078 void Scantable::selectWaveNumbers(const int whichrow, const std::vector<bool>& chanMask, const bool applyFFT, const std::string& fftMethod, const std::string& fftThresh, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, std::vector<int>& nWaves) 3079 { 3080 nWaves.clear(); 3081 3082 if (applyFFT) { 3083 string fftThAttr; 3084 float fftThSigma; 3085 int fftThTop; 3086 parseThresholdExpression(fftThresh, fftThAttr, fftThSigma, fftThTop); 3087 doSelectWaveNumbers(whichrow, chanMask, fftMethod, fftThSigma, fftThTop, fftThAttr, nWaves); 3088 } 3089 3090 addAuxWaveNumbers(whichrow, addNWaves, rejectNWaves, nWaves); 3091 } 3092 3093 void Scantable::parseThresholdExpression(const std::string& fftThresh, std::string& fftThAttr, float& fftThSigma, int& fftThTop) 3094 { 3095 uInt idxSigma = fftThresh.find("sigma"); 3096 uInt idxTop = fftThresh.find("top"); 3097 3098 if (idxSigma == fftThresh.size() - 5) { 3099 std::istringstream is(fftThresh.substr(0, fftThresh.size() - 5)); 3100 is >> fftThSigma; 3101 fftThAttr = "sigma"; 3102 } else if (idxTop == 0) { 3103 std::istringstream is(fftThresh.substr(3)); 3104 is >> fftThTop; 3105 fftThAttr = "top"; 3106 } else { 3107 bool isNumber = true; 3108 for (uInt i = 0; i < fftThresh.size()-1; ++i) { 3109 char ch = (fftThresh.substr(i, 1).c_str())[0]; 3110 if (!(isdigit(ch) || (fftThresh.substr(i, 1) == "."))) { 3111 isNumber = false; 3112 break; 3113 } 3114 } 3115 if (isNumber) { 3116 std::istringstream is(fftThresh); 3117 is >> fftThSigma; 3118 fftThAttr = "sigma"; 3119 } else { 3120 throw(AipsError("fftthresh has a wrong value")); 3121 } 3122 } 3123 } 3124 3125 void Scantable::doSelectWaveNumbers(const int whichrow, const std::vector<bool>& chanMask, const std::string& fftMethod, const float fftThSigma, const int fftThTop, const std::string& fftThAttr, std::vector<int>& nWaves) 3126 { 3127 std::vector<float> fspec; 3128 if (fftMethod == "fft") { 3129 fspec = execFFT(whichrow, chanMask, false, true); 3130 //} else if (fftMethod == "lsp") { 3131 // fspec = lombScarglePeriodogram(whichrow); 3132 } 3133 3134 if (fftThAttr == "sigma") { 3135 float mean = 0.0; 3136 float mean2 = 0.0; 3137 for (uInt i = 0; i < fspec.size(); ++i) { 3138 mean += fspec[i]; 3139 mean2 += fspec[i]*fspec[i]; 3140 } 3141 mean /= float(fspec.size()); 3142 mean2 /= float(fspec.size()); 3143 float thres = mean + fftThSigma * float(sqrt(mean2 - mean*mean)); 3144 3145 for (uInt i = 0; i < fspec.size(); ++i) { 3146 if (fspec[i] >= thres) { 3147 nWaves.push_back(i); 3148 } 3149 } 3150 3151 } else if (fftThAttr == "top") { 3152 for (int i = 0; i < fftThTop; ++i) { 3153 float max = 0.0; 3154 int maxIdx = 0; 3155 for (uInt j = 0; j < fspec.size(); ++j) { 3156 if (fspec[j] > max) { 3157 max = fspec[j]; 3158 maxIdx = j; 3159 } 3160 } 3161 nWaves.push_back(maxIdx); 3162 fspec[maxIdx] = 0.0; 3163 } 3164 3165 } 3166 3167 if (nWaves.size() > 1) { 3168 sort(nWaves.begin(), nWaves.end()); 3169 } 3170 } 3171 3172 void Scantable::addAuxWaveNumbers(const int whichrow, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, std::vector<int>& nWaves) 3173 { 3174 std::vector<int> tempAddNWaves, tempRejectNWaves; 3175 for (uInt i = 0; i < addNWaves.size(); ++i) { 3176 tempAddNWaves.push_back(addNWaves[i]); 3177 } 3178 if ((tempAddNWaves.size() == 2) && (tempAddNWaves[1] == -999)) { 3179 setWaveNumberListUptoNyquistFreq(whichrow, tempAddNWaves); 3180 } 3181 3182 for (uInt i = 0; i < rejectNWaves.size(); ++i) { 3183 tempRejectNWaves.push_back(rejectNWaves[i]); 3184 } 3185 if ((tempRejectNWaves.size() == 2) && (tempRejectNWaves[1] == -999)) { 3186 setWaveNumberListUptoNyquistFreq(whichrow, tempRejectNWaves); 3187 } 3188 3189 for (uInt i = 0; i < tempAddNWaves.size(); ++i) { 3190 bool found = false; 3191 for (uInt j = 0; j < nWaves.size(); ++j) { 3192 if (nWaves[j] == tempAddNWaves[i]) { 3193 found = true; 3194 break; 3195 } 3196 } 3197 if (!found) nWaves.push_back(tempAddNWaves[i]); 3198 } 3199 3200 for (uInt i = 0; i < tempRejectNWaves.size(); ++i) { 3201 for (std::vector<int>::iterator j = nWaves.begin(); j != nWaves.end(); ) { 3202 if (*j == tempRejectNWaves[i]) { 3203 j = nWaves.erase(j); 3204 } else { 3205 ++j; 3206 } 3207 } 3208 } 3209 3210 if (nWaves.size() > 1) { 3211 sort(nWaves.begin(), nWaves.end()); 3212 unique(nWaves.begin(), nWaves.end()); 3213 } 3214 } 3215 3216 void Scantable::setWaveNumberListUptoNyquistFreq(const int whichrow, std::vector<int>& nWaves) 3217 { 3218 if ((nWaves.size() == 2)&&(nWaves[1] == -999)) { 3219 int val = nWaves[0]; 3220 int nyquistFreq = nchan(getIF(whichrow))/2+1; 3221 nWaves.clear(); 3222 if (val > nyquistFreq) { // for safety, at least nWaves contains a constant; CAS-3759 3223 nWaves.push_back(0); 3224 } 3225 while (val <= nyquistFreq) { 3226 nWaves.push_back(val); 3227 val++; 3228 } 3229 } 3230 } 3231 3232 void Scantable::sinusoidBaseline(const std::vector<bool>& mask, const bool applyFFT, const std::string& fftMethod, const std::string& fftThresh, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, float thresClip, int nIterClip, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 3233 { 2950 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 2951 { 2952 /************* 2953 double totTimeStart, totTimeEnd, blTimeStart, blTimeEnd, ioTimeStart, ioTimeEnd, msTimeStart, msTimeEnd, seTimeStart, seTimeEnd, otTimeStart, otTimeEnd, prTimeStart, prTimeEnd; 2954 double elapseMs = 0.0; 2955 double elapseSe = 0.0; 2956 double elapseOt = 0.0; 2957 double elapsePr = 0.0; 2958 double elapseBl = 0.0; 2959 double elapseIo = 0.0; 2960 totTimeStart = mathutil::gettimeofday_sec(); 2961 *************/ 2962 3234 2963 try { 3235 2964 ofstream ofs; … … 3252 2981 3253 2982 //Fitter fitter = Fitter(); 3254 //fitter.setExpression(" sinusoid", nWaves);2983 //fitter.setExpression("cspline", nPiece); 3255 2984 //fitter.setIterClipping(thresClip, nIterClip); 3256 3257 int nRow = nrow();3258 std::vector<bool> chanMask;3259 std::vector<int> nWaves;3260 2985 3261 2986 bool showProgress; … … 3263 2988 parseProgressInfo(progressInfo, showProgress, minNRow); 3264 2989 2990 int nRow = nrow(); 2991 std::vector<bool> chanMask; 2992 2993 //-------------------------------- 3265 2994 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 2995 /****************** 2996 ioTimeStart = mathutil::gettimeofday_sec(); 2997 **/ 2998 std::vector<float> sp = getSpectrum(whichrow); 2999 /** 3000 ioTimeEnd = mathutil::gettimeofday_sec(); 3001 elapseIo += (double)(ioTimeEnd - ioTimeStart); 3002 msTimeStart = mathutil::gettimeofday_sec(); 3003 ******************/ 3004 3266 3005 chanMask = getCompositeChanMask(whichrow, mask); 3267 selectWaveNumbers(whichrow, chanMask, applyFFT, fftMethod, fftThresh, addNWaves, rejectNWaves, nWaves); 3268 3269 //FOR DEBUGGING------------ 3270 /* 3271 if (whichrow < 0) {// == nRow -1) { 3272 cout << "+++ i=" << setw(3) << whichrow << ", IF=" << setw(2) << getIF(whichrow); 3273 if (applyFFT) { 3274 cout << "[ "; 3275 for (uInt j = 0; j < nWaves.size(); ++j) { 3276 cout << nWaves[j] << ", "; 3277 } 3278 cout << " ] " << endl; 3279 } 3280 cout << flush; 3281 } 3282 */ 3283 //------------------------- 3006 3007 /** 3008 msTimeEnd = mathutil::gettimeofday_sec(); 3009 elapseMs += (double)(msTimeEnd - msTimeStart); 3010 blTimeStart = mathutil::gettimeofday_sec(); 3011 **/ 3284 3012 3285 3013 //fitBaseline(chanMask, whichrow, fitter); 3286 3014 //setSpectrum((getResidual ? fitter.getResidual() : fitter.getFit()), whichrow); 3287 std::vector<float> params; 3015 std::vector<int> pieceEdges(nPiece+1); 3016 std::vector<float> params(nPiece*4); 3288 3017 int nClipped = 0; 3289 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nWaves, params, nClipped, thresClip, nIterClip, getResidual); 3018 std::vector<float> res = doCubicSplineFitting(sp, chanMask, nPiece, pieceEdges, params, nClipped, thresClip, nIterClip, getResidual); 3019 3020 /** 3021 blTimeEnd = mathutil::gettimeofday_sec(); 3022 elapseBl += (double)(blTimeEnd - blTimeStart); 3023 seTimeStart = mathutil::gettimeofday_sec(); 3024 **/ 3025 3026 3290 3027 setSpectrum(res, whichrow); 3291 3028 // 3292 3029 3293 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "sinusoidBaseline()", params, nClipped); 3030 /** 3031 seTimeEnd = mathutil::gettimeofday_sec(); 3032 elapseSe += (double)(seTimeEnd - seTimeStart); 3033 otTimeStart = mathutil::gettimeofday_sec(); 3034 **/ 3035 3036 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "cubicSplineBaseline()", pieceEdges, params, nClipped); 3037 3038 /** 3039 otTimeEnd = mathutil::gettimeofday_sec(); 3040 elapseOt += (double)(otTimeEnd - otTimeStart); 3041 prTimeStart = mathutil::gettimeofday_sec(); 3042 **/ 3043 3294 3044 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 3295 } 3296 3045 3046 /****************** 3047 prTimeEnd = mathutil::gettimeofday_sec(); 3048 elapsePr += (double)(prTimeEnd - prTimeStart); 3049 ******************/ 3050 } 3051 //-------------------------------- 3052 3297 3053 if (outTextFile) ofs.close(); 3298 3054 … … 3300 3056 throw; 3301 3057 } 3302 } 3303 3304 void Scantable::autoSinusoidBaseline(const std::vector<bool>& mask, const bool applyFFT, const std::string& fftMethod, const std::string& fftThresh, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 3058 /*************** 3059 totTimeEnd = mathutil::gettimeofday_sec(); 3060 std::cout << "io : " << elapseIo << " (sec.)" << endl; 3061 std::cout << "ms : " << elapseMs << " (sec.)" << endl; 3062 std::cout << "bl : " << elapseBl << " (sec.)" << endl; 3063 std::cout << "se : " << elapseSe << " (sec.)" << endl; 3064 std::cout << "ot : " << elapseOt << " (sec.)" << endl; 3065 std::cout << "pr : " << elapsePr << " (sec.)" << endl; 3066 std::cout << "total : " << (double)(totTimeEnd - totTimeStart) << " (sec.)" << endl; 3067 ***************/ 3068 } 3069 3070 void Scantable::autoCubicSplineBaseline(const std::vector<bool>& mask, int nPiece, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 3305 3071 { 3306 3072 try { … … 3324 3090 3325 3091 //Fitter fitter = Fitter(); 3326 //fitter.setExpression(" sinusoid", nWaves);3092 //fitter.setExpression("cspline", nPiece); 3327 3093 //fitter.setIterClipping(thresClip, nIterClip); 3328 3094 3329 3095 int nRow = nrow(); 3330 3096 std::vector<bool> chanMask; 3331 std::vector<int> nWaves;3332 3333 3097 int minEdgeSize = getIFNos().size()*2; 3334 3098 STLineFinder lineFinder = STLineFinder(); … … 3340 3104 3341 3105 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3106 std::vector<float> sp = getSpectrum(whichrow); 3342 3107 3343 3108 //------------------------------------------------------- … … 3359 3124 throw(AipsError("Wrong length of edge element")); 3360 3125 } 3126 //lineFinder.setData(getSpectrum(whichrow)); 3127 lineFinder.setData(sp); 3128 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 3129 chanMask = lineFinder.getMask(); 3130 //------------------------------------------------------- 3131 3132 3133 //fitBaseline(chanMask, whichrow, fitter); 3134 //setSpectrum((getResidual ? fitter.getResidual() : fitter.getFit()), whichrow); 3135 std::vector<int> pieceEdges(nPiece+1); 3136 std::vector<float> params(nPiece*4); 3137 int nClipped = 0; 3138 std::vector<float> res = doCubicSplineFitting(sp, chanMask, nPiece, pieceEdges, params, nClipped, thresClip, nIterClip, getResidual); 3139 setSpectrum(res, whichrow); 3140 // 3141 3142 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoCubicSplineBaseline()", pieceEdges, params, nClipped); 3143 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 3144 } 3145 3146 if (outTextFile) ofs.close(); 3147 3148 } catch (...) { 3149 throw; 3150 } 3151 } 3152 3153 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, int& nClipped, float thresClip, int nIterClip, bool getResidual) 3154 { 3155 if (data.size() != mask.size()) { 3156 throw(AipsError("data and mask sizes are not identical")); 3157 } 3158 if (nPiece < 1) { 3159 throw(AipsError("number of the sections must be one or more")); 3160 } 3161 3162 int nChan = data.size(); 3163 std::vector<int> maskArray(nChan); 3164 std::vector<int> x(nChan); 3165 int j = 0; 3166 for (int i = 0; i < nChan; ++i) { 3167 maskArray[i] = mask[i] ? 1 : 0; 3168 if (mask[i]) { 3169 x[j] = i; 3170 j++; 3171 } 3172 } 3173 int initNData = j; 3174 3175 if (initNData < nPiece) { 3176 throw(AipsError("too few non-flagged channels")); 3177 } 3178 3179 int nElement = (int)(floor(floor((double)(initNData/nPiece))+0.5)); 3180 std::vector<double> invEdge(nPiece-1); 3181 idxEdge[0] = x[0]; 3182 for (int i = 1; i < nPiece; ++i) { 3183 int valX = x[nElement*i]; 3184 idxEdge[i] = valX; 3185 invEdge[i-1] = 1.0/(double)valX; 3186 } 3187 idxEdge[nPiece] = x[initNData-1]+1; 3188 3189 int nData = initNData; 3190 int nDOF = nPiece + 3; //number of parameters to solve, namely, 4+(nPiece-1). 3191 3192 std::vector<double> x1(nChan), x2(nChan), x3(nChan); 3193 std::vector<double> z1(nChan), x1z1(nChan), x2z1(nChan), x3z1(nChan); 3194 std::vector<double> r1(nChan), residual(nChan); 3195 for (int i = 0; i < nChan; ++i) { 3196 double di = (double)i; 3197 double dD = (double)data[i]; 3198 x1[i] = di; 3199 x2[i] = di*di; 3200 x3[i] = di*di*di; 3201 z1[i] = dD; 3202 x1z1[i] = dD*di; 3203 x2z1[i] = dD*di*di; 3204 x3z1[i] = dD*di*di*di; 3205 r1[i] = 0.0; 3206 residual[i] = 0.0; 3207 } 3208 3209 for (int nClip = 0; nClip < nIterClip+1; ++nClip) { 3210 // xMatrix : horizontal concatenation of 3211 // the least-sq. matrix (left) and an 3212 // identity matrix (right). 3213 // the right part is used to calculate the inverse matrix of the left part. 3214 double xMatrix[nDOF][2*nDOF]; 3215 double zMatrix[nDOF]; 3216 for (int i = 0; i < nDOF; ++i) { 3217 for (int j = 0; j < 2*nDOF; ++j) { 3218 xMatrix[i][j] = 0.0; 3219 } 3220 xMatrix[i][nDOF+i] = 1.0; 3221 zMatrix[i] = 0.0; 3222 } 3223 3224 for (int n = 0; n < nPiece; ++n) { 3225 int nUseDataInPiece = 0; 3226 for (int i = idxEdge[n]; i < idxEdge[n+1]; ++i) { 3227 3228 if (maskArray[i] == 0) continue; 3229 3230 xMatrix[0][0] += 1.0; 3231 xMatrix[0][1] += x1[i]; 3232 xMatrix[0][2] += x2[i]; 3233 xMatrix[0][3] += x3[i]; 3234 xMatrix[1][1] += x2[i]; 3235 xMatrix[1][2] += x3[i]; 3236 xMatrix[1][3] += x2[i]*x2[i]; 3237 xMatrix[2][2] += x2[i]*x2[i]; 3238 xMatrix[2][3] += x3[i]*x2[i]; 3239 xMatrix[3][3] += x3[i]*x3[i]; 3240 zMatrix[0] += z1[i]; 3241 zMatrix[1] += x1z1[i]; 3242 zMatrix[2] += x2z1[i]; 3243 zMatrix[3] += x3z1[i]; 3244 3245 for (int j = 0; j < n; ++j) { 3246 double q = 1.0 - x1[i]*invEdge[j]; 3247 q = q*q*q; 3248 xMatrix[0][j+4] += q; 3249 xMatrix[1][j+4] += q*x1[i]; 3250 xMatrix[2][j+4] += q*x2[i]; 3251 xMatrix[3][j+4] += q*x3[i]; 3252 for (int k = 0; k < j; ++k) { 3253 double r = 1.0 - x1[i]*invEdge[k]; 3254 r = r*r*r; 3255 xMatrix[k+4][j+4] += r*q; 3256 } 3257 xMatrix[j+4][j+4] += q*q; 3258 zMatrix[j+4] += q*z1[i]; 3259 } 3260 3261 nUseDataInPiece++; 3262 } 3263 3264 if (nUseDataInPiece < 1) { 3265 std::vector<string> suffixOfPieceNumber(4); 3266 suffixOfPieceNumber[0] = "th"; 3267 suffixOfPieceNumber[1] = "st"; 3268 suffixOfPieceNumber[2] = "nd"; 3269 suffixOfPieceNumber[3] = "rd"; 3270 int idxNoDataPiece = (n % 10 <= 3) ? n : 0; 3271 ostringstream oss; 3272 oss << "all channels clipped or masked in " << n << suffixOfPieceNumber[idxNoDataPiece]; 3273 oss << " piece of the spectrum. can't execute fitting anymore."; 3274 throw(AipsError(String(oss))); 3275 } 3276 } 3277 3278 for (int i = 0; i < nDOF; ++i) { 3279 for (int j = 0; j < i; ++j) { 3280 xMatrix[i][j] = xMatrix[j][i]; 3281 } 3282 } 3283 3284 std::vector<double> invDiag(nDOF); 3285 for (int i = 0; i < nDOF; ++i) { 3286 invDiag[i] = 1.0/xMatrix[i][i]; 3287 for (int j = 0; j < nDOF; ++j) { 3288 xMatrix[i][j] *= invDiag[i]; 3289 } 3290 } 3291 3292 for (int k = 0; k < nDOF; ++k) { 3293 for (int i = 0; i < nDOF; ++i) { 3294 if (i != k) { 3295 double factor1 = xMatrix[k][k]; 3296 double factor2 = xMatrix[i][k]; 3297 for (int j = k; j < 2*nDOF; ++j) { 3298 xMatrix[i][j] *= factor1; 3299 xMatrix[i][j] -= xMatrix[k][j]*factor2; 3300 xMatrix[i][j] /= factor1; 3301 } 3302 } 3303 } 3304 double xDiag = xMatrix[k][k]; 3305 for (int j = k; j < 2*nDOF; ++j) { 3306 xMatrix[k][j] /= xDiag; 3307 } 3308 } 3309 3310 for (int i = 0; i < nDOF; ++i) { 3311 for (int j = 0; j < nDOF; ++j) { 3312 xMatrix[i][nDOF+j] *= invDiag[j]; 3313 } 3314 } 3315 //compute a vector y which consists of the coefficients of the best-fit spline curves 3316 //(a0,a1,a2,a3(,b3,c3,...)), namely, the ones for the leftmost piece and the ones of 3317 //cubic terms for the other pieces (in case nPiece>1). 3318 std::vector<double> y(nDOF); 3319 for (int i = 0; i < nDOF; ++i) { 3320 y[i] = 0.0; 3321 for (int j = 0; j < nDOF; ++j) { 3322 y[i] += xMatrix[i][nDOF+j]*zMatrix[j]; 3323 } 3324 } 3325 3326 double a0 = y[0]; 3327 double a1 = y[1]; 3328 double a2 = y[2]; 3329 double a3 = y[3]; 3330 3331 int j = 0; 3332 for (int n = 0; n < nPiece; ++n) { 3333 for (int i = idxEdge[n]; i < idxEdge[n+1]; ++i) { 3334 r1[i] = a0 + a1*x1[i] + a2*x2[i] + a3*x3[i]; 3335 } 3336 params[j] = a0; 3337 params[j+1] = a1; 3338 params[j+2] = a2; 3339 params[j+3] = a3; 3340 j += 4; 3341 3342 if (n == nPiece-1) break; 3343 3344 double d = y[4+n]; 3345 double iE = invEdge[n]; 3346 a0 += d; 3347 a1 -= 3.0*d*iE; 3348 a2 += 3.0*d*iE*iE; 3349 a3 -= d*iE*iE*iE; 3350 } 3351 3352 //subtract constant value for masked regions at the edge of spectrum 3353 if (idxEdge[0] > 0) { 3354 int n = idxEdge[0]; 3355 for (int i = 0; i < idxEdge[0]; ++i) { 3356 //--cubic extrapolate-- 3357 //r1[i] = params[0] + params[1]*x1[i] + params[2]*x2[i] + params[3]*x3[i]; 3358 //--linear extrapolate-- 3359 //r1[i] = (r1[n+1] - r1[n])/(x1[n+1] - x1[n])*(x1[i] - x1[n]) + r1[n]; 3360 //--constant-- 3361 r1[i] = r1[n]; 3362 } 3363 } 3364 if (idxEdge[nPiece] < nChan) { 3365 int n = idxEdge[nPiece]-1; 3366 for (int i = idxEdge[nPiece]; i < nChan; ++i) { 3367 //--cubic extrapolate-- 3368 //int m = 4*(nPiece-1); 3369 //r1[i] = params[m] + params[m+1]*x1[i] + params[m+2]*x2[i] + params[m+3]*x3[i]; 3370 //--linear extrapolate-- 3371 //r1[i] = (r1[n-1] - r1[n])/(x1[n-1] - x1[n])*(x1[i] - x1[n]) + r1[n]; 3372 //--constant-- 3373 r1[i] = r1[n]; 3374 } 3375 } 3376 3377 for (int i = 0; i < nChan; ++i) { 3378 residual[i] = z1[i] - r1[i]; 3379 } 3380 3381 if ((nClip == nIterClip) || (thresClip <= 0.0)) { 3382 break; 3383 } else { 3384 double stdDev = 0.0; 3385 for (int i = 0; i < nChan; ++i) { 3386 stdDev += residual[i]*residual[i]*(double)maskArray[i]; 3387 } 3388 stdDev = sqrt(stdDev/(double)nData); 3389 3390 double thres = stdDev * thresClip; 3391 int newNData = 0; 3392 for (int i = 0; i < nChan; ++i) { 3393 if (abs(residual[i]) >= thres) { 3394 maskArray[i] = 0; 3395 } 3396 if (maskArray[i] > 0) { 3397 newNData++; 3398 } 3399 } 3400 if (newNData == nData) { 3401 break; //no more flag to add. iteration stops. 3402 } else { 3403 nData = newNData; 3404 } 3405 } 3406 } 3407 3408 nClipped = initNData - nData; 3409 3410 std::vector<float> result(nChan); 3411 if (getResidual) { 3412 for (int i = 0; i < nChan; ++i) { 3413 result[i] = (float)residual[i]; 3414 } 3415 } else { 3416 for (int i = 0; i < nChan; ++i) { 3417 result[i] = (float)r1[i]; 3418 } 3419 } 3420 3421 return result; 3422 } 3423 3424 void Scantable::selectWaveNumbers(const int whichrow, const std::vector<bool>& chanMask, const bool applyFFT, const std::string& fftMethod, const std::string& fftThresh, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, std::vector<int>& nWaves) 3425 { 3426 nWaves.clear(); 3427 3428 if (applyFFT) { 3429 string fftThAttr; 3430 float fftThSigma; 3431 int fftThTop; 3432 parseThresholdExpression(fftThresh, fftThAttr, fftThSigma, fftThTop); 3433 doSelectWaveNumbers(whichrow, chanMask, fftMethod, fftThSigma, fftThTop, fftThAttr, nWaves); 3434 } 3435 3436 addAuxWaveNumbers(whichrow, addNWaves, rejectNWaves, nWaves); 3437 } 3438 3439 void Scantable::parseThresholdExpression(const std::string& fftThresh, std::string& fftThAttr, float& fftThSigma, int& fftThTop) 3440 { 3441 uInt idxSigma = fftThresh.find("sigma"); 3442 uInt idxTop = fftThresh.find("top"); 3443 3444 if (idxSigma == fftThresh.size() - 5) { 3445 std::istringstream is(fftThresh.substr(0, fftThresh.size() - 5)); 3446 is >> fftThSigma; 3447 fftThAttr = "sigma"; 3448 } else if (idxTop == 0) { 3449 std::istringstream is(fftThresh.substr(3)); 3450 is >> fftThTop; 3451 fftThAttr = "top"; 3452 } else { 3453 bool isNumber = true; 3454 for (uInt i = 0; i < fftThresh.size()-1; ++i) { 3455 char ch = (fftThresh.substr(i, 1).c_str())[0]; 3456 if (!(isdigit(ch) || (fftThresh.substr(i, 1) == "."))) { 3457 isNumber = false; 3458 break; 3459 } 3460 } 3461 if (isNumber) { 3462 std::istringstream is(fftThresh); 3463 is >> fftThSigma; 3464 fftThAttr = "sigma"; 3465 } else { 3466 throw(AipsError("fftthresh has a wrong value")); 3467 } 3468 } 3469 } 3470 3471 void Scantable::doSelectWaveNumbers(const int whichrow, const std::vector<bool>& chanMask, const std::string& fftMethod, const float fftThSigma, const int fftThTop, const std::string& fftThAttr, std::vector<int>& nWaves) 3472 { 3473 std::vector<float> fspec; 3474 if (fftMethod == "fft") { 3475 fspec = execFFT(whichrow, chanMask, false, true); 3476 //} else if (fftMethod == "lsp") { 3477 // fspec = lombScarglePeriodogram(whichrow); 3478 } 3479 3480 if (fftThAttr == "sigma") { 3481 float mean = 0.0; 3482 float mean2 = 0.0; 3483 for (uInt i = 0; i < fspec.size(); ++i) { 3484 mean += fspec[i]; 3485 mean2 += fspec[i]*fspec[i]; 3486 } 3487 mean /= float(fspec.size()); 3488 mean2 /= float(fspec.size()); 3489 float thres = mean + fftThSigma * float(sqrt(mean2 - mean*mean)); 3490 3491 for (uInt i = 0; i < fspec.size(); ++i) { 3492 if (fspec[i] >= thres) { 3493 nWaves.push_back(i); 3494 } 3495 } 3496 3497 } else if (fftThAttr == "top") { 3498 for (int i = 0; i < fftThTop; ++i) { 3499 float max = 0.0; 3500 int maxIdx = 0; 3501 for (uInt j = 0; j < fspec.size(); ++j) { 3502 if (fspec[j] > max) { 3503 max = fspec[j]; 3504 maxIdx = j; 3505 } 3506 } 3507 nWaves.push_back(maxIdx); 3508 fspec[maxIdx] = 0.0; 3509 } 3510 3511 } 3512 3513 if (nWaves.size() > 1) { 3514 sort(nWaves.begin(), nWaves.end()); 3515 } 3516 } 3517 3518 void Scantable::addAuxWaveNumbers(const int whichrow, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, std::vector<int>& nWaves) 3519 { 3520 std::vector<int> tempAddNWaves, tempRejectNWaves; 3521 for (uInt i = 0; i < addNWaves.size(); ++i) { 3522 tempAddNWaves.push_back(addNWaves[i]); 3523 } 3524 if ((tempAddNWaves.size() == 2) && (tempAddNWaves[1] == -999)) { 3525 setWaveNumberListUptoNyquistFreq(whichrow, tempAddNWaves); 3526 } 3527 3528 for (uInt i = 0; i < rejectNWaves.size(); ++i) { 3529 tempRejectNWaves.push_back(rejectNWaves[i]); 3530 } 3531 if ((tempRejectNWaves.size() == 2) && (tempRejectNWaves[1] == -999)) { 3532 setWaveNumberListUptoNyquistFreq(whichrow, tempRejectNWaves); 3533 } 3534 3535 for (uInt i = 0; i < tempAddNWaves.size(); ++i) { 3536 bool found = false; 3537 for (uInt j = 0; j < nWaves.size(); ++j) { 3538 if (nWaves[j] == tempAddNWaves[i]) { 3539 found = true; 3540 break; 3541 } 3542 } 3543 if (!found) nWaves.push_back(tempAddNWaves[i]); 3544 } 3545 3546 for (uInt i = 0; i < tempRejectNWaves.size(); ++i) { 3547 for (std::vector<int>::iterator j = nWaves.begin(); j != nWaves.end(); ) { 3548 if (*j == tempRejectNWaves[i]) { 3549 j = nWaves.erase(j); 3550 } else { 3551 ++j; 3552 } 3553 } 3554 } 3555 3556 if (nWaves.size() > 1) { 3557 sort(nWaves.begin(), nWaves.end()); 3558 unique(nWaves.begin(), nWaves.end()); 3559 } 3560 } 3561 3562 void Scantable::setWaveNumberListUptoNyquistFreq(const int whichrow, std::vector<int>& nWaves) 3563 { 3564 if ((nWaves.size() == 2)&&(nWaves[1] == -999)) { 3565 int val = nWaves[0]; 3566 int nyquistFreq = nchan(getIF(whichrow))/2+1; 3567 nWaves.clear(); 3568 if (val > nyquistFreq) { // for safety, at least nWaves contains a constant; CAS-3759 3569 nWaves.push_back(0); 3570 } 3571 while (val <= nyquistFreq) { 3572 nWaves.push_back(val); 3573 val++; 3574 } 3575 } 3576 } 3577 3578 void Scantable::sinusoidBaseline(const std::vector<bool>& mask, const bool applyFFT, const std::string& fftMethod, const std::string& fftThresh, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, float thresClip, int nIterClip, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 3579 { 3580 try { 3581 ofstream ofs; 3582 String coordInfo = ""; 3583 bool hasSameNchan = true; 3584 bool outTextFile = false; 3585 bool csvFormat = false; 3586 3587 if (blfile != "") { 3588 csvFormat = (blfile.substr(0, 1) == "T"); 3589 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 3590 if (ofs) outTextFile = true; 3591 } 3592 3593 if (outLogger || outTextFile) { 3594 coordInfo = getCoordInfo()[0]; 3595 if (coordInfo == "") coordInfo = "channel"; 3596 hasSameNchan = hasSameNchanOverIFs(); 3597 } 3598 3599 //Fitter fitter = Fitter(); 3600 //fitter.setExpression("sinusoid", nWaves); 3601 //fitter.setIterClipping(thresClip, nIterClip); 3602 3603 int nRow = nrow(); 3604 std::vector<bool> chanMask; 3605 std::vector<int> nWaves; 3606 3607 bool showProgress; 3608 int minNRow; 3609 parseProgressInfo(progressInfo, showProgress, minNRow); 3610 3611 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3612 chanMask = getCompositeChanMask(whichrow, mask); 3613 selectWaveNumbers(whichrow, chanMask, applyFFT, fftMethod, fftThresh, addNWaves, rejectNWaves, nWaves); 3614 3615 //FOR DEBUGGING------------ 3616 /* 3617 if (whichrow < 0) {// == nRow -1) { 3618 cout << "+++ i=" << setw(3) << whichrow << ", IF=" << setw(2) << getIF(whichrow); 3619 if (applyFFT) { 3620 cout << "[ "; 3621 for (uInt j = 0; j < nWaves.size(); ++j) { 3622 cout << nWaves[j] << ", "; 3623 } 3624 cout << " ] " << endl; 3625 } 3626 cout << flush; 3627 } 3628 */ 3629 //------------------------- 3630 3631 //fitBaseline(chanMask, whichrow, fitter); 3632 //setSpectrum((getResidual ? fitter.getResidual() : fitter.getFit()), whichrow); 3633 std::vector<float> params; 3634 int nClipped = 0; 3635 std::vector<float> res = doSinusoidFitting(getSpectrum(whichrow), chanMask, nWaves, params, nClipped, thresClip, nIterClip, getResidual); 3636 setSpectrum(res, whichrow); 3637 // 3638 3639 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "sinusoidBaseline()", params, nClipped); 3640 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 3641 } 3642 3643 if (outTextFile) ofs.close(); 3644 3645 } catch (...) { 3646 throw; 3647 } 3648 } 3649 3650 void Scantable::autoSinusoidBaseline(const std::vector<bool>& mask, const bool applyFFT, const std::string& fftMethod, const std::string& fftThresh, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, float thresClip, int nIterClip, const std::vector<int>& edge, float threshold, int chanAvgLimit, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile) 3651 { 3652 try { 3653 ofstream ofs; 3654 String coordInfo = ""; 3655 bool hasSameNchan = true; 3656 bool outTextFile = false; 3657 bool csvFormat = false; 3658 3659 if (blfile != "") { 3660 csvFormat = (blfile.substr(0, 1) == "T"); 3661 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 3662 if (ofs) outTextFile = true; 3663 } 3664 3665 if (outLogger || outTextFile) { 3666 coordInfo = getCoordInfo()[0]; 3667 if (coordInfo == "") coordInfo = "channel"; 3668 hasSameNchan = hasSameNchanOverIFs(); 3669 } 3670 3671 //Fitter fitter = Fitter(); 3672 //fitter.setExpression("sinusoid", nWaves); 3673 //fitter.setIterClipping(thresClip, nIterClip); 3674 3675 int nRow = nrow(); 3676 std::vector<bool> chanMask; 3677 std::vector<int> nWaves; 3678 3679 int minEdgeSize = getIFNos().size()*2; 3680 STLineFinder lineFinder = STLineFinder(); 3681 lineFinder.setOptions(threshold, 3, chanAvgLimit); 3682 3683 bool showProgress; 3684 int minNRow; 3685 parseProgressInfo(progressInfo, showProgress, minNRow); 3686 3687 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3688 3689 //------------------------------------------------------- 3690 //chanMask = getCompositeChanMask(whichrow, mask, edge, minEdgeSize, lineFinder); 3691 //------------------------------------------------------- 3692 int edgeSize = edge.size(); 3693 std::vector<int> currentEdge; 3694 if (edgeSize >= 2) { 3695 int idx = 0; 3696 if (edgeSize > 2) { 3697 if (edgeSize < minEdgeSize) { 3698 throw(AipsError("Length of edge element info is less than that of IFs")); 3699 } 3700 idx = 2 * getIF(whichrow); 3701 } 3702 currentEdge.push_back(edge[idx]); 3703 currentEdge.push_back(edge[idx+1]); 3704 } else { 3705 throw(AipsError("Wrong length of edge element")); 3706 } 3361 3707 lineFinder.setData(getSpectrum(whichrow)); 3362 3708 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); … … 3738 4084 } 3739 4085 3740 /* for sinusoid. will be merged oncesinusoid is available in fitter (2011/3/10 WK) */4086 /* for chebyshev/sinusoid. will be merged once chebyshev/sinusoid is available in fitter (2011/3/10 WK) */ 3741 4087 void Scantable::outputFittingResult(bool outLogger, bool outTextFile, bool csvFormat, 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 int nClipped) 3742 4088 { -
trunk/src/Scantable.h
r2641 r2645 522 522 const bool outLogger=false, 523 523 const std::string& blfile=""); 524 void chebyshevBaseline(const std::vector<bool>& mask, 525 int order, 526 float thresClip, 527 int nIterClip, 528 bool getResidual=true, 529 const std::string& progressInfo="true,1000", 530 const bool outLogger=false, 531 const std::string& blfile=""); 532 void autoChebyshevBaseline(const std::vector<bool>& mask, 533 int order, 534 float thresClip, 535 int nIterClip, 536 const std::vector<int>& edge, 537 float threshold=3.0, 538 int chanAvgLimit=1, 539 bool getResidual=true, 540 const std::string& progressInfo="true,1000", 541 const bool outLogger=false, 542 const std::string& blfile=""); 524 543 void cubicSplineBaseline(const std::vector<bool>& mask, 525 544 int nPiece, … … 710 729 711 730 void fitBaseline(const std::vector<bool>& mask, int whichrow, Fitter& fitter); 731 double getChebyshevPolynomial(int n, double x); 732 std::vector<float> doChebyshevFitting(const std::vector<float>& data, 733 const std::vector<bool>& mask, 734 int order, 735 std::vector<float>& params, 736 int& nClipped, 737 float thresClip=3.0, 738 int nIterClip=1, 739 bool getResidual=true); 712 740 std::vector<float> doCubicSplineFitting(const std::vector<float>& data, 713 741 const std::vector<bool>& mask, -
trunk/src/ScantableWrapper.h
r2641 r2645 283 283 { table_->autoPolyBaseline(mask, order, edge, threshold, chan_avg_limit, getresidual, showprogress, outlog, blfile); } 284 284 285 void chebyshevBaseline(const std::vector<bool>& mask, int order, float clipthresh, int clipniter, bool getresidual=true, const std::string& showprogress="true,1000", const bool outlog=false, const std::string& blfile="") 286 { table_->chebyshevBaseline(mask, order, clipthresh, clipniter, getresidual, showprogress, outlog, blfile); } 287 288 void autoChebyshevBaseline(const std::vector<bool>& mask, int order, float clipthresh, int clipniter, const std::vector<int>& edge, float threshold=5.0, int chan_avg_limit=1, bool getresidual=true, const std::string& showprogress="true,1000", const bool outlog=false, const std::string& blfile="") 289 { table_->autoChebyshevBaseline(mask, order, clipthresh, clipniter, edge, threshold, chan_avg_limit, getresidual, showprogress, outlog, blfile); } 290 285 291 void cubicSplineBaseline(const std::vector<bool>& mask, int npiece, float clipthresh, int clipniter, bool getresidual=true, const std::string& showprogress="true,1000", const bool outlog=false, const std::string& blfile="") 286 292 { table_->cubicSplineBaseline(mask, npiece, clipthresh, clipniter, getresidual, showprogress, outlog, blfile); } -
trunk/src/python_Scantable.cpp
r2591 r2645 149 149 .def("_poly_baseline", &ScantableWrapper::polyBaseline) 150 150 .def("_auto_poly_baseline", &ScantableWrapper::autoPolyBaseline) 151 .def("_chebyshev_baseline", &ScantableWrapper::chebyshevBaseline) 152 .def("_auto_chebyshev_baseline", &ScantableWrapper::autoChebyshevBaseline) 151 153 .def("_cspline_baseline", &ScantableWrapper::cubicSplineBaseline) 152 154 .def("_auto_cspline_baseline", &ScantableWrapper::autoCubicSplineBaseline)
Note:
See TracChangeset
for help on using the changeset viewer.