//# tLineFinder.cc: this defines tests of SingleDishMS //# //# Copyright (C) 2014,2015 //# National Astronomical Observatory of Japan //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #include <iostream> #include <sstream> #include <list> #include <cassert> #include <casacore/casa/Arrays/Vector.h> #include <casacore/tables/Tables/Table.h> #include <casacore/tables/Tables/ArrayColumn.h> #include <casacore/tables/Tables/ScalarColumn.h> #include <casa_sakura/SakuraAlignedArray.h> #include <singledish/SingleDish/LineFindingUtils.h> #include <singledish/SingleDish/LineFinder.h> using namespace casacore; using namespace casa; using namespace std; template <typename DataType> string print_array(size_t const num_data, DataType const* data) { cout << "got " << num_data << " elements" << endl; ostringstream oss; oss << "["; if (num_data > 0) oss << data[0] ; for (size_t i=1; i<num_data; ++i) oss << ", " << data[i]; oss << "]"; return oss.str(); } void print_line(list<pair<size_t,size_t>> &line_list) { cout << "Number of Lines: " << line_list.size() << endl; for (list<pair<size_t,size_t>>::iterator iter = line_list.begin(); iter!=line_list.end(); ++iter) { cout << "- [ " << (*iter).first << ", " << (*iter).second << " ]" << endl; } } int main(int argc, char *argv[]) { bool dobin(true), domask(true), doline(true), domaskline(true), dolinefinder(false); if (dobin) {// Test binning cout << "\n**********\nTest binning\n**********" << endl; size_t const num_data=20; float data[num_data]; bool mask[num_data]; for (size_t i = 0; i<num_data; ++i) { data[i] = static_cast<float>(i); mask[i] = (i%4 != 0) ? true : false; } cout << "data = " << print_array<float>(num_data, data) << endl; cout << "mask = " << print_array<bool>(num_data, mask) << endl; size_t const bin_size = 3; size_t offset = 1; size_t num_out = (num_data-offset)/bin_size; bool keepsize=false; float out_data1[num_out]; bool out_mask1[num_out]; cout << "[Binning]" << endl; cout << "Bin = " << bin_size << ", offset = " << offset << ", keepsize = " << (keepsize ? "true" : "false") << endl; size_t nout1 = LineFinderUtils::binDataAndMask<float>(num_data, data, mask, bin_size, num_out, out_data1, out_mask1, offset, keepsize); cout << "returned" << endl; cout << "out_data = " << print_array<float>(nout1, out_data1) << endl; cout << "out_mask = " << print_array<bool>(nout1, out_mask1) << endl; keepsize = true; offset = 0; float out_data2[num_data]; bool out_mask2[num_data]; cout << "\n[keepsize]" << endl; cout << "Bin = " << bin_size << ", offset = " << offset << ", keepsize = " << (keepsize ? "true" : "false") << endl; size_t nout2 = LineFinderUtils::binDataAndMask<float>(num_data, data, mask, bin_size, num_data, out_data2, out_mask2, offset, keepsize); cout << "out_data = " << print_array<float>(nout2, out_data2) << endl; cout << "out_mask = " << print_array<bool>(nout2, out_mask2) << endl; } if (domask) {// Test mask creation cout << "\n**********\nTest mask creation\n**********" << endl; size_t const num_data = 20; SakuraAlignedArray<float> data(num_data); SakuraAlignedArray<float> mad(num_data); SakuraAlignedArray<bool> in_mask(num_data); SakuraAlignedArray<bool> out_mask(num_data); float* dptr = data.data(); bool* mptr = in_mask.data(); for (size_t i = 0 ; i < num_data; ++i) { dptr[i] = float(i); mptr[i] = (i%4 != 0) ? true : false; } LineFinderUtils::calculateMAD(num_data,data.data(),in_mask.data(),mad.data()); cout << "[MAD array]" << endl; cout << "data = " << print_array<float>(num_data, data.data()) << endl; cout << "in_mask = " << print_array<bool>(num_data, in_mask.data()) << endl; cout << "MAD = " << print_array<float>(num_data, mad.data()) << endl; float threshold = 5.0; cout << "\n[Mask creation]" << endl; cout << "MAD = " << print_array<float>(num_data, mad.data()) << endl; cout << "in_mask = " << print_array<bool>(num_data, in_mask.data()) << endl; cout << "threshold = " << threshold << endl; LineFinderUtils::createMaskByAThreshold(num_data, mad.data(), in_mask.data(), threshold, out_mask.data()); cout << "out_mask = " << print_array<bool>(num_data, out_mask.data()) << endl; cout << "\n[Sign creation]" << endl; Vector<int8_t> signval(num_data); LineFinderUtils::createSignByAThreshold(num_data, mad.data(), threshold,signval.data()); cout << "data = " << print_array<float>(num_data, mad.data()) << endl; cout << "threshold = " << threshold << endl; cout << "sign = " << print_array<int8_t>(num_data, signval.data()) << endl; cout << "\n[Mask to line list]" << endl; list<pair<size_t,size_t>> lines; cout << "in_mask = " << print_array<bool>(num_data, in_mask.data()) << endl; LineFinderUtils::maskToRangesList(num_data, in_mask.data(), lines); print_line(lines); for (size_t i = 0; i<num_data; ++i) { in_mask.data()[i] = (i%4 != 1) ? true : false; } cout << "\nin_mask = " << print_array<bool>(num_data, in_mask.data()) << endl; LineFinderUtils::maskToRangesList(num_data, in_mask.data(), lines); print_line(lines); } if (doline) { // Test handling of line_list cout << "\n**********\nTest line list handling\n**********" << endl; list<pair<size_t,size_t>> mylines; mylines.push_back(pair<size_t,size_t>(0,2)); mylines.push_back(pair<size_t,size_t>(5,10)); mylines.push_back(pair<size_t,size_t>(20,70)); mylines.push_back(pair<size_t,size_t>(72,80)); cout << "[ORIGINAL]" << endl; print_line(mylines); LineFinderUtils::rejectWideRange(20,mylines); cout << "[Regect wide (>20)]" << endl; print_line(mylines); LineFinderUtils::rejectNarrowRange(3,mylines); cout << "[Regect narrow (<3)]" << endl; print_line(mylines); size_t binsize = 4; size_t offset = 1; LineFinderUtils::deBinRanges(binsize, offset, mylines); cout << "[debin (bin=" << binsize << ", offset=" << offset << ")]" << endl; print_line(mylines); // Merge overlap in a list cout << "\nMerge overlap in a list" << endl; mylines.clear(); mylines.push_back(pair<size_t,size_t>(5,8)); mylines.push_back(pair<size_t,size_t>(4,6)); mylines.push_back(pair<size_t,size_t>(12,14)); mylines.push_back(pair<size_t,size_t>(11,15)); mylines.push_back(pair<size_t,size_t>(20,23)); mylines.push_back(pair<size_t,size_t>(23,25)); cout << "[ORIGINAL]" << endl; print_line(mylines); LineFinderUtils::mergeOverlappingRanges(mylines); cout << "[Merged]" << endl; print_line(mylines); // Merge overlap in two lists mylines.clear(); mylines.push_back(pair<size_t,size_t>(5,10)); mylines.push_back(pair<size_t,size_t>(15,20)); mylines.push_back(pair<size_t,size_t>(25,30)); mylines.push_back(pair<size_t,size_t>(35,40)); mylines.push_back(pair<size_t,size_t>(45,50)); mylines.push_back(pair<size_t,size_t>(55,60)); list<pair<size_t,size_t>> new_lines; new_lines.push_back(pair<size_t,size_t>(0,2)); new_lines.push_back(pair<size_t,size_t>(12,13)); new_lines.push_back(pair<size_t,size_t>(22,27)); new_lines.push_back(pair<size_t,size_t>(37,39)); new_lines.push_back(pair<size_t,size_t>(42,52)); new_lines.push_back(pair<size_t,size_t>(57,62)); new_lines.push_back(pair<size_t,size_t>(67,69)); cout << "[ORIGINAL]" << endl; cout << "to = "; print_line(mylines); cout << "from = "; print_line(new_lines); LineFinderUtils::mergeOverlapInTwoLists(mylines, new_lines); cout << "out = "; print_line(mylines); cout << "\nMultiple overlap" << endl; mylines.clear(); mylines.push_back(pair<size_t,size_t>(5,10)); mylines.push_back(pair<size_t,size_t>(15,20)); mylines.push_back(pair<size_t,size_t>(25,30)); mylines.push_back(pair<size_t,size_t>(35,40)); mylines.push_back(pair<size_t,size_t>(45,50)); mylines.push_back(pair<size_t,size_t>(55,60)); new_lines.clear(); new_lines.push_back(pair<size_t,size_t>(2,17)); new_lines.push_back(pair<size_t,size_t>(22,42)); new_lines.push_back(pair<size_t,size_t>(47,62)); cout << "to = "; print_line(mylines); cout << "from = "; print_line(new_lines); LineFinderUtils::mergeOverlapInTwoLists(mylines, new_lines); cout << "out = "; print_line(mylines); } if(domaskline) { cout << "\n**********\nTest line list handling with mask\n**********" << endl; size_t num_data(20); Vector<int8_t> sign(num_data); Vector<bool> mask(num_data); for (size_t i = 0; i<num_data; ++i) { sign[i] = ((i/6) % 2)==0 ? 1:-1; mask[i] = (i % 5)==0 ? false : true; } cout << "[Extend by sign]" << endl; cout << "sign = " << print_array<int8_t>(num_data, sign.data()) << endl; cout << "in_mask = " << print_array<bool>(num_data, mask.data()) << endl; list<pair<size_t,size_t>> mylines; mylines.push_back(pair<size_t,size_t>(2,2)); mylines.push_back(pair<size_t,size_t>(7,7)); mylines.push_back(pair<size_t,size_t>(12,12)); cout << "input line:" << endl; print_line(mylines); LineFinderUtils::extendRangeBySign(num_data, sign.data(), mask.data(), mylines); cout << "extended line:" << endl; print_line(mylines); cout << "[Merge Lines by false]" << endl; mylines.clear(); mylines.push_back(pair<size_t,size_t>(5,10)); mylines.push_back(pair<size_t,size_t>(16,18)); for (size_t i = 0; i < num_data; ++i) { mask[i] = (i>mylines.front().second && i<mylines.back().first)? false : true; } size_t maxgap = 5; cout << "max gap = " << maxgap << endl; cout << "mask = " << print_array<bool>(num_data, mask.data()) << endl; cout << "input line = "; print_line(mylines); LineFinderUtils::mergeGapByFalse(num_data, mask.data(), maxgap, mylines); cout << "output line: "; print_line(mylines); // change max gap to merge. This time lines would not be merged. maxgap = 4; mylines.clear(); mylines.push_back(pair<size_t,size_t>(5,10)); mylines.push_back(pair<size_t,size_t>(16,18)); cout << "max gap = " << maxgap << endl; cout << "mask = " << print_array<bool>(num_data, mask.data()) << endl; cout << "input line = "; print_line(mylines); LineFinderUtils::mergeGapByFalse(num_data, mask.data(), maxgap, mylines); cout << "output line: "; print_line(mylines); } if (dolinefinder) { cout << "\n**********\nTest line finding\n**********" << endl; string table_name = "/almadev/work/reg_test/IRC+10216_rawACSmod_cal"; //string table_name = "/almadev/work/OrionS_rawACSmod_calTPave.asap"; size_t row_idx = 0; cout << "Table: " << table_name << endl; cout << "idx: " << row_idx << endl; Table mytab(table_name, Table::Old); assert(row_idx<mytab.nrow()); ScalarColumn<unsigned int> flagRCol(mytab, "FLAGROW"); assert(flagRCol.get(row_idx)==0); ArrayColumn<float> specCol(mytab, "SPECTRA"); ArrayColumn<uint8_t> flagCol(mytab, "FLAGTRA"); Vector<float> specvec(specCol.get(row_idx)); Vector<uint8_t> flagvec(flagCol.get(row_idx)); size_t num_data(specvec.nelements()); cout << "nchan: " << num_data << endl; Vector<float> data(num_data); Vector<bool> mask(num_data); for (size_t i=0; i<num_data; ++i) { data[i] = specvec[i]; mask[i] = (flagvec[i]==static_cast<uint8_t>(0)); } pair<size_t,size_t> edge(500,500); list<pair<size_t,size_t>> line_list = \ linefinder::MADLineFinder(num_data, data.data(), mask.data(), 5.0, 10.0, 3, 1000, 4, edge); cout << "[Line finding result]" << endl; print_line(line_list); } return 0; }