- Timestamp:
- 02/25/13 15:49:06 (12 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/STBaselineTable.cpp
r2767 r2773 137 137 } 138 138 139 void STBaselineTable::appenddata(int scanno, int cycleno, 140 int beamno, int ifno, int polno, 141 int freqid, Double time, 142 bool apply, 143 STBaselineFunc::FuncName ftype, 144 int fpar, 145 vector<float> ffpar, 146 Vector<uInt> mask, 147 vector<float> res, 148 float rms, 149 int nchan, 150 float cthres, 151 int citer, 152 float lfthres, 153 int lfavg, 154 vector<int> lfedge) 155 { 156 vector<int> fparam(1); 157 fparam[0] = fpar; 158 159 appenddata(scanno, cycleno, beamno, ifno, polno, freqid, time, 160 apply, ftype, fparam, ffpar, mask, res, rms, nchan, 161 cthres, citer, lfthres, lfavg, lfedge); 162 } 163 164 void STBaselineTable::appenddata(int scanno, int cycleno, 165 int beamno, int ifno, int polno, 166 int freqid, Double time, 167 bool apply, 168 STBaselineFunc::FuncName ftype, 169 vector<int> fpar, 170 vector<float> ffpar, 171 Vector<uInt> mask, 172 vector<float> res, 173 float rms, 174 int nchan, 175 float cthres, 176 int citer, 177 float lfthres, 178 int lfavg, 179 vector<int> lfedge) 180 { 181 Vector<Int> fparam(fpar.size()); 182 for (uInt i = 0; i < fpar.size(); ++i) { 183 fparam[i] = fpar[i]; 184 } 185 Vector<uInt> edge(lfedge.size()); 186 for (uInt i = 0; i < lfedge.size(); ++i) { 187 edge[i] = lfedge[i]; 188 } 189 appenddata(uInt(scanno), uInt(cycleno), uInt(beamno), 190 uInt(ifno), uInt(polno), uInt(freqid), time, 191 Bool(apply), ftype, fparam, Vector<Float>(ffpar), 192 mask, Vector<Float>(res), Float(rms), uInt(nchan), 193 Float(cthres), uInt(citer), 194 Float(lfthres), uInt(lfavg), edge); 195 } 196 139 197 void STBaselineTable::appenddata(uInt scanno, uInt cycleno, 140 198 uInt beamno, uInt ifno, uInt polno, -
trunk/src/STBaselineTable.h
r2767 r2773 59 59 casa::uInt lfavg, 60 60 casa::Vector<casa::uInt> lfedge); 61 void appenddata(int scanno, int cycleno, 62 int beamno, int ifno, int polno, 63 int freqid, casa::Double time, 64 bool apply, 65 STBaselineFunc::FuncName ftype, 66 vector<int> fpar, 67 vector<float> ffpar, 68 casa::Vector<casa::uInt> mask, 69 vector<float> res, 70 float rms, 71 int nchan, 72 float cthres, 73 int citer, 74 float lfthres, 75 int lfavg, 76 vector<int> lfedge); 77 void appenddata(int scanno, int cycleno, 78 int beamno, int ifno, int polno, 79 int freqid, casa::Double time, 80 bool apply, 81 STBaselineFunc::FuncName ftype, 82 int fpar, 83 vector<float> ffpar, 84 casa::Vector<casa::uInt> mask, 85 vector<float> res, 86 float rms, 87 int nchan, 88 float cthres, 89 int citer, 90 float lfthres, 91 int lfavg, 92 vector<int> lfedge); 61 93 void appenddata(casa::uInt scanno, casa::uInt cycleno, 62 94 casa::uInt beamno, casa::uInt ifno, casa::uInt polno, -
trunk/src/Scantable.cpp
r2767 r2773 2492 2492 std::vector<std::string> Scantable::applyBaselineTable(const std::string& bltable, const std::string& outbltable, const bool outbltableexists, const bool overwrite) 2493 2493 { 2494 STBaselineTable * btin = newSTBaselineTable(bltable);2495 2496 Vector<Bool> applyCol = btin ->getApply();2494 STBaselineTable btin = STBaselineTable(bltable); 2495 2496 Vector<Bool> applyCol = btin.getApply(); 2497 2497 int nRowBl = applyCol.size(); 2498 2498 if (nRowBl != nrow()) { … … 2505 2505 bool outBaselineTable = ((outbltable != "") && (!outbltableexists || overwrite)); 2506 2506 bool bltableidentical = (bltable == outbltable); 2507 STBaselineTable * btout = newSTBaselineTable(*this);2508 ROScalarColumn<Double> *tcol = newROScalarColumn<Double>(table_, "TIME");2509 Vector<Double> timeSecCol = tcol ->getColumn();2507 STBaselineTable btout = STBaselineTable(*this); 2508 ROScalarColumn<Double> tcol = ROScalarColumn<Double>(table_, "TIME"); 2509 Vector<Double> timeSecCol = tcol.getColumn(); 2510 2510 2511 2511 for (int whichrow = 0; whichrow < nRowBl; ++whichrow) { … … 2513 2513 std::vector<float> spec = getSpectrum(whichrow); 2514 2514 2515 //--channel mask-- maybe the following choices should be available 2516 std::vector<bool> mask = btin->getMask(whichrow); //use mask_bltable only (default) 2517 //std::vector<bool> mask = getMask(whichrow); // or mask_scantable only 2518 //std::vector<bool> mask = getCompositeChanMask(whichrow, btin->getMask(whichrow)); // or mask_scantable && mask_bltable 2519 2520 STBaselineFunc::FuncName ftype = btin->getFunctionName(whichrow); 2521 std::vector<int> fpar = btin->getFuncParam(whichrow); 2515 std::vector<bool> mask = btin.getMask(whichrow); //use mask_bltable only 2516 2517 STBaselineFunc::FuncName ftype = btin.getFunctionName(whichrow); 2518 std::vector<int> fpar = btin.getFuncParam(whichrow); 2522 2519 std::vector<float> params; 2523 2520 float rms; … … 2529 2526 2530 2527 if (outBaselineTable) { 2531 Vector<Int> fparam(fpar.size());2532 for (uInt j = 0; j < fparam.size(); ++j) {2533 fparam[j] = (Int)fpar[j];2534 }2535 std::vector<int> maskList0;2536 maskList0.clear();2537 for (uInt j = 0; j < mask.size(); ++j) {2538 if (mask[j]) {2539 if ((j == 0)||(j == mask.size()-1)) {2540 maskList0.push_back(j);2541 } else {2542 if ((mask[j])&&(!mask[j-1])) {2543 maskList0.push_back(j);2544 }2545 if ((mask[j])&&(!mask[j+1])) {2546 maskList0.push_back(j);2547 }2548 }2549 }2550 }2551 Vector<uInt> maskList(maskList0.size());2552 for (uInt j = 0; j < maskList0.size(); ++j) {2553 maskList[j] = (uInt)maskList0[j];2554 }2555 2556 2528 if (outbltableexists) { 2557 2529 if (overwrite) { 2558 2530 if (bltableidentical) { 2559 btin ->setresult(uInt(whichrow), Vector<Float>(params), Float(rms));2531 btin.setresult(uInt(whichrow), Vector<Float>(params), Float(rms)); 2560 2532 } else { 2561 btout ->setresult(uInt(whichrow), Vector<Float>(params), Float(rms));2533 btout.setresult(uInt(whichrow), Vector<Float>(params), Float(rms)); 2562 2534 } 2563 2535 } 2564 2536 } else { 2565 btout->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), 2566 uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 2567 uInt(0), timeSecCol[whichrow], Bool(true), ftype, fparam, 2568 Vector<Float>(), maskList, Vector<Float>(params), 2569 Float(rms), uInt(spec.size()), Float(3.0), uInt(0), 2570 Float(0.0), uInt(0), Vector<uInt>()); 2537 btout.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 2538 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 2539 true, ftype, fpar, std::vector<float>(), 2540 getMaskListFromMask(mask), params, rms, spec.size(), 2541 3.0, 0, 0.0, 0, std::vector<int>()); 2571 2542 } 2572 2543 } … … 2576 2547 if (outBaselineTable) { 2577 2548 if (bltableidentical) { 2578 btin ->save(outbltable);2549 btin.save(outbltable); 2579 2550 } else { 2580 btout->save(outbltable); 2581 } 2582 } 2583 delete btin; 2584 delete btout; 2551 btout.save(outbltable); 2552 } 2553 } 2585 2554 2586 2555 return res; … … 2600 2569 } 2601 2570 2602 STBaselineTable * bt = newSTBaselineTable(*this);2603 ROScalarColumn<Double> *tcol = newROScalarColumn<Double>(table_, "TIME");2604 Vector<Double> timeSecCol = tcol ->getColumn();2571 STBaselineTable bt = STBaselineTable(*this); 2572 ROScalarColumn<Double> tcol = ROScalarColumn<Double>(table_, "TIME"); 2573 Vector<Double> timeSecCol = tcol.getColumn(); 2605 2574 2606 2575 if (outBaselineTable && !outbltableexists) { 2607 2576 for (int i = 0; i < nRowSt; ++i) { 2608 bt ->appendbasedata(getScan(i), getCycle(i), getBeam(i), getIF(i), getPol(i),2577 bt.appendbasedata(getScan(i), getCycle(i), getBeam(i), getIF(i), getPol(i), 2609 2578 0, timeSecCol[i]); 2610 bt ->setApply(i, false);2579 bt.setApply(i, false); 2611 2580 } 2612 2581 } … … 2640 2609 fparam[j] = (Int)fpar[j]; 2641 2610 } 2642 std::vector<int> maskList0; 2643 maskList0.clear(); 2644 for (uInt j = 0; j < finalmask.size(); ++j) { 2645 if (finalmask[j]) { 2646 if ((j == 0)||(j == finalmask.size()-1)) { 2647 maskList0.push_back(j); 2648 } else { 2649 if ((finalmask[j])&&(!finalmask[j-1])) { 2650 maskList0.push_back(j); 2651 } 2652 if ((finalmask[j])&&(!finalmask[j+1])) { 2653 maskList0.push_back(j); 2654 } 2655 } 2656 } 2657 } 2658 Vector<uInt> maskList(maskList0.size()); 2659 for (uInt j = 0; j < maskList0.size(); ++j) { 2660 maskList[j] = (uInt)maskList0[j]; 2661 } 2662 2663 bt->setdata(uInt(irow), 2611 2612 bt.setdata(uInt(irow), 2664 2613 uInt(getScan(irow)), uInt(getCycle(irow)), 2665 2614 uInt(getBeam(irow)), uInt(getIF(irow)), uInt(getPol(irow)), 2666 2615 uInt(0), timeSecCol[irow], Bool(true), ftype, fparam, 2667 Vector<Float>(), maskList, Vector<Float>(params),2616 Vector<Float>(), getMaskListFromMask(finalmask), Vector<Float>(params), 2668 2617 Float(rms), uInt(spec.size()), Float(clipth), uInt(clipn), 2669 2618 Float(0.0), uInt(0), Vector<uInt>()); … … 2674 2623 2675 2624 if (outBaselineTable) { 2676 bt->save(outbltable); 2677 } 2678 delete bt; 2625 bt.save(outbltable); 2626 } 2679 2627 2680 2628 return res; 2681 2629 } 2682 2630 2683 std::vector<float> Scantable::doApplyBaselineTable(std::vector<float>& spec, std::vector<bool>& mask, const STBaselineFunc::FuncName ftype, std::vector<int>& fpar, std::vector<float>& params, float&rms) 2631 std::vector<float> Scantable::doApplyBaselineTable(std::vector<float>& spec, 2632 std::vector<bool>& mask, 2633 const STBaselineFunc::FuncName ftype, 2634 std::vector<int>& fpar, 2635 std::vector<float>& params, 2636 float&rms) 2684 2637 { 2685 2638 std::vector<bool> finalmask; … … 2688 2641 } 2689 2642 2690 std::vector<float> Scantable::doSubtractBaseline(std::vector<float>& spec, std::vector<bool>& mask, const STBaselineFunc::FuncName ftype, std::vector<int>& fpar, std::vector<float>& params, float&rms, std::vector<bool>& finalmask, float clipth, int clipn, bool uself, int irow, float lfth, std::vector<int>& lfedge, int lfavg) 2691 { 2692 //---replace mask with (mask AND mask_linefinder). 2643 std::vector<float> Scantable::doSubtractBaseline(std::vector<float>& spec, 2644 std::vector<bool>& mask, 2645 const STBaselineFunc::FuncName ftype, 2646 std::vector<int>& fpar, 2647 std::vector<float>& params, 2648 float&rms, 2649 std::vector<bool>& finalmask, 2650 float clipth, 2651 int clipn, 2652 bool uself, 2653 int irow, 2654 float lfth, 2655 std::vector<int>& lfedge, 2656 int lfavg) 2657 { 2658 //--- replacing mask with (mask AND mask_linefinder). 2693 2659 if (uself) { 2694 2660 STLineFinder lineFinder = STLineFinder(); … … 2885 2851 } 2886 2852 2887 void Scantable::polyBaseline(const std::vector<bool>& mask, int order, float thresClip, int nIterClip, bool getResidual, const std::string& progressInfo, const bool outLogger, const std::string& blfile, const std::string& bltable) 2888 { 2889 /**** 2853 Vector<uInt> Scantable::getMaskListFromMask(const std::vector<bool>& mask) 2854 { 2855 std::vector<int> masklist; 2856 masklist.clear(); 2857 2858 for (uInt i = 0; i < mask.size(); ++i) { 2859 if (mask[i]) { 2860 if ((i == 0)||(i == mask.size()-1)) { 2861 masklist.push_back(i); 2862 } else { 2863 if ((mask[i])&&(!mask[i-1])) { 2864 masklist.push_back(i); 2865 } 2866 if ((mask[i])&&(!mask[i+1])) { 2867 masklist.push_back(i); 2868 } 2869 } 2870 } 2871 } 2872 2873 Vector<uInt> res(masklist.size()); 2874 for (uInt i = 0; i < masklist.size(); ++i) { 2875 res[i] = (uInt)masklist[i]; 2876 } 2877 2878 return res; 2879 } 2880 2881 void Scantable::initialiseBaselining(const std::string& blfile, 2882 ofstream& ofs, 2883 const bool outLogger, 2884 bool& outTextFile, 2885 bool& csvFormat, 2886 String& coordInfo, 2887 bool& hasSameNchan, 2888 const std::string& progressInfo, 2889 bool& showProgress, 2890 int& minNRow, 2891 Vector<Double>& timeSecCol) 2892 { 2893 csvFormat = false; 2894 outTextFile = false; 2895 2896 if (blfile != "") { 2897 csvFormat = (blfile.substr(0, 1) == "T"); 2898 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 2899 if (ofs) outTextFile = true; 2900 } 2901 2902 coordInfo = ""; 2903 hasSameNchan = true; 2904 2905 if (outLogger || outTextFile) { 2906 coordInfo = getCoordInfo()[0]; 2907 if (coordInfo == "") coordInfo = "channel"; 2908 hasSameNchan = hasSameNchanOverIFs(); 2909 } 2910 2911 parseProgressInfo(progressInfo, showProgress, minNRow); 2912 2913 ROScalarColumn<Double> tcol = ROScalarColumn<Double>(table_, "TIME"); 2914 timeSecCol = tcol.getColumn(); 2915 } 2916 2917 void Scantable::finaliseBaselining(const bool outBaselineTable, 2918 STBaselineTable* pbt, 2919 const string& bltable, 2920 const bool outTextFile, 2921 ofstream& ofs) 2922 { 2923 if (outBaselineTable) { 2924 pbt->save(bltable); 2925 } 2926 2927 if (outTextFile) ofs.close(); 2928 } 2929 2930 void Scantable::initLineFinder(const std::vector<int>& edge, 2931 const float threshold, 2932 const int chanAvgLimit, 2933 STLineFinder& lineFinder) 2934 { 2935 if (edge.size() < getIFNos().size()*2) { 2936 throw(AipsError("Length of edge element info is less than that of IFs")); 2937 } 2938 2939 lineFinder.setOptions(threshold, 3, chanAvgLimit); 2940 } 2941 2942 void Scantable::polyBaseline(const std::vector<bool>& mask, int order, 2943 float thresClip, int nIterClip, 2944 bool getResidual, 2945 const std::string& progressInfo, 2946 const bool outLogger, const std::string& blfile, 2947 const std::string& bltable) 2948 { 2949 /****/ 2890 2950 double TimeStart = mathutil::gettimeofday_sec(); 2891 ****/2951 /****/ 2892 2952 2893 2953 try { 2894 2954 ofstream ofs; 2895 String coordInfo = ""; 2896 bool hasSameNchan = true; 2897 bool outTextFile = false; 2898 bool csvFormat = false; 2899 2900 if (blfile != "") { 2901 csvFormat = (blfile.substr(0, 1) == "T"); 2902 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 2903 if (ofs) outTextFile = true; 2904 } 2905 2906 if (outLogger || outTextFile) { 2907 coordInfo = getCoordInfo()[0]; 2908 if (coordInfo == "") coordInfo = "channel"; 2909 hasSameNchan = hasSameNchanOverIFs(); 2910 } 2911 2912 bool showProgress; 2955 String coordInfo; 2956 bool hasSameNchan, outTextFile, csvFormat, showProgress; 2913 2957 int minNRow; 2914 parseProgressInfo(progressInfo, showProgress, minNRow);2915 2916 2958 int nRow = nrow(); 2917 std::vector<bool> chanMask; 2918 std::vector<bool> finalChanMask; 2959 std::vector<bool> chanMask, finalChanMask; 2919 2960 float rms; 2920 2921 //--- 2922 bool outBaselintTable = (bltable != ""); 2923 STBaselineTable* bt = new STBaselineTable(*this); 2924 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME"); 2925 Vector<Double> timeSecCol = tcol->getColumn(); 2926 //--- 2961 bool outBaselineTable = (bltable != ""); 2962 STBaselineTable bt = STBaselineTable(*this); 2963 Vector<Double> timeSecCol; 2964 2965 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 2966 coordInfo, hasSameNchan, 2967 progressInfo, showProgress, minNRow, 2968 timeSecCol); 2969 2970 std::vector<int> nChanNos; 2971 std::vector<std::vector<std::vector<double> > > modelReservoir; 2972 modelReservoir = getPolynomialModelReservoir(order, 2973 &Scantable::getNormalPolynomial, 2974 nChanNos); 2927 2975 2928 2976 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 2929 2977 std::vector<float> sp = getSpectrum(whichrow); 2930 2978 chanMask = getCompositeChanMask(whichrow, mask); 2931 std::vector<float> params(order+1); 2979 2980 std::vector<float> params; 2932 2981 int nClipped = 0; 2933 std::vector<float> res = doPolynomialFitting(sp, chanMask, order, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 2934 2935 //--- 2936 if (outBaselintTable) { 2937 Vector<Int> fparam(1); 2938 fparam[0] = order; 2939 std::vector<int> finalMaskList0; 2940 finalMaskList0.clear(); 2941 for (uInt i = 0; i < finalChanMask.size(); ++i) { 2942 if (finalChanMask[i]) { 2943 if ((i == 0)||(i == finalChanMask.size()-1)) { 2944 finalMaskList0.push_back(i); 2945 } else { 2946 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 2947 finalMaskList0.push_back(i); 2948 } 2949 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 2950 finalMaskList0.push_back(i); 2951 } 2952 } 2953 } 2954 } 2955 Vector<uInt> finalMaskList(finalMaskList0.size()); 2956 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 2957 finalMaskList[i] = (uInt)finalMaskList0[i]; 2958 } 2959 2960 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 2961 uInt(0), 2962 timeSecCol[whichrow], 2963 Bool(true), 2964 STBaselineFunc::Polynomial, 2965 fparam, 2966 Vector<Float>(), 2967 finalMaskList, 2968 Vector<Float>(params), 2969 Float(rms), 2970 uInt(sp.size()), 2971 Float(thresClip), 2972 uInt(nIterClip), 2973 Float(0.0), 2974 uInt(0), 2975 Vector<uInt>()); 2982 std::vector<float> res = doLeastSquareFitting(sp, chanMask, 2983 modelReservoir[getIdxOfNchan(sp.size(), nChanNos)], 2984 params, rms, finalChanMask, 2985 nClipped, thresClip, nIterClip, getResidual); 2986 2987 if (outBaselineTable) { 2988 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 2989 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 2990 true, STBaselineFunc::Polynomial, order, std::vector<float>(), 2991 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 2992 thresClip, nIterClip, 0.0, 0, std::vector<int>()); 2976 2993 } else { 2977 2994 setSpectrum(res, whichrow); 2978 2995 } 2979 //--- 2980 2981 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "chebyshevBaseline()", params, nClipped); 2996 2997 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 2998 coordInfo, hasSameNchan, ofs, "polyBaseline()", 2999 params, nClipped); 2982 3000 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 2983 3001 } 2984 2985 //--- 2986 if (outBaselintTable) { 2987 bt->save(bltable); 2988 } 2989 //--- 2990 delete bt; 2991 2992 if (outTextFile) ofs.close(); 3002 3003 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 2993 3004 2994 3005 } catch (...) { … … 2996 3007 } 2997 3008 2998 /**** 3009 /****/ 2999 3010 double TimeEnd = mathutil::gettimeofday_sec(); 3000 3011 double elapse1 = TimeEnd - TimeStart; 3001 3012 std::cout << "poly-new : " << elapse1 << " (sec.)" << endl; 3002 ****/ 3003 } 3004 3005 void Scantable::autoPolyBaseline(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, const std::string& bltable) 3013 /****/ 3014 } 3015 3016 void Scantable::autoPolyBaseline(const std::vector<bool>& mask, int order, 3017 float thresClip, int nIterClip, 3018 const std::vector<int>& edge, 3019 float threshold, int chanAvgLimit, 3020 bool getResidual, 3021 const std::string& progressInfo, 3022 const bool outLogger, const std::string& blfile, 3023 const std::string& bltable) 3006 3024 { 3007 3025 try { 3008 3026 ofstream ofs; 3009 String coordInfo = ""; 3010 bool hasSameNchan = true; 3011 bool outTextFile = false; 3012 bool csvFormat = false; 3013 3014 if (blfile != "") { 3015 csvFormat = (blfile.substr(0, 1) == "T"); 3016 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 3017 if (ofs) outTextFile = true; 3018 } 3019 3020 if (outLogger || outTextFile) { 3021 coordInfo = getCoordInfo()[0]; 3022 if (coordInfo == "") coordInfo = "channel"; 3023 hasSameNchan = hasSameNchanOverIFs(); 3024 } 3025 3026 bool showProgress; 3027 String coordInfo; 3028 bool hasSameNchan, outTextFile, csvFormat, showProgress; 3027 3029 int minNRow; 3028 parseProgressInfo(progressInfo, showProgress, minNRow); 3029 3030 int minEdgeSize = getIFNos().size()*2; 3030 int nRow = nrow(); 3031 std::vector<bool> chanMask, finalChanMask; 3032 float rms; 3033 bool outBaselineTable = (bltable != ""); 3034 STBaselineTable bt = STBaselineTable(*this); 3035 Vector<Double> timeSecCol; 3031 3036 STLineFinder lineFinder = STLineFinder(); 3032 lineFinder.setOptions(threshold, 3, chanAvgLimit); 3033 3034 int nRow = nrow(); 3035 std::vector<bool> chanMask; 3036 std::vector<bool> finalChanMask;3037 float rms; 3038 3039 //--- 3040 bool outBaselintTable = (bltable != "");3041 STBaselineTable* bt = new STBaselineTable(*this);3042 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME");3043 Vector<Double> timeSecCol = tcol->getColumn(); 3044 //--- 3037 3038 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 3039 coordInfo, hasSameNchan, 3040 progressInfo, showProgress, minNRow, 3041 timeSecCol); 3042 3043 initLineFinder(edge, threshold, chanAvgLimit, lineFinder); 3044 3045 std::vector<int> nChanNos; 3046 std::vector<std::vector<std::vector<double> > > modelReservoir; 3047 modelReservoir = getPolynomialModelReservoir(order, 3048 &Scantable::getNormalPolynomial, 3049 nChanNos); 3045 3050 3046 3051 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3047 3052 std::vector<float> sp = getSpectrum(whichrow); 3048 //-- composote given channel mask and flagtra --------3049 int edgeSize = edge.size();3050 3053 std::vector<int> currentEdge; 3051 currentEdge.clear(); 3052 if (edgeSize >= 2) { 3053 int idx = 0; 3054 if (edgeSize > 2) { 3055 if (edgeSize < minEdgeSize) { 3056 throw(AipsError("Length of edge element info is less than that of IFs")); 3057 } 3058 idx = 2 * getIF(whichrow); 3059 } 3060 currentEdge.push_back(edge[idx]); 3061 currentEdge.push_back(edge[idx+1]); 3062 } else { 3063 throw(AipsError("Wrong length of edge element")); 3064 } 3065 lineFinder.setData(sp); 3066 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 3067 chanMask = lineFinder.getMask(); 3068 //-- composote given channel mask and flagtra END -------- 3069 3070 std::vector<float> params(order+1); 3054 chanMask = getCompositeChanMask(whichrow, mask, edge, currentEdge, lineFinder); 3055 3056 std::vector<float> params; 3071 3057 int nClipped = 0; 3072 std::vector<float> res = doPolynomialFitting(sp, chanMask, order, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 3073 3074 if (outBaselintTable) { 3075 Vector<Int> fparam(1); 3076 fparam[0] = order; 3077 std::vector<int> finalMaskList0; 3078 finalMaskList0.clear(); 3079 for (uInt i = 0; i < finalChanMask.size(); ++i) { 3080 if (finalChanMask[i]) { 3081 if ((i == 0)||(i == finalChanMask.size()-1)) { 3082 finalMaskList0.push_back(i); 3083 } else { 3084 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 3085 finalMaskList0.push_back(i); 3086 } 3087 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 3088 finalMaskList0.push_back(i); 3089 } 3090 } 3091 } 3092 } 3093 Vector<uInt> finalMaskList(finalMaskList0.size()); 3094 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 3095 finalMaskList[i] = (uInt)finalMaskList0[i]; 3096 } 3097 3098 Vector<uInt> cEdge(currentEdge.size()); 3099 for (uInt i = 0; i < currentEdge.size(); ++i) { 3100 cEdge[i] = currentEdge[i]; 3101 } 3102 3103 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 3104 uInt(0), 3105 timeSecCol[whichrow], 3106 Bool(true), 3107 STBaselineFunc::Polynomial, 3108 fparam, 3109 Vector<Float>(), 3110 finalMaskList, 3111 Vector<Float>(params), 3112 Float(rms), 3113 uInt(sp.size()), 3114 Float(thresClip), 3115 uInt(nIterClip), 3116 Float(threshold), 3117 uInt(chanAvgLimit), 3118 cEdge); 3058 std::vector<float> res = doLeastSquareFitting(sp, chanMask, 3059 modelReservoir[getIdxOfNchan(sp.size(), nChanNos)], 3060 params, rms, finalChanMask, 3061 nClipped, thresClip, nIterClip, getResidual); 3062 3063 if (outBaselineTable) { 3064 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 3065 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 3066 true, STBaselineFunc::Polynomial, order, std::vector<float>(), 3067 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 3068 thresClip, nIterClip, threshold, chanAvgLimit, currentEdge); 3119 3069 } else { 3120 3070 setSpectrum(res, whichrow); 3121 3071 } 3122 3072 3123 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoChebyshevBaseline()", params, nClipped); 3073 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 3074 coordInfo, hasSameNchan, ofs, "autoPolyBaseline()", 3075 params, nClipped); 3124 3076 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 3125 3077 } 3126 3078 3127 //--- 3128 if (outBaselintTable) { 3129 bt->save(bltable); 3130 } 3131 //--- 3132 delete bt; 3133 3134 if (outTextFile) ofs.close(); 3079 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 3135 3080 3136 3081 } catch (...) { … … 3139 3084 } 3140 3085 3141 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, const std::string& bltable) 3086 void Scantable::chebyshevBaseline(const std::vector<bool>& mask, int order, 3087 float thresClip, int nIterClip, 3088 bool getResidual, 3089 const std::string& progressInfo, 3090 const bool outLogger, const std::string& blfile, 3091 const std::string& bltable) 3142 3092 { 3143 3093 // … … 3147 3097 try { 3148 3098 ofstream ofs; 3149 String coordInfo = ""; 3150 bool hasSameNchan = true; 3151 bool outTextFile = false; 3152 bool csvFormat = false; 3153 3154 if (blfile != "") { 3155 csvFormat = (blfile.substr(0, 1) == "T"); 3156 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 3157 if (ofs) outTextFile = true; 3158 } 3159 3160 if (outLogger || outTextFile) { 3161 coordInfo = getCoordInfo()[0]; 3162 if (coordInfo == "") coordInfo = "channel"; 3163 hasSameNchan = hasSameNchanOverIFs(); 3164 } 3165 3166 bool showProgress; 3099 String coordInfo; 3100 bool hasSameNchan, outTextFile, csvFormat, showProgress; 3167 3101 int minNRow; 3168 parseProgressInfo(progressInfo, showProgress, minNRow);3169 3170 3102 int nRow = nrow(); 3171 std::vector<bool> chanMask; 3172 std::vector<bool> finalChanMask; 3103 std::vector<bool> chanMask, finalChanMask; 3173 3104 float rms; 3174 3175 //--- 3176 bool outBaselintTable = (bltable != ""); 3177 STBaselineTable* bt = new STBaselineTable(*this); 3178 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME"); 3179 Vector<Double> timeSecCol = tcol->getColumn(); 3180 //--- 3105 bool outBaselineTable = (bltable != ""); 3106 STBaselineTable bt = STBaselineTable(*this); 3107 Vector<Double> timeSecCol; 3108 3109 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 3110 coordInfo, hasSameNchan, 3111 progressInfo, showProgress, minNRow, 3112 timeSecCol); 3113 3114 std::vector<int> nChanNos; 3115 std::vector<std::vector<std::vector<double> > > modelReservoir; 3116 modelReservoir = getPolynomialModelReservoir(order, 3117 &Scantable::getChebyshevPolynomial, 3118 nChanNos); 3181 3119 3182 3120 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3183 3121 std::vector<float> sp = getSpectrum(whichrow); 3184 3122 chanMask = getCompositeChanMask(whichrow, mask); 3185 std::vector<float> params(order+1); 3123 3124 std::vector<float> params; 3186 3125 int nClipped = 0; 3187 std::vector<float> res = doChebyshevFitting(sp, chanMask, order, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 3188 3189 //--- 3190 if (outBaselintTable) { 3191 Vector<Int> fparam(1); 3192 fparam[0] = order; 3193 std::vector<int> finalMaskList0; 3194 finalMaskList0.clear(); 3195 for (uInt i = 0; i < finalChanMask.size(); ++i) { 3196 if (finalChanMask[i]) { 3197 if ((i == 0)||(i == finalChanMask.size()-1)) { 3198 finalMaskList0.push_back(i); 3199 } else { 3200 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 3201 finalMaskList0.push_back(i); 3202 } 3203 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 3204 finalMaskList0.push_back(i); 3205 } 3206 } 3207 } 3208 } 3209 Vector<uInt> finalMaskList(finalMaskList0.size()); 3210 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 3211 finalMaskList[i] = (uInt)finalMaskList0[i]; 3212 } 3213 3214 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 3215 uInt(0), 3216 timeSecCol[whichrow], 3217 Bool(true), 3218 STBaselineFunc::Chebyshev, 3219 fparam, 3220 Vector<Float>(), 3221 finalMaskList, 3222 Vector<Float>(params), 3223 Float(rms), 3224 uInt(sp.size()), 3225 Float(thresClip), 3226 uInt(nIterClip), 3227 Float(0.0), 3228 uInt(0), 3229 Vector<uInt>()); 3126 std::vector<float> res = doLeastSquareFitting(sp, chanMask, 3127 modelReservoir[getIdxOfNchan(sp.size(), nChanNos)], 3128 params, rms, finalChanMask, 3129 nClipped, thresClip, nIterClip, getResidual); 3130 3131 if (outBaselineTable) { 3132 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 3133 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 3134 true, STBaselineFunc::Chebyshev, order, std::vector<float>(), 3135 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 3136 thresClip, nIterClip, 0.0, 0, std::vector<int>()); 3230 3137 } else { 3231 3138 setSpectrum(res, whichrow); 3232 3139 } 3233 //--- 3234 3235 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "chebyshevBaseline()", params, nClipped); 3140 3141 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 3142 coordInfo, hasSameNchan, ofs, "chebyshevBaseline()", 3143 params, nClipped); 3236 3144 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 3237 3145 } 3238 3146 3239 //--- 3240 if (outBaselintTable) { 3241 bt->save(bltable); 3242 } 3243 //--- 3244 delete bt; 3245 3246 if (outTextFile) ofs.close(); 3147 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 3247 3148 3248 3149 } catch (...) { … … 3255 3156 } 3256 3157 3257 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, const std::string& bltable) 3158 void Scantable::autoChebyshevBaseline(const std::vector<bool>& mask, int order, 3159 float thresClip, int nIterClip, 3160 const std::vector<int>& edge, 3161 float threshold, int chanAvgLimit, 3162 bool getResidual, 3163 const std::string& progressInfo, 3164 const bool outLogger, const std::string& blfile, 3165 const std::string& bltable) 3258 3166 { 3259 3167 try { 3260 3168 ofstream ofs; 3261 String coordInfo = ""; 3262 bool hasSameNchan = true; 3263 bool outTextFile = false; 3264 bool csvFormat = false; 3265 3266 if (blfile != "") { 3267 csvFormat = (blfile.substr(0, 1) == "T"); 3268 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 3269 if (ofs) outTextFile = true; 3270 } 3271 3272 if (outLogger || outTextFile) { 3273 coordInfo = getCoordInfo()[0]; 3274 if (coordInfo == "") coordInfo = "channel"; 3275 hasSameNchan = hasSameNchanOverIFs(); 3276 } 3277 3278 bool showProgress; 3169 String coordInfo; 3170 bool hasSameNchan, outTextFile, csvFormat, showProgress; 3279 3171 int minNRow; 3280 parseProgressInfo(progressInfo, showProgress, minNRow); 3281 3282 int minEdgeSize = getIFNos().size()*2; 3172 int nRow = nrow(); 3173 std::vector<bool> chanMask, finalChanMask; 3174 float rms; 3175 bool outBaselineTable = (bltable != ""); 3176 STBaselineTable bt = STBaselineTable(*this); 3177 Vector<Double> timeSecCol; 3283 3178 STLineFinder lineFinder = STLineFinder(); 3284 lineFinder.setOptions(threshold, 3, chanAvgLimit); 3285 3286 int nRow = nrow(); 3287 std::vector<bool> chanMask; 3288 std::vector<bool> finalChanMask;3289 float rms; 3290 3291 //--- 3292 bool outBaselintTable = (bltable != "");3293 STBaselineTable* bt = new STBaselineTable(*this);3294 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME");3295 Vector<Double> timeSecCol = tcol->getColumn(); 3296 //--- 3179 3180 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 3181 coordInfo, hasSameNchan, 3182 progressInfo, showProgress, minNRow, 3183 timeSecCol); 3184 3185 initLineFinder(edge, threshold, chanAvgLimit, lineFinder); 3186 3187 std::vector<int> nChanNos; 3188 std::vector<std::vector<std::vector<double> > > modelReservoir; 3189 modelReservoir = getPolynomialModelReservoir(order, 3190 &Scantable::getChebyshevPolynomial, 3191 nChanNos); 3297 3192 3298 3193 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3299 3194 std::vector<float> sp = getSpectrum(whichrow); 3300 //-- composote given channel mask and flagtra --------3301 int edgeSize = edge.size();3302 3195 std::vector<int> currentEdge; 3303 currentEdge.clear(); 3304 if (edgeSize >= 2) { 3305 int idx = 0; 3306 if (edgeSize > 2) { 3307 if (edgeSize < minEdgeSize) { 3308 throw(AipsError("Length of edge element info is less than that of IFs")); 3309 } 3310 idx = 2 * getIF(whichrow); 3311 } 3312 currentEdge.push_back(edge[idx]); 3313 currentEdge.push_back(edge[idx+1]); 3314 } else { 3315 throw(AipsError("Wrong length of edge element")); 3316 } 3317 lineFinder.setData(sp); 3318 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 3319 chanMask = lineFinder.getMask(); 3320 //-- composote given channel mask and flagtra END -------- 3321 3322 std::vector<float> params(order+1); 3196 chanMask = getCompositeChanMask(whichrow, mask, edge, currentEdge, lineFinder); 3197 3198 std::vector<float> params; 3323 3199 int nClipped = 0; 3324 std::vector<float> res = doChebyshevFitting(sp, chanMask, order, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 3325 3326 if (outBaselintTable) { 3327 Vector<Int> fparam(1); 3328 fparam[0] = order; 3329 std::vector<int> finalMaskList0; 3330 finalMaskList0.clear(); 3331 for (uInt i = 0; i < finalChanMask.size(); ++i) { 3332 if (finalChanMask[i]) { 3333 if ((i == 0)||(i == finalChanMask.size()-1)) { 3334 finalMaskList0.push_back(i); 3335 } else { 3336 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 3337 finalMaskList0.push_back(i); 3338 } 3339 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 3340 finalMaskList0.push_back(i); 3341 } 3342 } 3343 } 3344 } 3345 Vector<uInt> finalMaskList(finalMaskList0.size()); 3346 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 3347 finalMaskList[i] = (uInt)finalMaskList0[i]; 3348 } 3349 3350 Vector<uInt> cEdge(currentEdge.size()); 3351 for (uInt i = 0; i < currentEdge.size(); ++i) { 3352 cEdge[i] = currentEdge[i]; 3353 } 3354 3355 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 3356 uInt(0), 3357 timeSecCol[whichrow], 3358 Bool(true), 3359 STBaselineFunc::Chebyshev, 3360 fparam, 3361 Vector<Float>(), 3362 finalMaskList, 3363 Vector<Float>(params), 3364 Float(rms), 3365 uInt(sp.size()), 3366 Float(thresClip), 3367 uInt(nIterClip), 3368 Float(threshold), 3369 uInt(chanAvgLimit), 3370 cEdge); 3200 std::vector<float> res = doLeastSquareFitting(sp, chanMask, 3201 modelReservoir[getIdxOfNchan(sp.size(), nChanNos)], 3202 params, rms, finalChanMask, 3203 nClipped, thresClip, nIterClip, getResidual); 3204 3205 if (outBaselineTable) { 3206 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 3207 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 3208 true, STBaselineFunc::Chebyshev, order, std::vector<float>(), 3209 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 3210 thresClip, nIterClip, threshold, chanAvgLimit, currentEdge); 3371 3211 } else { 3372 3212 setSpectrum(res, whichrow); 3373 3213 } 3374 3214 3375 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoChebyshevBaseline()", params, nClipped); 3215 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 3216 coordInfo, hasSameNchan, ofs, "autoChebyshevBaseline()", 3217 params, nClipped); 3376 3218 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 3377 3219 } 3378 3220 3379 //--- 3380 if (outBaselintTable) { 3381 bt->save(bltable); 3382 } 3383 //--- 3384 delete bt; 3385 3386 if (outTextFile) ofs.close(); 3221 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 3387 3222 3388 3223 } catch (...) { … … 3448 3283 std::vector<int> pieceEdges;//(order+1); //order = npiece 3449 3284 nparam = order + 3; 3450 //params.resize(4*order);3451 3285 res = doCubicSplineFitting(spec, mask, order, false, pieceEdges, params, rms, finalChanMask, nClipped); 3452 3286 } else if (blfunc == "sinusoid") { … … 3568 3402 } 3569 3403 3570 std::vector<float> Scantable::doPolynomialFitting(const std::vector<float>& data, const std::vector<bool>& mask, int order, std::vector<float>& params, float& rms, std::vector<bool>& finalmask, float clipth, int clipn) 3404 std::vector<float> Scantable::doPolynomialFitting(const std::vector<float>& data, 3405 const std::vector<bool>& mask, 3406 int order, 3407 std::vector<float>& params, 3408 float& rms, 3409 std::vector<bool>& finalmask, 3410 float clipth, 3411 int clipn) 3571 3412 { 3572 3413 int nClipped = 0; … … 3574 3415 } 3575 3416 3576 std::vector<float> Scantable::doPolynomialFitting(const std::vector<float>& data, const std::vector<bool>& mask, int order, std::vector<float>& params, float& rms, std::vector<bool>& finalMask, int& nClipped, float thresClip, int nIterClip, bool getResidual) 3577 { 3578 return doLeastSquareFitting(data, mask, &Scantable::getNormalPolynomial, order, params, rms, finalMask, nClipped, thresClip, nIterClip, getResidual); 3579 } 3580 3581 std::vector<float> Scantable::doChebyshevFitting(const std::vector<float>& data, const std::vector<bool>& mask, int order, std::vector<float>& params, float& rms, std::vector<bool>& finalmask, float clipth, int clipn) 3417 std::vector<float> Scantable::doPolynomialFitting(const std::vector<float>& data, 3418 const std::vector<bool>& mask, 3419 int order, 3420 std::vector<float>& params, 3421 float& rms, 3422 std::vector<bool>& finalMask, 3423 int& nClipped, 3424 float thresClip, 3425 int nIterClip, 3426 bool getResidual) 3427 { 3428 return doLeastSquareFitting(data, mask, 3429 getPolynomialModel(order, data.size(), &Scantable::getNormalPolynomial), 3430 params, rms, finalMask, 3431 nClipped, thresClip, nIterClip, 3432 getResidual); 3433 } 3434 3435 std::vector<float> Scantable::doChebyshevFitting(const std::vector<float>& data, 3436 const std::vector<bool>& mask, 3437 int order, 3438 std::vector<float>& params, 3439 float& rms, 3440 std::vector<bool>& finalmask, 3441 float clipth, 3442 int clipn) 3582 3443 { 3583 3444 int nClipped = 0; … … 3585 3446 } 3586 3447 3587 std::vector<float> Scantable::doChebyshevFitting(const std::vector<float>& data, const std::vector<bool>& mask, int order, std::vector<float>& params, float& rms, std::vector<bool>& finalMask, int& nClipped, float thresClip, int nIterClip, bool getResidual) 3588 { 3589 return doLeastSquareFitting(data, mask, &Scantable::getChebyshevPolynomial, order, params, rms, finalMask, nClipped, thresClip, nIterClip, getResidual); 3590 } 3591 3592 std::vector<float> Scantable::doLeastSquareFitting(const std::vector<float>& data, const std::vector<bool>& mask, double (Scantable::*pfunc)(int, double), int order, std::vector<float>& params, float& rms, std::vector<bool>& finalMask, int& nClipped, float thresClip, int nIterClip, bool getResidual) 3593 { 3594 if (data.size() != mask.size()) { 3595 throw(AipsError("data and mask sizes are not identical")); 3596 } 3597 if (order < 0) { 3598 throw(AipsError("maximum order of polynomial must not be negative.")); 3599 } 3600 3601 int nChan = data.size(); 3602 3603 finalMask.clear(); 3604 finalMask.resize(nChan); 3605 3606 std::vector<int> maskArray; 3607 std::vector<int> x; 3608 for (int i = 0; i < nChan; ++i) { 3609 maskArray.push_back(mask[i] ? 1 : 0); 3610 if (mask[i]) { 3611 x.push_back(i); 3612 } 3613 finalMask[i] = mask[i]; 3614 } 3615 3616 int initNData = x.size(); 3617 3618 int nData = initNData; 3619 int nDOF = order + 1; //number of parameters to solve. 3620 3621 // xArray : contains elemental values for computing the least-square matrix. 3622 // xArray.size() is nDOF and xArray[*].size() is nChan. 3623 // Each xArray element are as follows: 3448 std::vector<float> Scantable::doChebyshevFitting(const std::vector<float>& data, 3449 const std::vector<bool>& mask, 3450 int order, 3451 std::vector<float>& params, 3452 float& rms, 3453 std::vector<bool>& finalMask, 3454 int& nClipped, 3455 float thresClip, 3456 int nIterClip, 3457 bool getResidual) 3458 { 3459 return doLeastSquareFitting(data, mask, 3460 getPolynomialModel(order, data.size(), &Scantable::getChebyshevPolynomial), 3461 params, rms, finalMask, 3462 nClipped, thresClip, nIterClip, 3463 getResidual); 3464 } 3465 3466 std::vector<std::vector<double> > Scantable::getPolynomialModel(int order, int nchan, double (Scantable::*pfunc)(int, double)) 3467 { 3468 // model : contains model values for computing the least-square matrix. 3469 // model.size() is nmodel and model[*].size() is nchan. 3470 // Each model element are as follows: 3624 3471 // 3625 3472 // (for normal polynomials) 3626 // xArray[0] = {1.0, 1.0, 1.0, ..., 1.0},3627 // xArray[1] = {0.0, 1.0, 2.0, ..., (nChan-1)}3628 // xArray[n-1] = ...,3629 // xArray[n] = {0.0^n, 1.0^n, 2.0^n, ..., (nChan-1)^n}3473 // model[0] = {1.0, 1.0, 1.0, ..., 1.0}, 3474 // model[1] = {0.0, 1.0, 2.0, ..., (nchan-1)} 3475 // model[n-1] = ..., 3476 // model[n] = {0.0^n, 1.0^n, 2.0^n, ..., (nchan-1)^n} 3630 3477 // where (0 <= n <= order) 3631 3478 // 3632 3479 // (for Chebyshev polynomials) 3633 // xArray[0] = {T0(-1), T0(2/(nChan-1)-1), T0(4/(nChan-1)-1), ..., T0(1)},3634 // xArray[n-1] = ...,3635 // xArray[n] = {Tn(-1), Tn(2/(nChan-1)-1), Tn(4/(nChan-1)-1), ..., Tn(1)}3480 // model[0] = {T0(-1), T0(2/(nchan-1)-1), T0(4/(nchan-1)-1), ..., T0(1)}, 3481 // model[n-1] = ..., 3482 // model[n] = {Tn(-1), Tn(2/(nchan-1)-1), Tn(4/(nchan-1)-1), ..., Tn(1)} 3636 3483 // where (0 <= n <= order), 3637 std::vector<std::vector<double> > xArray; 3638 double xFactor, xShift; 3484 3485 int nmodel = order + 1; 3486 std::vector<std::vector<double> > model(nmodel, std::vector<double>(nchan)); 3487 3488 double stretch, shift; 3639 3489 if (pfunc == &Scantable::getChebyshevPolynomial) { 3640 xFactor = 2.0/(double)(nChan - 1);3641 xShift= -1.0;3490 stretch = 2.0/(double)(nchan - 1); 3491 shift = -1.0; 3642 3492 } else { 3643 xFactor = 1.0; 3644 xShift = 0.0; 3493 stretch = 1.0; 3494 shift = 0.0; 3495 } 3496 3497 for (int i = 0; i < nmodel; ++i) { 3498 for (int j = 0; j < nchan; ++j) { 3499 model[i][j] = (this->*pfunc)(i, stretch*(double)j + shift); 3500 } 3501 } 3502 3503 return model; 3504 } 3505 3506 std::vector<std::vector<std::vector<double> > > Scantable::getPolynomialModelReservoir(int order, 3507 double (Scantable::*pfunc)(int, double), 3508 std::vector<int>& nChanNos) 3509 { 3510 std::vector<std::vector<std::vector<double> > > res; 3511 res.clear(); 3512 nChanNos.clear(); 3513 3514 std::vector<uint> ifNos = getIFNos(); 3515 for (uint i = 0; i < ifNos.size(); ++i) { 3516 int currNchan = nchan(ifNos[i]); 3517 bool hasDifferentNchan = (i == 0); 3518 for (uint j = 0; j < i; ++j) { 3519 if (currNchan != nchan(ifNos[j])) { 3520 hasDifferentNchan = true; 3521 break; 3522 } 3523 } 3524 if (hasDifferentNchan) { 3525 res.push_back(getPolynomialModel(order, currNchan, pfunc)); 3526 nChanNos.push_back(currNchan); 3527 } 3528 } 3529 3530 return res; 3531 } 3532 3533 std::vector<float> Scantable::doLeastSquareFitting(const std::vector<float>& data, 3534 const std::vector<bool>& mask, 3535 const std::vector<std::vector<double> >& model, 3536 std::vector<float>& params, 3537 float& rms, 3538 std::vector<bool>& finalMask, 3539 int& nClipped, 3540 float thresClip, 3541 int nIterClip, 3542 bool getResidual) 3543 { 3544 int nDOF = model.size(); 3545 int nChan = data.size(); 3546 3547 if (nDOF == 0) { 3548 throw(AipsError("no model data given")); 3549 } 3550 if (nChan < 2) { 3551 throw(AipsError("data size is too few")); 3552 } 3553 if (nChan != (int)mask.size()) { 3554 throw(AipsError("data and mask sizes are not identical")); 3645 3555 } 3646 3556 for (int i = 0; i < nDOF; ++i) { 3647 std::vector<double> xs; 3648 xs.clear(); 3649 for (int j = 0; j < nChan; ++j) { 3650 xs.push_back((this->*pfunc)(i, xFactor*(double)j + xShift)); 3651 } 3652 xArray.push_back(xs); 3653 } 3654 3655 std::vector<double> z1, r1, residual; 3557 if (nChan != (int)model[i].size()) { 3558 throw(AipsError("data and model sizes are not identical")); 3559 } 3560 } 3561 3562 params.clear(); 3563 params.resize(nDOF); 3564 3565 finalMask.clear(); 3566 finalMask.resize(nChan); 3567 3568 std::vector<int> maskArray(nChan); 3569 int j = 0; 3656 3570 for (int i = 0; i < nChan; ++i) { 3657 z1.push_back((double)data[i]); 3658 r1.push_back(0.0); 3659 residual.push_back(0.0); 3571 maskArray[i] = mask[i] ? 1 : 0; 3572 if (mask[i]) { 3573 j++; 3574 } 3575 finalMask[i] = mask[i]; 3576 } 3577 3578 int initNData = j; 3579 int nData = initNData; 3580 3581 std::vector<double> z1(nChan), r1(nChan), residual(nChan); 3582 for (int i = 0; i < nChan; ++i) { 3583 z1[i] = (double)data[i]; 3584 r1[i] = 0.0; 3585 residual[i] = 0.0; 3660 3586 } 3661 3587 … … 3681 3607 for (int i = 0; i < nDOF; ++i) { 3682 3608 for (int j = i; j < nDOF; ++j) { 3683 xMatrix[i][j] += xArray[i][k] * xArray[j][k];3609 xMatrix[i][j] += model[i][k] * model[j][k]; 3684 3610 } 3685 zMatrix[i] += z1[k] * xArray[i][k];3611 zMatrix[i] += z1[k] * model[i][k]; 3686 3612 } 3687 3613 … … 3699 3625 } 3700 3626 3701 std::vector<double> invDiag ;3627 std::vector<double> invDiag(nDOF); 3702 3628 for (int i = 0; i < nDOF; ++i) { 3703 invDiag .push_back(1.0/xMatrix[i][i]);3629 invDiag[i] = 1.0 / xMatrix[i][i]; 3704 3630 for (int j = 0; j < nDOF; ++j) { 3705 3631 xMatrix[i][j] *= invDiag[i]; … … 3711 3637 if (i != k) { 3712 3638 double factor1 = xMatrix[k][k]; 3639 double invfactor1 = 1.0 / factor1; 3713 3640 double factor2 = xMatrix[i][k]; 3714 3641 for (int j = k; j < 2*nDOF; ++j) { 3715 3642 xMatrix[i][j] *= factor1; 3716 3643 xMatrix[i][j] -= xMatrix[k][j]*factor2; 3717 xMatrix[i][j] /=factor1;3644 xMatrix[i][j] *= invfactor1; 3718 3645 } 3719 3646 } 3720 3647 } 3721 double xDiag =xMatrix[k][k];3648 double invXDiag = 1.0 / xMatrix[k][k]; 3722 3649 for (int j = k; j < 2*nDOF; ++j) { 3723 xMatrix[k][j] /= xDiag;3650 xMatrix[k][j] *= invXDiag; 3724 3651 } 3725 3652 } … … 3730 3657 } 3731 3658 } 3732 //compute a vector y which consists of the coefficients of Chebyshev polynomials. 3733 std::vector<double> y; 3734 params.clear(); 3659 //compute a vector y in which coefficients of the best-fit 3660 //model functions are stored. 3661 //in case of polynomials, y consists of (a0,a1,a2,...) 3662 //where ai is the coefficient of the term x^i. 3663 //in case of sinusoids, y consists of (a0,s1,c1,s2,c2,...) 3664 //where a0 is constant term and s* and c* are of sine 3665 //and cosine functions, respectively. 3666 std::vector<double> y(nDOF); 3735 3667 for (int i = 0; i < nDOF; ++i) { 3736 y .push_back(0.0);3668 y[i] = 0.0; 3737 3669 for (int j = 0; j < nDOF; ++j) { 3738 3670 y[i] += xMatrix[i][nDOF+j]*zMatrix[j]; 3739 3671 } 3740 params .push_back(y[i]);3672 params[i] = (float)y[i]; 3741 3673 } 3742 3674 … … 3744 3676 r1[i] = y[0]; 3745 3677 for (int j = 1; j < nDOF; ++j) { 3746 r1[i] += y[j]* xArray[j][i];3678 r1[i] += y[j]*model[j][i]; 3747 3679 } 3748 3680 residual[i] = z1[i] - r1[i]; … … 3782 3714 nClipped = initNData - nData; 3783 3715 3784 std::vector<float> result; 3785 result.clear(); 3716 std::vector<float> result(nChan); 3786 3717 if (getResidual) { 3787 3718 for (int i = 0; i < nChan; ++i) { 3788 result .push_back((float)residual[i]);3719 result[i] = (float)residual[i]; 3789 3720 } 3790 3721 } else { 3791 3722 for (int i = 0; i < nChan; ++i) { 3792 result .push_back((float)r1[i]);3723 result[i] = (float)r1[i]; 3793 3724 } 3794 3725 } … … 3797 3728 } 3798 3729 3799 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, const std::string& bltable) 3800 { 3730 void Scantable::cubicSplineBaseline(const std::vector<bool>& mask, int nPiece, 3731 float thresClip, int nIterClip, 3732 bool getResidual, 3733 const std::string& progressInfo, 3734 const bool outLogger, const std::string& blfile, 3735 const std::string& bltable) 3736 { 3737 /****/ 3738 double TimeStart = mathutil::gettimeofday_sec(); 3739 /****/ 3740 3801 3741 try { 3802 3742 ofstream ofs; 3803 String coordInfo = ""; 3804 bool hasSameNchan = true; 3805 bool outTextFile = false; 3806 bool csvFormat = false; 3807 3808 if (blfile != "") { 3809 csvFormat = (blfile.substr(0, 1) == "T"); 3810 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 3811 if (ofs) outTextFile = true; 3812 } 3813 3814 if (outLogger || outTextFile) { 3815 coordInfo = getCoordInfo()[0]; 3816 if (coordInfo == "") coordInfo = "channel"; 3817 hasSameNchan = hasSameNchanOverIFs(); 3818 } 3819 3820 bool showProgress; 3743 String coordInfo; 3744 bool hasSameNchan, outTextFile, csvFormat, showProgress; 3821 3745 int minNRow; 3822 parseProgressInfo(progressInfo, showProgress, minNRow);3823 3824 3746 int nRow = nrow(); 3825 std::vector<bool> chanMask; 3826 std::vector<bool> finalChanMask; 3747 std::vector<bool> chanMask, finalChanMask; 3827 3748 float rms; 3828 3829 //--- 3830 bool outBaselintTable = (bltable != ""); 3831 STBaselineTable* bt = new STBaselineTable(*this); 3832 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME"); 3833 Vector<Double> timeSecCol = tcol->getColumn(); 3834 //--- 3835 3749 bool outBaselineTable = (bltable != ""); 3750 STBaselineTable bt = STBaselineTable(*this); 3751 Vector<Double> timeSecCol; 3752 3753 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 3754 coordInfo, hasSameNchan, 3755 progressInfo, showProgress, minNRow, 3756 timeSecCol); 3757 3758 std::vector<int> nChanNos; 3759 std::vector<std::vector<std::vector<double> > > modelReservoir; 3760 modelReservoir = getPolynomialModelReservoir(3, 3761 &Scantable::getNormalPolynomial, 3762 nChanNos); 3836 3763 3837 3764 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3838 3765 std::vector<float> sp = getSpectrum(whichrow); 3839 3766 chanMask = getCompositeChanMask(whichrow, mask); 3840 std::vector<int> pieceEdges;//(nPiece+1); 3841 std::vector<float> params;//(nPiece*4); 3767 3768 std::vector<int> pieceEdges; 3769 std::vector<float> params; 3842 3770 int nClipped = 0; 3843 std::vector<float> res = doCubicSplineFitting(sp, chanMask, nPiece, false, pieceEdges, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 3844 3845 //--- 3846 if (outBaselintTable) { 3847 Vector<Int> fparam(nPiece); 3848 for (uInt i = 0; i < fparam.size(); ++i) { 3849 fparam[i] = pieceEdges[i]; 3850 } 3851 std::vector<int> finalMaskList0; 3852 finalMaskList0.clear(); 3853 for (uInt i = 0; i < finalChanMask.size(); ++i) { 3854 if (finalChanMask[i]) { 3855 if ((i == 0)||(i == finalChanMask.size()-1)) { 3856 finalMaskList0.push_back(i); 3857 } else { 3858 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 3859 finalMaskList0.push_back(i); 3860 } 3861 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 3862 finalMaskList0.push_back(i); 3863 } 3864 } 3865 } 3866 } 3867 Vector<uInt> finalMaskList(finalMaskList0.size()); 3868 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 3869 finalMaskList[i] = (uInt)finalMaskList0[i]; 3870 } 3871 3872 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 3873 uInt(0), 3874 timeSecCol[whichrow], 3875 Bool(true), 3876 STBaselineFunc::CSpline, 3877 fparam, 3878 Vector<Float>(), 3879 finalMaskList, 3880 Vector<Float>(params), 3881 Float(rms), 3882 uInt(sp.size()), 3883 Float(thresClip), 3884 uInt(nIterClip), 3885 Float(0.0), 3886 uInt(0), 3887 Vector<uInt>()); 3771 std::vector<float> res = doCubicSplineLeastSquareFitting(sp, chanMask, 3772 modelReservoir[getIdxOfNchan(sp.size(), nChanNos)], 3773 nPiece, false, pieceEdges, params, rms, finalChanMask, 3774 nClipped, thresClip, nIterClip, getResidual); 3775 3776 if (outBaselineTable) { 3777 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 3778 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 3779 true, STBaselineFunc::CSpline, pieceEdges, std::vector<float>(), 3780 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 3781 thresClip, nIterClip, 0.0, 0, std::vector<int>()); 3888 3782 } else { 3889 3783 setSpectrum(res, whichrow); 3890 3784 } 3891 //--- 3892 3893 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "cubicSplineBaseline()", pieceEdges, params, nClipped); 3785 3786 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 3787 coordInfo, hasSameNchan, ofs, "cubicSplineBaseline()", 3788 pieceEdges, params, nClipped); 3894 3789 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 3895 3790 } 3896 3791 3897 //--- 3898 if (outBaselintTable) { 3899 bt->save(bltable); 3900 } 3901 //--- 3902 delete bt; 3903 3904 if (outTextFile) ofs.close(); 3792 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 3905 3793 3906 3794 } catch (...) { 3907 3795 throw; 3908 3796 } 3909 } 3910 3911 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, const std::string& bltable) 3797 3798 /****/ 3799 double TimeEnd = mathutil::gettimeofday_sec(); 3800 double elapse1 = TimeEnd - TimeStart; 3801 std::cout << "cspline-new : " << elapse1 << " (sec.)" << endl; 3802 /****/ 3803 } 3804 3805 void Scantable::autoCubicSplineBaseline(const std::vector<bool>& mask, int nPiece, 3806 float thresClip, int nIterClip, 3807 const std::vector<int>& edge, 3808 float threshold, int chanAvgLimit, 3809 bool getResidual, 3810 const std::string& progressInfo, 3811 const bool outLogger, const std::string& blfile, 3812 const std::string& bltable) 3912 3813 { 3913 3814 try { 3914 3815 ofstream ofs; 3915 String coordInfo = ""; 3916 bool hasSameNchan = true; 3917 bool outTextFile = false; 3918 bool csvFormat = false; 3919 3920 if (blfile != "") { 3921 csvFormat = (blfile.substr(0, 1) == "T"); 3922 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 3923 if (ofs) outTextFile = true; 3924 } 3925 3926 if (outLogger || outTextFile) { 3927 coordInfo = getCoordInfo()[0]; 3928 if (coordInfo == "") coordInfo = "channel"; 3929 hasSameNchan = hasSameNchanOverIFs(); 3930 } 3931 3932 bool showProgress; 3816 String coordInfo; 3817 bool hasSameNchan, outTextFile, csvFormat, showProgress; 3933 3818 int minNRow; 3934 parseProgressInfo(progressInfo, showProgress, minNRow); 3935 3936 int minEdgeSize = getIFNos().size()*2; 3819 int nRow = nrow(); 3820 std::vector<bool> chanMask, finalChanMask; 3821 float rms; 3822 bool outBaselineTable = (bltable != ""); 3823 STBaselineTable bt = STBaselineTable(*this); 3824 Vector<Double> timeSecCol; 3937 3825 STLineFinder lineFinder = STLineFinder(); 3938 lineFinder.setOptions(threshold, 3, chanAvgLimit); 3939 3940 int nRow = nrow(); 3941 std::vector<bool> chanMask; 3942 std::vector<bool> finalChanMask;3943 float rms; 3944 3945 //--- 3946 bool outBaselintTable = (bltable != "");3947 STBaselineTable* bt = new STBaselineTable(*this);3948 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME");3949 Vector<Double> timeSecCol = tcol->getColumn(); 3950 //--- 3826 3827 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 3828 coordInfo, hasSameNchan, 3829 progressInfo, showProgress, minNRow, 3830 timeSecCol); 3831 3832 initLineFinder(edge, threshold, chanAvgLimit, lineFinder); 3833 3834 std::vector<int> nChanNos; 3835 std::vector<std::vector<std::vector<double> > > modelReservoir; 3836 modelReservoir = getPolynomialModelReservoir(3, 3837 &Scantable::getNormalPolynomial, 3838 nChanNos); 3951 3839 3952 3840 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 3953 3841 std::vector<float> sp = getSpectrum(whichrow); 3954 //-- composote given channel mask and flagtra --------3955 int edgeSize = edge.size();3956 3842 std::vector<int> currentEdge; 3957 currentEdge.clear(); 3958 if (edgeSize >= 2) { 3959 int idx = 0; 3960 if (edgeSize > 2) { 3961 if (edgeSize < minEdgeSize) { 3962 throw(AipsError("Length of edge element info is less than that of IFs")); 3963 } 3964 idx = 2 * getIF(whichrow); 3965 } 3966 currentEdge.push_back(edge[idx]); 3967 currentEdge.push_back(edge[idx+1]); 3968 } else { 3969 throw(AipsError("Wrong length of edge element")); 3970 } 3971 lineFinder.setData(sp); 3972 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 3973 chanMask = lineFinder.getMask(); 3974 //-- composote given channel mask and flagtra END -------- 3975 3976 std::vector<int> pieceEdges;//(nPiece+1); 3977 std::vector<float> params;//(nPiece*4); 3843 chanMask = getCompositeChanMask(whichrow, mask, edge, currentEdge, lineFinder); 3844 3845 std::vector<int> pieceEdges; 3846 std::vector<float> params; 3978 3847 int nClipped = 0; 3979 std::vector<float> res = doCubicSplineFitting(sp, chanMask, nPiece, false, pieceEdges, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 3980 3981 if (outBaselintTable) { 3982 Vector<Int> fparam(nPiece); 3983 for (uInt i = 0; i < fparam.size(); ++i) { 3984 fparam[i] = pieceEdges[i]; 3985 } 3986 std::vector<int> finalMaskList0; 3987 finalMaskList0.clear(); 3988 for (uInt i = 0; i < finalChanMask.size(); ++i) { 3989 if (finalChanMask[i]) { 3990 if ((i == 0)||(i == finalChanMask.size()-1)) { 3991 finalMaskList0.push_back(i); 3992 } else { 3993 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 3994 finalMaskList0.push_back(i); 3995 } 3996 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 3997 finalMaskList0.push_back(i); 3998 } 3999 } 4000 } 4001 } 4002 Vector<uInt> finalMaskList(finalMaskList0.size()); 4003 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 4004 finalMaskList[i] = (uInt)finalMaskList0[i]; 4005 } 4006 4007 Vector<uInt> cEdge(currentEdge.size()); 4008 for (uInt i = 0; i < currentEdge.size(); ++i) { 4009 cEdge[i] = currentEdge[i]; 4010 } 4011 4012 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 4013 uInt(0), 4014 timeSecCol[whichrow], 4015 Bool(true), 4016 STBaselineFunc::CSpline, 4017 fparam, 4018 Vector<Float>(), 4019 finalMaskList, 4020 Vector<Float>(params), 4021 Float(rms), 4022 uInt(sp.size()), 4023 Float(thresClip), 4024 uInt(nIterClip), 4025 Float(threshold), 4026 uInt(chanAvgLimit), 4027 cEdge); 3848 std::vector<float> res = doCubicSplineLeastSquareFitting(sp, chanMask, 3849 modelReservoir[getIdxOfNchan(sp.size(), nChanNos)], 3850 nPiece, false, pieceEdges, params, rms, finalChanMask, 3851 nClipped, thresClip, nIterClip, getResidual); 3852 3853 if (outBaselineTable) { 3854 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 3855 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 3856 true, STBaselineFunc::CSpline, pieceEdges, std::vector<float>(), 3857 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 3858 thresClip, nIterClip, threshold, chanAvgLimit, currentEdge); 4028 3859 } else { 4029 3860 setSpectrum(res, whichrow); 4030 3861 } 4031 3862 4032 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoCubicSplineBaseline()", pieceEdges, params, nClipped); 3863 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 3864 coordInfo, hasSameNchan, ofs, "autoCubicSplineBaseline()", 3865 pieceEdges, params, nClipped); 4033 3866 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 4034 3867 } 4035 3868 4036 //--- 4037 if (outBaselintTable) { 4038 bt->save(bltable); 4039 } 4040 //--- 4041 delete bt; 4042 4043 if (outTextFile) ofs.close(); 3869 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 4044 3870 4045 3871 } catch (...) { … … 4048 3874 } 4049 3875 4050 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, const std::vector<bool>& mask, std::vector<int>& idxEdge, std::vector<float>& params, float& rms, std::vector<bool>& finalmask, float clipth, int clipn) 3876 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, 3877 const std::vector<bool>& mask, 3878 std::vector<int>& idxEdge, 3879 std::vector<float>& params, 3880 float& rms, 3881 std::vector<bool>& finalmask, 3882 float clipth, 3883 int clipn) 4051 3884 { 4052 3885 int nClipped = 0; … … 4054 3887 } 4055 3888 4056 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& rms, std::vector<bool>& finalmask, float clipth, int clipn) 3889 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, 3890 const std::vector<bool>& mask, 3891 int nPiece, 3892 std::vector<int>& idxEdge, 3893 std::vector<float>& params, 3894 float& rms, 3895 std::vector<bool>& finalmask, 3896 float clipth, 3897 int clipn) 4057 3898 { 4058 3899 int nClipped = 0; … … 4060 3901 } 4061 3902 4062 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, const std::vector<bool>& mask, int nPiece, bool useGivenPieceBoundary, std::vector<int>& idxEdge, std::vector<float>& params, float& rms, std::vector<bool>& finalMask, int& nClipped, float thresClip, int nIterClip, bool getResidual) 4063 { 4064 if (data.size() != mask.size()) { 4065 throw(AipsError("data and mask sizes are not identical")); 3903 std::vector<float> Scantable::doCubicSplineFitting(const std::vector<float>& data, 3904 const std::vector<bool>& mask, 3905 int nPiece, 3906 bool useGivenPieceBoundary, 3907 std::vector<int>& idxEdge, 3908 std::vector<float>& params, 3909 float& rms, 3910 std::vector<bool>& finalMask, 3911 int& nClipped, 3912 float thresClip, 3913 int nIterClip, 3914 bool getResidual) 3915 { 3916 return doCubicSplineLeastSquareFitting(data, mask, 3917 getPolynomialModel(3, data.size(), &Scantable::getNormalPolynomial), 3918 nPiece, useGivenPieceBoundary, idxEdge, 3919 params, rms, finalMask, 3920 nClipped, thresClip, nIterClip, 3921 getResidual); 3922 } 3923 3924 std::vector<float> Scantable::doCubicSplineLeastSquareFitting(const std::vector<float>& data, 3925 const std::vector<bool>& mask, 3926 const std::vector<std::vector<double> >& model, 3927 int nPiece, 3928 bool useGivenPieceBoundary, 3929 std::vector<int>& idxEdge, 3930 std::vector<float>& params, 3931 float& rms, 3932 std::vector<bool>& finalMask, 3933 int& nClipped, 3934 float thresClip, 3935 int nIterClip, 3936 bool getResidual) 3937 { 3938 int nDOF = nPiece + 3; //number of independent parameters to solve, namely, 4+(nPiece-1). 3939 int nModel = model.size(); 3940 int nChan = data.size(); 3941 3942 if (nModel != 4) { 3943 throw(AipsError("model size must be 4.")); 4066 3944 } 4067 3945 if (nPiece < 1) { 4068 3946 throw(AipsError("number of the sections must be one or more")); 4069 3947 } 4070 4071 int nChan = data.size(); 3948 if (nChan < 2*nPiece) { 3949 throw(AipsError("data size is too few")); 3950 } 3951 if (nChan != (int)mask.size()) { 3952 throw(AipsError("data and mask sizes are not identical")); 3953 } 3954 for (int i = 0; i < nModel; ++i) { 3955 if (nChan != (int)model[i].size()) { 3956 throw(AipsError("data and model sizes are not identical")); 3957 } 3958 } 3959 3960 params.clear(); 3961 params.resize(nPiece*nModel); 4072 3962 4073 3963 finalMask.clear(); … … 4085 3975 finalMask[i] = mask[i]; 4086 3976 } 3977 4087 3978 int initNData = j; 3979 int nData = initNData; 4088 3980 4089 3981 if (initNData < nPiece) { … … 4114 4006 } 4115 4007 4116 params.clear(); 4117 params.resize(nPiece*4); 4118 4119 int nData = initNData; 4120 int nDOF = nPiece + 3; //number of parameters to solve, namely, 4+(nPiece-1). 4121 4122 std::vector<double> x1(nChan), x2(nChan), x3(nChan); 4123 std::vector<double> z1(nChan), x1z1(nChan), x2z1(nChan), x3z1(nChan); 4124 std::vector<double> r1(nChan), residual(nChan); 4008 std::vector<double> z1(nChan), r1(nChan), residual(nChan); 4125 4009 for (int i = 0; i < nChan; ++i) { 4126 double di = (double)i; 4127 double dD = (double)data[i]; 4128 x1[i] = di; 4129 x2[i] = di*di; 4130 x3[i] = di*di*di; 4131 z1[i] = dD; 4132 x1z1[i] = dD*di; 4133 x2z1[i] = dD*di*di; 4134 x3z1[i] = dD*di*di*di; 4135 r1[i] = 0.0; 4010 z1[i] = (double)data[i]; 4011 r1[i] = 0.0; 4136 4012 residual[i] = 0.0; 4137 4013 } … … 4155 4031 for (int n = 0; n < nPiece; ++n) { 4156 4032 int nUseDataInPiece = 0; 4157 for (int i = idxEdge[n]; i < idxEdge[n+1]; ++i) { 4158 4159 if (maskArray[i] == 0) continue; 4160 4161 xMatrix[0][0] += 1.0; 4162 xMatrix[0][1] += x1[i]; 4163 xMatrix[0][2] += x2[i]; 4164 xMatrix[0][3] += x3[i]; 4165 xMatrix[1][1] += x2[i]; 4166 xMatrix[1][2] += x3[i]; 4167 xMatrix[1][3] += x2[i]*x2[i]; 4168 xMatrix[2][2] += x2[i]*x2[i]; 4169 xMatrix[2][3] += x3[i]*x2[i]; 4170 xMatrix[3][3] += x3[i]*x3[i]; 4171 zMatrix[0] += z1[i]; 4172 zMatrix[1] += x1z1[i]; 4173 zMatrix[2] += x2z1[i]; 4174 zMatrix[3] += x3z1[i]; 4175 4176 for (int j = 0; j < n; ++j) { 4177 double q = 1.0 - x1[i]*invEdge[j]; 4033 for (int k = idxEdge[n]; k < idxEdge[n+1]; ++k) { 4034 4035 if (maskArray[k] == 0) continue; 4036 4037 for (int i = 0; i < nModel; ++i) { 4038 for (int j = i; j < nModel; ++j) { 4039 xMatrix[i][j] += model[i][k] * model[j][k]; 4040 } 4041 zMatrix[i] += z1[k] * model[i][k]; 4042 } 4043 4044 for (int i = 0; i < n; ++i) { 4045 double q = 1.0 - model[1][k]*invEdge[i]; 4178 4046 q = q*q*q; 4179 xMatrix[0][j+4] += q; 4180 xMatrix[1][j+4] += q*x1[i]; 4181 xMatrix[2][j+4] += q*x2[i]; 4182 xMatrix[3][j+4] += q*x3[i]; 4183 for (int k = 0; k < j; ++k) { 4184 double r = 1.0 - x1[i]*invEdge[k]; 4047 for (int j = 0; j < nModel; ++j) { 4048 xMatrix[j][i+nModel] += q * model[j][k]; 4049 } 4050 for (int j = 0; j < i; ++j) { 4051 double r = 1.0 - model[1][k]*invEdge[j]; 4185 4052 r = r*r*r; 4186 xMatrix[ k+4][j+4] += r*q;4053 xMatrix[j+nModel][i+nModel] += r*q; 4187 4054 } 4188 xMatrix[ j+4][j+4] += q*q;4189 zMatrix[ j+4] += q*z1[i];4055 xMatrix[i+nModel][i+nModel] += q*q; 4056 zMatrix[i+nModel] += q*z1[k]; 4190 4057 } 4191 4058 … … 4215 4082 std::vector<double> invDiag(nDOF); 4216 4083 for (int i = 0; i < nDOF; ++i) { 4217 invDiag[i] = 1.0 /xMatrix[i][i];4084 invDiag[i] = 1.0 / xMatrix[i][i]; 4218 4085 for (int j = 0; j < nDOF; ++j) { 4219 4086 xMatrix[i][j] *= invDiag[i]; … … 4225 4092 if (i != k) { 4226 4093 double factor1 = xMatrix[k][k]; 4094 double invfactor1 = 1.0 / factor1; 4227 4095 double factor2 = xMatrix[i][k]; 4228 4096 for (int j = k; j < 2*nDOF; ++j) { 4229 4097 xMatrix[i][j] *= factor1; 4230 4098 xMatrix[i][j] -= xMatrix[k][j]*factor2; 4231 xMatrix[i][j] /=factor1;4099 xMatrix[i][j] *= invfactor1; 4232 4100 } 4233 4101 } 4234 4102 } 4235 double xDiag =xMatrix[k][k];4103 double invXDiag = 1.0 / xMatrix[k][k]; 4236 4104 for (int j = k; j < 2*nDOF; ++j) { 4237 xMatrix[k][j] /= xDiag;4105 xMatrix[k][j] *= invXDiag; 4238 4106 } 4239 4107 } … … 4256 4124 } 4257 4125 4258 double a0 = y[0];4259 double a1 = y[1];4260 double a2 = y[2];4261 double a3 = y[3];4126 std::vector<double> a(nModel); 4127 for (int i = 0; i < nModel; ++i) { 4128 a[i] = y[i]; 4129 } 4262 4130 4263 4131 int j = 0; 4264 4132 for (int n = 0; n < nPiece; ++n) { 4265 4133 for (int i = idxEdge[n]; i < idxEdge[n+1]; ++i) { 4266 r1[i] = a0 + a1*x1[i] + a2*x2[i] + a3*x3[i]; 4267 } 4268 params[j] = a0; 4269 params[j+1] = a1; 4270 params[j+2] = a2; 4271 params[j+3] = a3; 4272 j += 4; 4134 r1[i] = 0.0; 4135 for (int j = 0; j < nModel; ++j) { 4136 r1[i] += a[j] * model[j][i]; 4137 } 4138 } 4139 for (int i = 0; i < nModel; ++i) { 4140 params[j+i] = a[i]; 4141 } 4142 j += nModel; 4273 4143 4274 4144 if (n == nPiece-1) break; 4275 4145 4276 double d = y[ 4+n];4146 double d = y[n+nModel]; 4277 4147 double iE = invEdge[n]; 4278 a 0 +=d;4279 a 1 -= 3.0*d*iE;4280 a 2 += 3.0*d*iE*iE;4281 a 3 -= d*iE*iE*iE;4148 a[0] += d; 4149 a[1] -= 3.0 * d * iE; 4150 a[2] += 3.0 * d * iE * iE; 4151 a[3] -= d * iE * iE * iE; 4282 4152 } 4283 4153 … … 4359 4229 } 4360 4230 4361 void Scantable::selectWaveNumbers(const int whichrow, const std::vector<bool>& chanMask, const std::string& fftInfo, const std::vector<int>& addNWaves, const std::vector<int>& rejectNWaves, std::vector<int>& nWaves) 4362 //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)4363 { 4364 bool applyFFT;4231 std::vector<int> Scantable::selectWaveNumbers(const std::vector<int>& addNWaves, 4232 const std::vector<int>& rejectNWaves) 4233 { 4234 std::vector<bool> chanMask; 4365 4235 std::string fftMethod; 4366 4236 std::string fftThresh; 4367 4237 4238 return selectWaveNumbers(0, chanMask, false, fftMethod, fftThresh, addNWaves, rejectNWaves); 4239 } 4240 4241 std::vector<int> Scantable::selectWaveNumbers(const int whichrow, 4242 const std::vector<bool>& chanMask, 4243 const bool applyFFT, 4244 const std::string& fftMethod, 4245 const std::string& fftThresh, 4246 const std::vector<int>& addNWaves, 4247 const std::vector<int>& rejectNWaves) 4248 { 4249 std::vector<int> nWaves; 4368 4250 nWaves.clear(); 4369 4251 4370 parseFFTInfo(fftInfo, applyFFT, fftMethod, fftThresh);4371 4252 if (applyFFT) { 4372 4253 string fftThAttr; 4373 4254 float fftThSigma; 4374 4255 int fftThTop; 4375 parse ThresholdExpression(fftThresh, fftThAttr, fftThSigma, fftThTop);4256 parseFFTThresholdInfo(fftThresh, fftThAttr, fftThSigma, fftThTop); 4376 4257 doSelectWaveNumbers(whichrow, chanMask, fftMethod, fftThSigma, fftThTop, fftThAttr, nWaves); 4377 4258 } 4378 4259 4379 4260 addAuxWaveNumbers(whichrow, addNWaves, rejectNWaves, nWaves); 4261 4262 return nWaves; 4263 } 4264 4265 int Scantable::getIdxOfNchan(const int nChan, const std::vector<int>& nChanNos) 4266 { 4267 int idx = -1; 4268 for (uint i = 0; i < nChanNos.size(); ++i) { 4269 if (nChan == nChanNos[i]) { 4270 idx = i; 4271 break; 4272 } 4273 } 4274 4275 if (idx < 0) { 4276 throw(AipsError("nChan not found in nChhanNos.")); 4277 } 4278 4279 return idx; 4380 4280 } 4381 4281 … … 4396 4296 } 4397 4297 4398 void Scantable::parse ThresholdExpression(const std::string& fftThresh, std::string& fftThAttr, float& fftThSigma, int& fftThTop)4298 void Scantable::parseFFTThresholdInfo(const std::string& fftThresh, std::string& fftThAttr, float& fftThSigma, int& fftThTop) 4399 4299 { 4400 4300 uInt idxSigma = fftThresh.find("sigma"); … … 4536 4436 } 4537 4437 4538 void Scantable::sinusoidBaseline(const std::vector<bool>& mask, const std::string& fftInfo, 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, const std::string& bltable) 4539 { 4438 void Scantable::sinusoidBaseline(const std::vector<bool>& mask, const std::string& fftInfo, 4439 const std::vector<int>& addNWaves, 4440 const std::vector<int>& rejectNWaves, 4441 float thresClip, int nIterClip, 4442 bool getResidual, 4443 const std::string& progressInfo, 4444 const bool outLogger, const std::string& blfile, 4445 const std::string& bltable) 4446 { 4447 /****/ 4448 double TimeStart = mathutil::gettimeofday_sec(); 4449 /****/ 4450 4540 4451 try { 4541 4452 ofstream ofs; 4542 String coordInfo = ""; 4543 bool hasSameNchan = true; 4544 bool outTextFile = false; 4545 bool csvFormat = false; 4546 4547 if (blfile != "") { 4548 csvFormat = (blfile.substr(0, 1) == "T"); 4549 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 4550 if (ofs) outTextFile = true; 4551 } 4552 4553 if (outLogger || outTextFile) { 4554 coordInfo = getCoordInfo()[0]; 4555 if (coordInfo == "") coordInfo = "channel"; 4556 hasSameNchan = hasSameNchanOverIFs(); 4557 } 4558 4559 bool showProgress; 4453 String coordInfo; 4454 bool hasSameNchan, outTextFile, csvFormat, showProgress; 4560 4455 int minNRow; 4561 parseProgressInfo(progressInfo, showProgress, minNRow);4562 4563 4456 int nRow = nrow(); 4564 std::vector<bool> chanMask; 4457 std::vector<bool> chanMask, finalChanMask; 4458 float rms; 4459 bool outBaselineTable = (bltable != ""); 4460 STBaselineTable bt = STBaselineTable(*this); 4461 Vector<Double> timeSecCol; 4462 4463 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 4464 coordInfo, hasSameNchan, 4465 progressInfo, showProgress, minNRow, 4466 timeSecCol); 4467 4468 bool applyFFT; 4469 std::string fftMethod, fftThresh; 4470 parseFFTInfo(fftInfo, applyFFT, fftMethod, fftThresh); 4471 4565 4472 std::vector<int> nWaves; 4566 std::vector<bool> finalChanMask; 4567 float rms; 4568 4569 //--- 4570 bool outBaselintTable = (bltable != ""); 4571 STBaselineTable* bt = new STBaselineTable(*this); 4572 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME"); 4573 Vector<Double> timeSecCol = tcol->getColumn(); 4574 //--- 4473 std::vector<int> nChanNos; 4474 std::vector<std::vector<std::vector<double> > > modelReservoir; 4475 if (!applyFFT) { 4476 nWaves = selectWaveNumbers(addNWaves, rejectNWaves); 4477 modelReservoir = getSinusoidModelReservoir(nWaves, nChanNos); 4478 } 4575 4479 4576 4480 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 4577 4481 std::vector<float> sp = getSpectrum(whichrow); 4578 4482 chanMask = getCompositeChanMask(whichrow, mask); 4579 selectWaveNumbers(whichrow, chanMask, fftInfo, addNWaves, rejectNWaves, nWaves); 4483 std::vector<std::vector<double> > model; 4484 if (applyFFT) { 4485 nWaves = selectWaveNumbers(whichrow, chanMask, true, fftMethod, fftThresh, 4486 addNWaves, rejectNWaves); 4487 model = getSinusoidModel(nWaves, sp.size()); 4488 } else { 4489 model = modelReservoir[getIdxOfNchan(sp.size(), nChanNos)]; 4490 } 4580 4491 4581 4492 std::vector<float> params; 4582 4493 int nClipped = 0; 4583 std::vector<float> res = doSinusoidFitting(sp, chanMask, nWaves, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 4584 4585 //--- 4586 if (outBaselintTable) { 4587 uInt nparam = nWaves.size(); 4588 Vector<Int> fparam(nparam); 4589 for (uInt i = 0; i < nparam; ++i) { 4590 fparam[i] = nWaves[i]; 4591 } 4592 std::vector<int> finalMaskList0; 4593 finalMaskList0.clear(); 4594 for (uInt i = 0; i < finalChanMask.size(); ++i) { 4595 if (finalChanMask[i]) { 4596 if ((i == 0)||(i == finalChanMask.size()-1)) { 4597 finalMaskList0.push_back(i); 4598 } else { 4599 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 4600 finalMaskList0.push_back(i); 4601 } 4602 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 4603 finalMaskList0.push_back(i); 4604 } 4605 } 4606 } 4607 } 4608 Vector<uInt> finalMaskList(finalMaskList0.size()); 4609 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 4610 finalMaskList[i] = (uInt)finalMaskList0[i]; 4611 } 4612 4613 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 4614 uInt(0), 4615 timeSecCol[whichrow], 4616 Bool(true), 4617 STBaselineFunc::Sinusoid, 4618 fparam, 4619 Vector<Float>(), 4620 finalMaskList, 4621 Vector<Float>(params), 4622 Float(rms), 4623 uInt(sp.size()), 4624 Float(thresClip), 4625 uInt(nIterClip), 4626 Float(0.0), 4627 uInt(0), 4628 Vector<uInt>()); 4494 std::vector<float> res = doLeastSquareFitting(sp, chanMask, model, 4495 params, rms, finalChanMask, 4496 nClipped, thresClip, nIterClip, getResidual); 4497 4498 if (outBaselineTable) { 4499 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 4500 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 4501 true, STBaselineFunc::Sinusoid, nWaves, std::vector<float>(), 4502 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 4503 thresClip, nIterClip, 0.0, 0, std::vector<int>()); 4629 4504 } else { 4630 4505 setSpectrum(res, whichrow); 4631 4506 } 4632 //--- 4633 4634 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "sinusoidBaseline()", params, nClipped); 4507 4508 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 4509 coordInfo, hasSameNchan, ofs, "sinusoidBaseline()", 4510 params, nClipped); 4635 4511 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 4636 4512 } 4637 4513 4638 //--- 4639 if (outBaselintTable) { 4640 bt->save(bltable); 4641 } 4642 //--- 4643 delete bt; 4644 4645 if (outTextFile) ofs.close(); 4514 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 4646 4515 4647 4516 } catch (...) { 4648 4517 throw; 4649 4518 } 4650 } 4651 4652 void Scantable::autoSinusoidBaseline(const std::vector<bool>& mask, const std::string& fftInfo, 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, const std::string& bltable) 4653 //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, const std::string& bltable) 4519 4520 /****/ 4521 double TimeEnd = mathutil::gettimeofday_sec(); 4522 double elapse1 = TimeEnd - TimeStart; 4523 std::cout << "sinusoid-old : " << elapse1 << " (sec.)" << endl; 4524 /****/ 4525 } 4526 4527 void Scantable::autoSinusoidBaseline(const std::vector<bool>& mask, const std::string& fftInfo, 4528 const std::vector<int>& addNWaves, 4529 const std::vector<int>& rejectNWaves, 4530 float thresClip, int nIterClip, 4531 const std::vector<int>& edge, 4532 float threshold, int chanAvgLimit, 4533 bool getResidual, 4534 const std::string& progressInfo, 4535 const bool outLogger, const std::string& blfile, 4536 const std::string& bltable) 4654 4537 { 4655 4538 try { 4656 4539 ofstream ofs; 4657 String coordInfo = ""; 4658 bool hasSameNchan = true; 4659 bool outTextFile = false; 4660 bool csvFormat = false; 4661 4662 if (blfile != "") { 4663 csvFormat = (blfile.substr(0, 1) == "T"); 4664 ofs.open(blfile.substr(1).c_str(), ios::out | ios::app); 4665 if (ofs) outTextFile = true; 4666 } 4667 4668 if (outLogger || outTextFile) { 4669 coordInfo = getCoordInfo()[0]; 4670 if (coordInfo == "") coordInfo = "channel"; 4671 hasSameNchan = hasSameNchanOverIFs(); 4672 } 4673 4674 bool showProgress; 4540 String coordInfo; 4541 bool hasSameNchan, outTextFile, csvFormat, showProgress; 4675 4542 int minNRow; 4676 parseProgressInfo(progressInfo, showProgress, minNRow); 4677 4678 int minEdgeSize = getIFNos().size()*2; 4543 int nRow = nrow(); 4544 std::vector<bool> chanMask, finalChanMask; 4545 float rms; 4546 bool outBaselineTable = (bltable != ""); 4547 STBaselineTable bt = STBaselineTable(*this); 4548 Vector<Double> timeSecCol; 4679 4549 STLineFinder lineFinder = STLineFinder(); 4680 lineFinder.setOptions(threshold, 3, chanAvgLimit); 4681 4682 int nRow = nrow(); 4683 std::vector<bool> chanMask; 4550 4551 initialiseBaselining(blfile, ofs, outLogger, outTextFile, csvFormat, 4552 coordInfo, hasSameNchan, 4553 progressInfo, showProgress, minNRow, 4554 timeSecCol); 4555 4556 initLineFinder(edge, threshold, chanAvgLimit, lineFinder); 4557 4558 bool applyFFT; 4559 string fftMethod, fftThresh; 4560 parseFFTInfo(fftInfo, applyFFT, fftMethod, fftThresh); 4561 4684 4562 std::vector<int> nWaves; 4685 std::vector<bool> finalChanMask; 4686 float rms; 4687 4688 //--- 4689 bool outBaselintTable = (bltable != ""); 4690 STBaselineTable* bt = new STBaselineTable(*this); 4691 ROScalarColumn<Double> *tcol = new ROScalarColumn<Double>(table_, "TIME"); 4692 Vector<Double> timeSecCol = tcol->getColumn(); 4693 //--- 4563 std::vector<int> nChanNos; 4564 std::vector<std::vector<std::vector<double> > > modelReservoir; 4565 if (!applyFFT) { 4566 nWaves = selectWaveNumbers(addNWaves, rejectNWaves); 4567 modelReservoir = getSinusoidModelReservoir(nWaves, nChanNos); 4568 } 4694 4569 4695 4570 for (int whichrow = 0; whichrow < nRow; ++whichrow) { 4696 4571 std::vector<float> sp = getSpectrum(whichrow); 4697 //-- composote given channel mask and flagtra --------4698 int edgeSize = edge.size();4699 4572 std::vector<int> currentEdge; 4700 currentEdge.clear(); 4701 if (edgeSize >= 2) { 4702 int idx = 0; 4703 if (edgeSize > 2) { 4704 if (edgeSize < minEdgeSize) { 4705 throw(AipsError("Length of edge element info is less than that of IFs")); 4706 } 4707 idx = 2 * getIF(whichrow); 4708 } 4709 currentEdge.push_back(edge[idx]); 4710 currentEdge.push_back(edge[idx+1]); 4573 chanMask = getCompositeChanMask(whichrow, mask, edge, currentEdge, lineFinder); 4574 std::vector<std::vector<double> > model; 4575 if (applyFFT) { 4576 nWaves = selectWaveNumbers(whichrow, chanMask, true, fftMethod, fftThresh, 4577 addNWaves, rejectNWaves); 4578 model = getSinusoidModel(nWaves, sp.size()); 4711 4579 } else { 4712 throw(AipsError("Wrong length of edge element")); 4713 } 4714 lineFinder.setData(sp); 4715 lineFinder.findLines(getCompositeChanMask(whichrow, mask), currentEdge, whichrow); 4716 chanMask = lineFinder.getMask(); 4717 //-- composote given channel mask and flagtra END -------- 4718 selectWaveNumbers(whichrow, chanMask, fftInfo, addNWaves, rejectNWaves, nWaves); 4580 model = modelReservoir[getIdxOfNchan(sp.size(), nChanNos)]; 4581 } 4719 4582 4720 4583 std::vector<float> params; 4721 4584 int nClipped = 0; 4722 std::vector<float> res = doSinusoidFitting(sp, chanMask, nWaves, params, rms, finalChanMask, nClipped, thresClip, nIterClip, getResidual); 4723 4724 //--- 4725 if (outBaselintTable) { 4726 uInt nparam = nWaves.size(); 4727 Vector<Int> fparam(nparam); 4728 for (uInt i = 0; i < nparam; ++i) { 4729 fparam[i] = nWaves[i]; 4730 } 4731 std::vector<int> finalMaskList0; 4732 finalMaskList0.clear(); 4733 for (uInt i = 0; i < finalChanMask.size(); ++i) { 4734 if (finalChanMask[i]) { 4735 if ((i == 0)||(i == finalChanMask.size()-1)) { 4736 finalMaskList0.push_back(i); 4737 } else { 4738 if ((finalChanMask[i])&&(!finalChanMask[i-1])) { 4739 finalMaskList0.push_back(i); 4740 } 4741 if ((finalChanMask[i])&&(!finalChanMask[i+1])) { 4742 finalMaskList0.push_back(i); 4743 } 4744 } 4745 } 4746 } 4747 Vector<uInt> finalMaskList(finalMaskList0.size()); 4748 for (uInt i = 0; i < finalMaskList0.size(); ++i) { 4749 finalMaskList[i] = (uInt)finalMaskList0[i]; 4750 } 4751 4752 Vector<uInt> cEdge(currentEdge.size()); 4753 for (uInt i = 0; i < currentEdge.size(); ++i) { 4754 cEdge[i] = currentEdge[i]; 4755 } 4756 4757 bt->appenddata(uInt(getScan(whichrow)), uInt(getCycle(whichrow)), uInt(getBeam(whichrow)), uInt(getIF(whichrow)), uInt(getPol(whichrow)), 4758 uInt(0), 4759 timeSecCol[whichrow], 4760 Bool(true), 4761 STBaselineFunc::Sinusoid, 4762 fparam, 4763 Vector<Float>(), 4764 finalMaskList, 4765 Vector<Float>(params), 4766 Float(rms), 4767 uInt(sp.size()), 4768 Float(thresClip), 4769 uInt(nIterClip), 4770 Float(threshold), 4771 uInt(chanAvgLimit), 4772 cEdge); 4585 std::vector<float> res = doLeastSquareFitting(sp, chanMask, model, 4586 params, rms, finalChanMask, 4587 nClipped, thresClip, nIterClip, getResidual); 4588 4589 if (outBaselineTable) { 4590 bt.appenddata(getScan(whichrow), getCycle(whichrow), getBeam(whichrow), 4591 getIF(whichrow), getPol(whichrow), 0, timeSecCol[whichrow], 4592 true, STBaselineFunc::Sinusoid, nWaves, std::vector<float>(), 4593 getMaskListFromMask(finalChanMask), params, rms, sp.size(), 4594 thresClip, nIterClip, threshold, chanAvgLimit, currentEdge); 4773 4595 } else { 4774 4596 setSpectrum(res, whichrow); 4775 4597 } 4776 //--- 4777 4778 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, coordInfo, hasSameNchan, ofs, "autoSinusoidBaseline()", params, nClipped); 4598 4599 outputFittingResult(outLogger, outTextFile, csvFormat, chanMask, whichrow, 4600 coordInfo, hasSameNchan, ofs, "autoSinusoidBaseline()", 4601 params, nClipped); 4779 4602 showProgressOnTerminal(whichrow, nRow, showProgress, minNRow); 4780 4603 } 4781 4604 4782 //--- 4783 if (outBaselintTable) { 4784 bt->save(bltable); 4785 } 4786 //--- 4787 delete bt; 4788 4789 if (outTextFile) ofs.close(); 4605 finaliseBaselining(outBaselineTable, &bt, bltable, outTextFile, ofs); 4790 4606 4791 4607 } catch (...) { … … 4794 4610 } 4795 4611 4796 std::vector<float> Scantable::doSinusoidFitting(const std::vector<float>& data, const std::vector<bool>& mask, const std::vector<int>& waveNumbers, std::vector<float>& params, float& rms, std::vector<bool>& finalmask, float clipth, int clipn) 4612 std::vector<float> Scantable::doSinusoidFitting(const std::vector<float>& data, 4613 const std::vector<bool>& mask, 4614 const std::vector<int>& waveNumbers, 4615 std::vector<float>& params, 4616 float& rms, 4617 std::vector<bool>& finalmask, 4618 float clipth, 4619 int clipn) 4797 4620 { 4798 4621 int nClipped = 0; … … 4800 4623 } 4801 4624 4802 std::vector<float> Scantable::doSinusoidFitting(const std::vector<float>& data, const std::vector<bool>& mask, const std::vector<int>& waveNumbers, std::vector<float>& params, float& rms, std::vector<bool>& finalMask, int& nClipped, float thresClip, int nIterClip, bool getResidual) 4803 { 4804 if (data.size() != mask.size()) { 4805 throw(AipsError("data and mask sizes are not identical")); 4806 } 4807 if (data.size() < 2) { 4808 throw(AipsError("data size is too short")); 4809 } 4810 if (waveNumbers.size() == 0) { 4811 throw(AipsError("no wave numbers given")); 4812 } 4625 std::vector<float> Scantable::doSinusoidFitting(const std::vector<float>& data, 4626 const std::vector<bool>& mask, 4627 const std::vector<int>& waveNumbers, 4628 std::vector<float>& params, 4629 float& rms, 4630 std::vector<bool>& finalMask, 4631 int& nClipped, 4632 float thresClip, 4633 int nIterClip, 4634 bool getResidual) 4635 { 4636 return doLeastSquareFitting(data, mask, 4637 getSinusoidModel(waveNumbers, data.size()), 4638 params, rms, finalMask, 4639 nClipped, thresClip, nIterClip, 4640 getResidual); 4641 } 4642 4643 std::vector<std::vector<std::vector<double> > > Scantable::getSinusoidModelReservoir(const std::vector<int>& waveNumbers, 4644 std::vector<int>& nChanNos) 4645 { 4646 std::vector<std::vector<std::vector<double> > > res; 4647 res.clear(); 4648 nChanNos.clear(); 4649 4650 std::vector<uint> ifNos = getIFNos(); 4651 for (uint i = 0; i < ifNos.size(); ++i) { 4652 int currNchan = nchan(ifNos[i]); 4653 bool hasDifferentNchan = (i == 0); 4654 for (uint j = 0; j < i; ++j) { 4655 if (currNchan != nchan(ifNos[j])) { 4656 hasDifferentNchan = true; 4657 break; 4658 } 4659 } 4660 if (hasDifferentNchan) { 4661 res.push_back(getSinusoidModel(waveNumbers, currNchan)); 4662 nChanNos.push_back(currNchan); 4663 } 4664 } 4665 4666 return res; 4667 } 4668 4669 std::vector<std::vector<double> > Scantable::getSinusoidModel(const std::vector<int>& waveNumbers, int nchan) 4670 { 4671 // model : contains elemental values for computing the least-square matrix. 4672 // model.size() is nmodel and model[*].size() is nchan. 4673 // Each model element are as follows: 4674 // model[0] = {1.0, 1.0, 1.0, ..., 1.0}, 4675 // model[2n-1] = {sin(nPI/L*x[0]), sin(nPI/L*x[1]), ..., sin(nPI/L*x[nchan])}, 4676 // model[2n] = {cos(nPI/L*x[0]), cos(nPI/L*x[1]), ..., cos(nPI/L*x[nchan])}, 4677 // where (1 <= n <= nMaxWavesInSW), 4678 // or, 4679 // model[2n-1] = {sin(wn[n]PI/L*x[0]), sin(wn[n]PI/L*x[1]), ..., sin(wn[n]PI/L*x[nchan])}, 4680 // model[2n] = {cos(wn[n]PI/L*x[0]), cos(wn[n]PI/L*x[1]), ..., cos(wn[n]PI/L*x[nchan])}, 4681 // where wn[n] denotes waveNumbers[n] (1 <= n <= waveNumbers.size()). 4682 4813 4683 std::vector<int> nWaves; // sorted and uniqued array of wave numbers 4814 4684 nWaves.reserve(waveNumbers.size()); … … 4823 4693 } 4824 4694 bool hasConstantTerm = (minNWaves == 0); 4825 4826 int nChan = data.size(); 4827 4828 finalMask.clear(); 4829 finalMask.resize(nChan); 4830 4831 std::vector<int> maskArray; 4832 std::vector<int> x; 4833 for (int i = 0; i < nChan; ++i) { 4834 maskArray.push_back(mask[i] ? 1 : 0); 4835 if (mask[i]) { 4836 x.push_back(i); 4837 } 4838 finalMask[i] = mask[i]; 4839 } 4840 4841 int initNData = x.size(); 4842 4843 int nData = initNData; 4844 int nDOF = nWaves.size() * 2 - (hasConstantTerm ? 1 : 0); //number of parameters to solve. 4695 int nmodel = nWaves.size() * 2 - (hasConstantTerm ? 1 : 0); //number of parameters to solve. 4696 4697 std::vector<std::vector<double> > model(nmodel, std::vector<double>(nchan)); 4698 4699 if (hasConstantTerm) { 4700 for (int j = 0; j < nchan; ++j) { 4701 model[0][j] = 1.0; 4702 } 4703 } 4845 4704 4846 4705 const double PI = 6.0 * asin(0.5); // PI (= 3.141592653...) 4847 double baseXFactor = 2.0*PI/(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. (2011/03/30 WK) 4848 4849 // xArray : contains elemental values for computing the least-square matrix. 4850 // xArray.size() is nDOF and xArray[*].size() is nChan. 4851 // Each xArray element are as follows: 4852 // xArray[0] = {1.0, 1.0, 1.0, ..., 1.0}, 4853 // xArray[2n-1] = {sin(nPI/L*x[0]), sin(nPI/L*x[1]), ..., sin(nPI/L*x[nChan])}, 4854 // xArray[2n] = {cos(nPI/L*x[0]), cos(nPI/L*x[1]), ..., cos(nPI/L*x[nChan])}, 4855 // where (1 <= n <= nMaxWavesInSW), 4856 // or, 4857 // xArray[2n-1] = {sin(wn[n]PI/L*x[0]), sin(wn[n]PI/L*x[1]), ..., sin(wn[n]PI/L*x[nChan])}, 4858 // xArray[2n] = {cos(wn[n]PI/L*x[0]), cos(wn[n]PI/L*x[1]), ..., cos(wn[n]PI/L*x[nChan])}, 4859 // where wn[n] denotes waveNumbers[n] (1 <= n <= waveNumbers.size()). 4860 std::vector<std::vector<double> > xArray; 4861 if (hasConstantTerm) { 4862 std::vector<double> xu; 4863 for (int j = 0; j < nChan; ++j) { 4864 xu.push_back(1.0); 4865 } 4866 xArray.push_back(xu); 4867 } 4706 double stretch0 = 2.0*PI/(double)(nchan-1); 4707 4868 4708 for (uInt i = (hasConstantTerm ? 1 : 0); i < nWaves.size(); ++i) { 4869 double xFactor = baseXFactor*(double)nWaves[i]; 4870 std::vector<double> xs, xc; 4871 xs.clear(); 4872 xc.clear(); 4873 for (int j = 0; j < nChan; ++j) { 4874 xs.push_back(sin(xFactor*(double)j)); 4875 xc.push_back(cos(xFactor*(double)j)); 4876 } 4877 xArray.push_back(xs); 4878 xArray.push_back(xc); 4879 } 4880 4881 std::vector<double> z1, r1, residual; 4882 for (int i = 0; i < nChan; ++i) { 4883 z1.push_back((double)data[i]); 4884 r1.push_back(0.0); 4885 residual.push_back(0.0); 4886 } 4887 4888 for (int nClip = 0; nClip < nIterClip+1; ++nClip) { 4889 // xMatrix : horizontal concatenation of 4890 // the least-sq. matrix (left) and an 4891 // identity matrix (right). 4892 // the right part is used to calculate the inverse matrix of the left part. 4893 double xMatrix[nDOF][2*nDOF]; 4894 double zMatrix[nDOF]; 4895 for (int i = 0; i < nDOF; ++i) { 4896 for (int j = 0; j < 2*nDOF; ++j) { 4897 xMatrix[i][j] = 0.0; 4898 } 4899 xMatrix[i][nDOF+i] = 1.0; 4900 zMatrix[i] = 0.0; 4901 } 4902 4903 int nUseData = 0; 4904 for (int k = 0; k < nChan; ++k) { 4905 if (maskArray[k] == 0) continue; 4906 4907 for (int i = 0; i < nDOF; ++i) { 4908 for (int j = i; j < nDOF; ++j) { 4909 xMatrix[i][j] += xArray[i][k] * xArray[j][k]; 4910 } 4911 zMatrix[i] += z1[k] * xArray[i][k]; 4912 } 4913 4914 nUseData++; 4915 } 4916 4917 if (nUseData < 1) { 4918 throw(AipsError("all channels clipped or masked. can't execute fitting anymore.")); 4919 } 4920 4921 for (int i = 0; i < nDOF; ++i) { 4922 for (int j = 0; j < i; ++j) { 4923 xMatrix[i][j] = xMatrix[j][i]; 4924 } 4925 } 4926 4927 std::vector<double> invDiag; 4928 for (int i = 0; i < nDOF; ++i) { 4929 invDiag.push_back(1.0/xMatrix[i][i]); 4930 for (int j = 0; j < nDOF; ++j) { 4931 xMatrix[i][j] *= invDiag[i]; 4932 } 4933 } 4934 4935 for (int k = 0; k < nDOF; ++k) { 4936 for (int i = 0; i < nDOF; ++i) { 4937 if (i != k) { 4938 double factor1 = xMatrix[k][k]; 4939 double factor2 = xMatrix[i][k]; 4940 for (int j = k; j < 2*nDOF; ++j) { 4941 xMatrix[i][j] *= factor1; 4942 xMatrix[i][j] -= xMatrix[k][j]*factor2; 4943 xMatrix[i][j] /= factor1; 4944 } 4945 } 4946 } 4947 double xDiag = xMatrix[k][k]; 4948 for (int j = k; j < 2*nDOF; ++j) { 4949 xMatrix[k][j] /= xDiag; 4950 } 4951 } 4952 4953 for (int i = 0; i < nDOF; ++i) { 4954 for (int j = 0; j < nDOF; ++j) { 4955 xMatrix[i][nDOF+j] *= invDiag[j]; 4956 } 4957 } 4958 //compute a vector y which consists of the coefficients of the sinusoids forming the 4959 //best-fit curves (a0,s1,c1,s2,c2,...), where a0 is constant and s* and c* are of sine 4960 //and cosine functions, respectively. 4961 std::vector<double> y; 4962 params.clear(); 4963 for (int i = 0; i < nDOF; ++i) { 4964 y.push_back(0.0); 4965 for (int j = 0; j < nDOF; ++j) { 4966 y[i] += xMatrix[i][nDOF+j]*zMatrix[j]; 4967 } 4968 params.push_back(y[i]); 4969 } 4970 4971 for (int i = 0; i < nChan; ++i) { 4972 r1[i] = y[0]; 4973 for (int j = 1; j < nDOF; ++j) { 4974 r1[i] += y[j]*xArray[j][i]; 4975 } 4976 residual[i] = z1[i] - r1[i]; 4977 } 4978 4979 double stdDev = 0.0; 4980 for (int i = 0; i < nChan; ++i) { 4981 stdDev += residual[i]*residual[i]*(double)maskArray[i]; 4982 } 4983 stdDev = sqrt(stdDev/(double)nData); 4984 rms = (float)stdDev; 4985 4986 if ((nClip == nIterClip) || (thresClip <= 0.0)) { 4987 break; 4988 } else { 4989 4990 double thres = stdDev * thresClip; 4991 int newNData = 0; 4992 for (int i = 0; i < nChan; ++i) { 4993 if (abs(residual[i]) >= thres) { 4994 maskArray[i] = 0; 4995 finalMask[i] = false; 4996 } 4997 if (maskArray[i] > 0) { 4998 newNData++; 4999 } 5000 } 5001 if (newNData == nData) { 5002 break; //no more flag to add. iteration stops. 5003 } else { 5004 nData = newNData; 5005 } 5006 5007 } 5008 } 5009 5010 nClipped = initNData - nData; 5011 5012 std::vector<float> result; 5013 if (getResidual) { 5014 for (int i = 0; i < nChan; ++i) { 5015 result.push_back((float)residual[i]); 5016 } 5017 } else { 5018 for (int i = 0; i < nChan; ++i) { 5019 result.push_back((float)r1[i]); 5020 } 5021 } 5022 5023 return result; 5024 } 5025 5026 void Scantable::fitBaseline(const std::vector<bool>& mask, int whichrow, Fitter& fitter) 5027 { 5028 std::vector<double> dAbcissa = getAbcissa(whichrow); 5029 std::vector<float> abcissa; 5030 for (uInt i = 0; i < dAbcissa.size(); ++i) { 5031 abcissa.push_back((float)dAbcissa[i]); 5032 } 5033 std::vector<float> spec = getSpectrum(whichrow); 5034 5035 fitter.setData(abcissa, spec, mask); 5036 fitter.lfit(); 5037 } 5038 5039 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask) 5040 { 5041 /**** 5042 double ms1TimeStart, ms1TimeEnd, ms2TimeStart, ms2TimeEnd; 5043 double elapse1 = 0.0; 5044 double elapse2 = 0.0; 5045 5046 ms1TimeStart = mathutil::gettimeofday_sec(); 5047 ****/ 5048 4709 int sidx = hasConstantTerm ? 2*i-1 : 2*i; 4710 int cidx = sidx + 1; 4711 double stretch = stretch0*(double)nWaves[i]; 4712 4713 for (int j = 0; j < nchan; ++j) { 4714 model[sidx][j] = sin(stretch*(double)j); 4715 model[cidx][j] = cos(stretch*(double)j); 4716 } 4717 } 4718 4719 return model; 4720 } 4721 4722 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, 4723 const std::vector<bool>& inMask) 4724 { 5049 4725 std::vector<bool> mask = getMask(whichrow); 5050 5051 /****5052 ms1TimeEnd = mathutil::gettimeofday_sec();5053 elapse1 = ms1TimeEnd - ms1TimeStart;5054 std::cout << "ms1 : " << elapse1 << " (sec.)" << endl;5055 ms2TimeStart = mathutil::gettimeofday_sec();5056 ****/5057 5058 4726 uInt maskSize = mask.size(); 5059 4727 if (inMask.size() != 0) { … … 5066 4734 } 5067 4735 5068 /****5069 ms2TimeEnd = mathutil::gettimeofday_sec();5070 elapse2 = ms2TimeEnd - ms2TimeStart;5071 std::cout << "ms2 : " << elapse2 << " (sec.)" << endl;5072 ****/5073 5074 4736 return mask; 5075 4737 } 5076 4738 5077 /* 5078 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, const int minEdgeSize, STLineFinder& lineFinder) 5079 { 5080 int edgeSize = edge.size(); 5081 std::vector<int> currentEdge; 5082 if (edgeSize >= 2) { 5083 int idx = 0; 5084 if (edgeSize > 2) { 5085 if (edgeSize < minEdgeSize) { 5086 throw(AipsError("Length of edge element info is less than that of IFs")); 5087 } 5088 idx = 2 * getIF(whichrow); 5089 } 5090 currentEdge.push_back(edge[idx]); 5091 currentEdge.push_back(edge[idx+1]); 5092 } else { 5093 throw(AipsError("Wrong length of edge element")); 5094 } 4739 std::vector<bool> Scantable::getCompositeChanMask(int whichrow, 4740 const std::vector<bool>& inMask, 4741 const std::vector<int>& edge, 4742 std::vector<int>& currEdge, 4743 STLineFinder& lineFinder) 4744 { 4745 std::vector<uint> ifNos = getIFNos(); 4746 if (edge.size() < ifNos.size()*2) { 4747 throw(AipsError("Length of edge element info is less than that of IFs")); 4748 } 4749 4750 int ifVal = getIF(whichrow); 4751 bool foundIF = false; 4752 uint idx; 4753 for (uint i = 0; i < ifNos.size(); ++i) { 4754 if (ifVal == (int)ifNos[i]) { 4755 idx = 2*i; 4756 foundIF = true; 4757 break; 4758 } 4759 } 4760 if (!foundIF) { 4761 throw(AipsError("bad IF number")); 4762 } 4763 4764 currEdge.clear(); 4765 currEdge.resize(2); 4766 currEdge[0] = edge[idx]; 4767 currEdge[1] = edge[idx+1]; 5095 4768 5096 4769 lineFinder.setData(getSpectrum(whichrow)); 5097 lineFinder.findLines(getCompositeChanMask(whichrow, inMask), curr entEdge, whichrow);4770 lineFinder.findLines(getCompositeChanMask(whichrow, inMask), currEdge, whichrow); 5098 4771 5099 4772 return lineFinder.getMask(); 5100 4773 } 5101 */5102 5103 /* for poly. the variations of outputFittingResult() should be merged into one eventually (2011/3/10 WK) */5104 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, Fitter& fitter)5105 {5106 if (outLogger || outTextFile) {5107 std::vector<float> params = fitter.getParameters();5108 std::vector<bool> fixed = fitter.getFixedParameters();5109 float rms = getRms(chanMask, whichrow);5110 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan);5111 5112 if (outLogger) {5113 LogIO ols(LogOrigin("Scantable", funcName, WHERE));5114 ols << formatBaselineParams(params, fixed, rms, -1, masklist, whichrow, false, csvFormat) << LogIO::POST ;5115 }5116 if (outTextFile) {5117 ofs << formatBaselineParams(params, fixed, rms, -1, masklist, whichrow, true, csvFormat) << flush;5118 }5119 }5120 }5121 4774 5122 4775 /* for cspline. will be merged once cspline is available in fitter (2011/3/10 WK) */ 5123 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<int>& edge, const std::vector<float>& params, const int nClipped) 5124 { 5125 if (outLogger || outTextFile) { 5126 /**** 5127 double ms1TimeStart, ms1TimeEnd, ms2TimeStart, ms2TimeEnd; 5128 double elapse1 = 0.0; 5129 double elapse2 = 0.0; 5130 5131 ms1TimeStart = mathutil::gettimeofday_sec(); 5132 ****/ 5133 5134 float rms = getRms(chanMask, whichrow); 5135 5136 /**** 5137 ms1TimeEnd = mathutil::gettimeofday_sec(); 5138 elapse1 = ms1TimeEnd - ms1TimeStart; 5139 std::cout << "ot1 : " << elapse1 << " (sec.)" << endl; 5140 ms2TimeStart = mathutil::gettimeofday_sec(); 5141 ****/ 5142 5143 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan); 5144 std::vector<bool> fixed; 5145 fixed.clear(); 5146 5147 if (outLogger) { 5148 LogIO ols(LogOrigin("Scantable", funcName, WHERE)); 5149 ols << formatPiecewiseBaselineParams(edge, params, fixed, rms, nClipped, masklist, whichrow, false, csvFormat) << LogIO::POST ; 5150 } 5151 if (outTextFile) { 5152 ofs << formatPiecewiseBaselineParams(edge, params, fixed, rms, nClipped, masklist, whichrow, true, csvFormat) << flush; 5153 } 5154 5155 /**** 5156 ms2TimeEnd = mathutil::gettimeofday_sec(); 5157 elapse2 = ms2TimeEnd - ms2TimeStart; 5158 std::cout << "ot2 : " << elapse2 << " (sec.)" << endl; 5159 ****/ 5160 5161 } 5162 } 5163 5164 /* for chebyshev/sinusoid. will be merged once chebyshev/sinusoid is available in fitter (2011/3/10 WK) */ 5165 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) 4776 void Scantable::outputFittingResult(bool outLogger, 4777 bool outTextFile, 4778 bool csvFormat, 4779 const std::vector<bool>& chanMask, 4780 int whichrow, 4781 const casa::String& coordInfo, 4782 bool hasSameNchan, 4783 ofstream& ofs, 4784 const casa::String& funcName, 4785 const std::vector<int>& edge, 4786 const std::vector<float>& params, 4787 const int nClipped) 5166 4788 { 5167 4789 if (outLogger || outTextFile) { … … 5173 4795 if (outLogger) { 5174 4796 LogIO ols(LogOrigin("Scantable", funcName, WHERE)); 5175 ols << formatBaselineParams(params, fixed, rms, nClipped, masklist, whichrow, false, csvFormat) << LogIO::POST ; 4797 ols << formatPiecewiseBaselineParams(edge, params, fixed, rms, nClipped, 4798 masklist, whichrow, false, csvFormat) << LogIO::POST ; 5176 4799 } 5177 4800 if (outTextFile) { 5178 ofs << formatBaselineParams(params, fixed, rms, nClipped, masklist, whichrow, true, csvFormat) << flush; 4801 ofs << formatPiecewiseBaselineParams(edge, params, fixed, rms, nClipped, 4802 masklist, whichrow, true, csvFormat) << flush; 4803 } 4804 } 4805 } 4806 4807 /* for poly/chebyshev/sinusoid. */ 4808 void Scantable::outputFittingResult(bool outLogger, 4809 bool outTextFile, 4810 bool csvFormat, 4811 const std::vector<bool>& chanMask, 4812 int whichrow, 4813 const casa::String& coordInfo, 4814 bool hasSameNchan, 4815 ofstream& ofs, 4816 const casa::String& funcName, 4817 const std::vector<float>& params, 4818 const int nClipped) 4819 { 4820 if (outLogger || outTextFile) { 4821 float rms = getRms(chanMask, whichrow); 4822 String masklist = getMaskRangeList(chanMask, whichrow, coordInfo, hasSameNchan); 4823 std::vector<bool> fixed; 4824 fixed.clear(); 4825 4826 if (outLogger) { 4827 LogIO ols(LogOrigin("Scantable", funcName, WHERE)); 4828 ols << formatBaselineParams(params, fixed, rms, nClipped, 4829 masklist, whichrow, false, csvFormat) << LogIO::POST ; 4830 } 4831 if (outTextFile) { 4832 ofs << formatBaselineParams(params, fixed, rms, nClipped, 4833 masklist, whichrow, true, csvFormat) << flush; 5179 4834 } 5180 4835 } -
trunk/src/Scantable.h
r2767 r2773 39 39 #include "STFit.h" 40 40 #include "STFitEntry.h" 41 //#include "STFitter.h"42 41 #include "STFocus.h" 43 42 #include "STFrequencies.h" … … 53 52 54 53 class Fitter; 54 class STLineFinder; 55 class STBaselineTable; 55 56 56 57 /** … … 635 636 static std::vector<bool> getMaskFromMaskList(const int nchan, 636 637 const std::vector<int>& masklist); 638 static casa::Vector<casa::uInt> getMaskListFromMask(const std::vector<bool>& mask); 637 639 static std::vector<int> splitToIntList(const std::string& str, const char delim); 638 640 static std::vector<string> splitToStringList(const std::string& str, const char delim); … … 752 754 const casa::Array<T2>&); 753 755 754 void fitBaseline(const std::vector<bool>& mask, int whichrow, Fitter& fitter);755 756 double getNormalPolynomial(int n, double x); 756 757 double getChebyshevPolynomial(int n, double x); 758 std::vector<std::vector<double> > getPolynomialModel(int order, 759 int nchan, 760 double (Scantable::*pfunc)(int, double)); 761 std::vector<std::vector<std::vector<double> > > getPolynomialModelReservoir(int order, 762 double (Scantable::*pfunc)(int, double), 763 std::vector<int>& nChanNos); 757 764 std::vector<float> doPolynomialFitting(const std::vector<float>& data, 758 765 const std::vector<bool>& mask, … … 793 800 std::vector<float> doLeastSquareFitting(const std::vector<float>& data, 794 801 const std::vector<bool>& mask, 795 double (Scantable::*pfunc)(int, double), 796 int order, 802 const std::vector<std::vector<double> >& model, 797 803 std::vector<float>& params, 798 804 float& rms, … … 831 837 int nIterClip=0, 832 838 bool getResidual=true); 839 std::vector<float> doCubicSplineLeastSquareFitting(const std::vector<float>& data, 840 const std::vector<bool>& mask, 841 const std::vector<std::vector<double> >& model, 842 int nPiece, 843 bool useGivenPieceBoundary, 844 std::vector<int>& idxEdge, 845 std::vector<float>& params, 846 float& rms, 847 std::vector<bool>& finalMask, 848 int& nClipped, 849 float thresClip=3.0, 850 int nIterClip=0, 851 bool getResidual=true); 833 852 std::vector<float> doSinusoidFitting(const std::vector<float>& data, 834 853 const std::vector<bool>& mask, … … 849 868 int nIterClip=0, 850 869 bool getResidual=true); 851 void selectWaveNumbers(const int whichrow, 852 const std::vector<bool>& chanMask, 853 const std::string& fftInfo, 854 //const bool applyFFT, 855 //const std::string& fftMethod, 856 //const std::string& fftThresh, 857 const std::vector<int>& addNWaves, 858 const std::vector<int>& rejectNWaves, 859 std::vector<int>& nWaves); 870 std::vector<std::vector<double> > getSinusoidModel(const std::vector<int>& waveNumbers, int nchan); 871 std::vector<std::vector<std::vector<double> > > getSinusoidModelReservoir(const std::vector<int>& waveNumbers, 872 std::vector<int>& nChanNos); 873 std::vector<int> selectWaveNumbers(const std::vector<int>& addNWaves, 874 const std::vector<int>& rejectNWaves); 875 std::vector<int> selectWaveNumbers(const int whichrow, 876 const std::vector<bool>& chanMask, 877 //const std::string& fftInfo, 878 const bool applyFFT, 879 const std::string& fftMethod, 880 const std::string& fftThresh, 881 const std::vector<int>& addNWaves, 882 const std::vector<int>& rejectNWaves); 883 int getIdxOfNchan(const int nChan, const std::vector<int>& nChanNos); 860 884 void parseFFTInfo(const std::string& fftInfo, 861 885 bool& applyFFT, 862 886 std::string& fftMethod, 863 887 std::string& fftThresh); 864 void parse ThresholdExpression(const std::string& fftThresh,865 866 867 888 void parseFFTThresholdInfo(const std::string& fftThresh, 889 std::string& fftThAttr, 890 float& fftThSigma, 891 int& fftThTop); 868 892 void doSelectWaveNumbers(const int whichrow, 869 893 const std::vector<bool>& chanMask, … … 879 903 void setWaveNumberListUptoNyquistFreq(const int whichrow, 880 904 std::vector<int>& nWaves); 905 void initialiseBaselining(const std::string& blfile, 906 std::ofstream& ofs, 907 const bool outLogger, 908 bool& outTextFile, 909 bool& csvFormat, 910 casa::String& coordInfo, 911 bool& hasSameNchan, 912 const std::string& progressInfo, 913 bool& showProgress, 914 int& minNRow, 915 casa::Vector<casa::Double>& timeSecCol); 916 void finaliseBaselining(const bool outBaselineTable, 917 STBaselineTable* pbt, 918 const string& bltable, 919 const bool outTextFile, 920 std::ofstream& ofs); 921 void initLineFinder(const std::vector<int>& edge, 922 const float threshold, 923 const int chanAvgLimit, 924 STLineFinder& lineFinder); 881 925 bool hasSameNchanOverIFs(); 882 926 std::string getMaskRangeList(const std::vector<bool>& mask, … … 889 933 std::string formatBaselineParamsFooter(float rms, int nClipped, bool verbose, bool csvformat) const; 890 934 std::vector<bool> getCompositeChanMask(int whichrow, const std::vector<bool>& inMask); 891 //std::vector<bool> getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, const int minEdgeSize, STLineFinder& lineFinder); 892 void outputFittingResult(bool outLogger, bool outTextFile, bool csvFormat, const std::vector<bool>& chanMask, int whichrow, const casa::String& coordInfo, bool hasSameNchan, std::ofstream& ofs, const casa::String& funcName, Fitter& fitter); 935 std::vector<bool> getCompositeChanMask(int whichrow, const std::vector<bool>& inMask, const std::vector<int>& edge, std::vector<int>& currEdge, STLineFinder& lineFinder); 893 936 void outputFittingResult(bool outLogger, bool outTextFile, bool csvFormat, 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 int nClipped); 894 937 void outputFittingResult(bool outLogger, bool outTextFile, bool csvFormat, 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 int nClipped); -
trunk/test/test_scantable.py
r2672 r2773 221 221 res_rms = (q-b).stats('rms') 222 222 assert_almost_equals(res_rms[0], 0.38346, 5) 223 assert_almost_equals(res_rms[1], 0.38780, 5) 223 #assert_almost_equals(res_rms[1], 0.38780, 5) 224 assert_almost_equals(res_rms[1], 0.48780, 5) 224 225 225 226
Note:
See TracChangeset
for help on using the changeset viewer.