LCOV - code coverage report
Current view: top level - singledish/SingleDish/test - tLineFinder.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 214 239 89.5 %
Date: 2024-12-11 20:54:31 Functions: 5 5 100.0 %

          Line data    Source code
       1             : //# tLineFinder.cc: this defines tests of SingleDishMS
       2             : //#
       3             : //# Copyright (C) 2014,2015
       4             : //# National Astronomical Observatory of Japan
       5             : //#
       6             : //# This library is free software; you can redistribute it and/or modify it
       7             : //# under the terms of the GNU Library General Public License as published by
       8             : //# the Free Software Foundation; either version 2 of the License, or (at your
       9             : //# option) any later version.
      10             : //#
      11             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      12             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      14             : //# License for more details.
      15             : //#
      16             : //# You should have received a copy of the GNU Library General Public License
      17             : //# along with this library; if not, write to the Free Software Foundation,
      18             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      19             : //#
      20             : //# Correspondence concerning AIPS++ should be addressed as follows:
      21             : //#        Internet email: casa-feedback@nrao.edu.
      22             : //#        Postal address: AIPS++ Project Office
      23             : //#                        National Radio Astronomy Observatory
      24             : //#                        520 Edgemont Road
      25             : //#                        Charlottesville, VA 22903-2475 USA
      26             : //#
      27             : //# $Id$
      28             : #include <iostream>
      29             : #include <sstream>
      30             : #include <list>
      31             : #include <cassert>
      32             : 
      33             : 
      34             : #include <casacore/casa/Arrays/Vector.h>
      35             : #include <casacore/tables/Tables/Table.h>
      36             : #include <casacore/tables/Tables/ArrayColumn.h>
      37             : #include <casacore/tables/Tables/ScalarColumn.h>
      38             : 
      39             : #include <casa_sakura/SakuraAlignedArray.h>
      40             : #include <singledish/SingleDish/LineFindingUtils.h>
      41             : #include <singledish/SingleDish/LineFinder.h>
      42             : 
      43             : using namespace casacore;
      44             : using namespace casa;
      45             : using namespace std;
      46             : 
      47             : template <typename DataType>
      48          20 : string print_array(size_t const num_data, DataType const* data) {
      49          20 :   cout << "got " << num_data << " elements" << endl;
      50          20 :   ostringstream oss;
      51          20 :   oss << "[";
      52          20 :   if (num_data > 0)
      53          20 :     oss << data[0] ;
      54         372 :   for (size_t i=1; i<num_data; ++i)
      55         352 :     oss << ", " << data[i];
      56          20 :   oss << "]";
      57          40 :   return oss.str();
      58          20 : }
      59             : 
      60          20 : void print_line(list<pair<size_t,size_t>> &line_list) {
      61          20 :   cout << "Number of Lines: " << line_list.size() << endl;
      62          20 :   for (list<pair<size_t,size_t>>::iterator iter = line_list.begin();
      63         100 :        iter!=line_list.end(); ++iter) {
      64          80 :     cout << "- [ " << (*iter).first << ", " << (*iter).second << " ]" << endl;
      65             :   }
      66          20 : }
      67             : 
      68           1 : int main(int argc, char *argv[]) {
      69           1 :   bool dobin(true), domask(true), doline(true), domaskline(true), dolinefinder(false);
      70           1 :   if (dobin)
      71             :   {// Test binning
      72           1 :     cout << "\n**********\nTest binning\n**********" << endl;
      73           1 :     size_t const num_data=20;
      74             :     float data[num_data];
      75             :     bool mask[num_data];
      76          21 :     for (size_t i = 0; i<num_data; ++i) {
      77          20 :       data[i] = static_cast<float>(i);
      78          20 :       mask[i] = (i%4 != 0) ? true : false;
      79             :     }
      80           1 :     cout << "data = " << print_array<float>(num_data, data) << endl;
      81           1 :     cout << "mask = " << print_array<bool>(num_data, mask) << endl;
      82           1 :     size_t const bin_size = 3;
      83           1 :     size_t offset = 1;
      84           1 :     size_t num_out = (num_data-offset)/bin_size;
      85           1 :     bool keepsize=false;
      86           1 :     float out_data1[num_out];
      87           1 :     bool out_mask1[num_out];
      88           1 :     cout << "[Binning]" << endl;
      89           1 :     cout << "Bin = " << bin_size << ", offset = " << offset
      90           1 :          << ", keepsize = " << (keepsize ? "true" : "false") << endl;
      91           1 :     size_t nout1 = LineFinderUtils::binDataAndMask<float>(num_data, data, mask, bin_size, num_out, out_data1, out_mask1, offset, keepsize);
      92           1 :     cout << "returned" << endl;
      93           1 :     cout << "out_data = " << print_array<float>(nout1, out_data1) << endl;
      94           1 :     cout << "out_mask = " << print_array<bool>(nout1, out_mask1) << endl;
      95           1 :     keepsize = true;
      96           1 :     offset = 0;
      97             :     float out_data2[num_data];
      98             :     bool out_mask2[num_data];
      99           1 :     cout << "\n[keepsize]" << endl;
     100           1 :     cout << "Bin = " << bin_size << ", offset = " << offset
     101           1 :          << ", keepsize = " << (keepsize ? "true" : "false") << endl;
     102           1 :     size_t nout2 = LineFinderUtils::binDataAndMask<float>(num_data, data, mask, bin_size, num_data, out_data2, out_mask2, offset, keepsize);
     103           1 :     cout << "out_data = " << print_array<float>(nout2, out_data2) << endl;
     104           1 :     cout << "out_mask = " << print_array<bool>(nout2, out_mask2) << endl;
     105           1 :   }
     106             : 
     107           1 :   if (domask)
     108             :   {// Test mask creation
     109           1 :     cout << "\n**********\nTest mask creation\n**********" << endl;
     110           1 :     size_t const num_data = 20;
     111           1 :     SakuraAlignedArray<float> data(num_data);
     112           1 :     SakuraAlignedArray<float> mad(num_data);
     113           1 :     SakuraAlignedArray<bool> in_mask(num_data);
     114           1 :     SakuraAlignedArray<bool> out_mask(num_data);
     115           1 :     float* dptr = data.data();
     116           1 :     bool* mptr = in_mask.data();
     117          21 :     for (size_t i = 0 ; i < num_data; ++i) {
     118          20 :       dptr[i] = float(i);
     119          20 :       mptr[i] = (i%4 != 0) ? true : false;
     120             :     }
     121           1 :     LineFinderUtils::calculateMAD(num_data,data.data(),in_mask.data(),mad.data());
     122           1 :     cout << "[MAD array]" << endl;
     123           1 :     cout << "data = " << print_array<float>(num_data, data.data()) << endl;
     124           1 :     cout << "in_mask = " << print_array<bool>(num_data, in_mask.data()) << endl;
     125           1 :     cout << "MAD = " << print_array<float>(num_data, mad.data()) << endl;
     126             : 
     127           1 :     float threshold = 5.0;
     128           1 :     cout << "\n[Mask creation]" << endl;
     129           1 :     cout << "MAD = " << print_array<float>(num_data, mad.data()) << endl;
     130           1 :     cout << "in_mask = " << print_array<bool>(num_data, in_mask.data()) << endl;
     131           1 :     cout << "threshold = " << threshold << endl;
     132           1 :     LineFinderUtils::createMaskByAThreshold(num_data, mad.data(), in_mask.data(), threshold, out_mask.data());
     133           1 :     cout << "out_mask = " << print_array<bool>(num_data, out_mask.data()) << endl;
     134           1 :     cout << "\n[Sign creation]" << endl;
     135           1 :     Vector<int8_t> signval(num_data);
     136           1 :     LineFinderUtils::createSignByAThreshold(num_data, mad.data(),
     137             :                                             threshold,signval.data());
     138           1 :     cout << "data = " << print_array<float>(num_data, mad.data()) << endl;
     139           1 :     cout << "threshold = " << threshold << endl;
     140           1 :     cout << "sign = " << print_array<int8_t>(num_data, signval.data()) << endl;
     141             : 
     142           1 :     cout << "\n[Mask to line list]" << endl;
     143           1 :     list<pair<size_t,size_t>> lines;
     144           1 :     cout << "in_mask = " << print_array<bool>(num_data, in_mask.data()) << endl;
     145           1 :     LineFinderUtils::maskToRangesList(num_data, in_mask.data(), lines);
     146           1 :     print_line(lines);
     147             : 
     148          21 :     for (size_t i = 0; i<num_data; ++i) {
     149          20 :       in_mask.data()[i] = (i%4 != 1) ? true : false;
     150             :     }
     151           1 :     cout << "\nin_mask = " << print_array<bool>(num_data, in_mask.data()) << endl;
     152           1 :     LineFinderUtils::maskToRangesList(num_data, in_mask.data(), lines);
     153           1 :     print_line(lines);
     154           1 :   }
     155           1 :   if (doline)
     156             :   { // Test handling of line_list
     157           1 :     cout << "\n**********\nTest line list handling\n**********" << endl;
     158           1 :     list<pair<size_t,size_t>> mylines;
     159           1 :     mylines.push_back(pair<size_t,size_t>(0,2));
     160           1 :     mylines.push_back(pair<size_t,size_t>(5,10));
     161           1 :     mylines.push_back(pair<size_t,size_t>(20,70));
     162           1 :     mylines.push_back(pair<size_t,size_t>(72,80));
     163           1 :     cout << "[ORIGINAL]" << endl;
     164           1 :     print_line(mylines);
     165           1 :     LineFinderUtils::rejectWideRange(20,mylines);
     166           1 :     cout << "[Regect wide (>20)]" << endl;
     167           1 :     print_line(mylines);
     168           1 :     LineFinderUtils::rejectNarrowRange(3,mylines);
     169           1 :     cout << "[Regect narrow (<3)]" << endl;
     170           1 :     print_line(mylines);
     171           1 :     size_t binsize = 4;
     172           1 :     size_t offset = 1;
     173           1 :     LineFinderUtils::deBinRanges(binsize, offset, mylines);
     174           1 :     cout << "[debin (bin=" << binsize << ", offset=" << offset << ")]" << endl;
     175           1 :     print_line(mylines);
     176             :     // Merge overlap in a list
     177           1 :     cout << "\nMerge overlap in a list" << endl;
     178           1 :     mylines.clear();
     179           1 :     mylines.push_back(pair<size_t,size_t>(5,8));
     180           1 :     mylines.push_back(pair<size_t,size_t>(4,6));
     181           1 :     mylines.push_back(pair<size_t,size_t>(12,14));
     182           1 :     mylines.push_back(pair<size_t,size_t>(11,15));
     183           1 :     mylines.push_back(pair<size_t,size_t>(20,23));
     184           1 :     mylines.push_back(pair<size_t,size_t>(23,25));
     185           1 :     cout << "[ORIGINAL]" << endl;
     186           1 :     print_line(mylines);
     187           1 :     LineFinderUtils::mergeOverlappingRanges(mylines);
     188           1 :     cout << "[Merged]" << endl;
     189           1 :     print_line(mylines);
     190             :     // Merge overlap in two lists
     191           1 :     mylines.clear();
     192           1 :     mylines.push_back(pair<size_t,size_t>(5,10));
     193           1 :     mylines.push_back(pair<size_t,size_t>(15,20));
     194           1 :     mylines.push_back(pair<size_t,size_t>(25,30));
     195           1 :     mylines.push_back(pair<size_t,size_t>(35,40));
     196           1 :     mylines.push_back(pair<size_t,size_t>(45,50));
     197           1 :     mylines.push_back(pair<size_t,size_t>(55,60));
     198           1 :     list<pair<size_t,size_t>> new_lines;
     199           1 :     new_lines.push_back(pair<size_t,size_t>(0,2));
     200           1 :     new_lines.push_back(pair<size_t,size_t>(12,13));
     201           1 :     new_lines.push_back(pair<size_t,size_t>(22,27));
     202           1 :     new_lines.push_back(pair<size_t,size_t>(37,39));
     203           1 :     new_lines.push_back(pair<size_t,size_t>(42,52));
     204           1 :     new_lines.push_back(pair<size_t,size_t>(57,62));
     205           1 :     new_lines.push_back(pair<size_t,size_t>(67,69));
     206           1 :     cout << "[ORIGINAL]" << endl;
     207           1 :     cout << "to = ";
     208           1 :     print_line(mylines);
     209           1 :     cout << "from = ";
     210           1 :     print_line(new_lines);
     211           1 :     LineFinderUtils::mergeOverlapInTwoLists(mylines, new_lines);
     212           1 :     cout << "out = ";
     213           1 :     print_line(mylines);
     214             : 
     215           1 :     cout << "\nMultiple overlap" << endl;
     216           1 :     mylines.clear();
     217           1 :     mylines.push_back(pair<size_t,size_t>(5,10));
     218           1 :     mylines.push_back(pair<size_t,size_t>(15,20));
     219           1 :     mylines.push_back(pair<size_t,size_t>(25,30));
     220           1 :     mylines.push_back(pair<size_t,size_t>(35,40));
     221           1 :     mylines.push_back(pair<size_t,size_t>(45,50));
     222           1 :     mylines.push_back(pair<size_t,size_t>(55,60));
     223           1 :     new_lines.clear();
     224           1 :     new_lines.push_back(pair<size_t,size_t>(2,17));
     225           1 :     new_lines.push_back(pair<size_t,size_t>(22,42));
     226           1 :     new_lines.push_back(pair<size_t,size_t>(47,62));
     227           1 :     cout << "to = ";
     228           1 :     print_line(mylines);
     229           1 :     cout << "from = ";
     230           1 :     print_line(new_lines);
     231           1 :     LineFinderUtils::mergeOverlapInTwoLists(mylines, new_lines);
     232           1 :     cout << "out = ";
     233           1 :     print_line(mylines);
     234           1 :   }
     235             : 
     236           1 :   if(domaskline)
     237             :   {
     238           1 :     cout << "\n**********\nTest line list handling with mask\n**********" << endl;
     239           1 :     size_t num_data(20);
     240           1 :     Vector<int8_t> sign(num_data);
     241           1 :     Vector<bool> mask(num_data);
     242          21 :     for (size_t i = 0; i<num_data; ++i) {
     243          20 :       sign[i] = ((i/6) % 2)==0 ? 1:-1;
     244          20 :       mask[i] = (i % 5)==0 ? false : true;
     245             :     }
     246           1 :     cout << "[Extend by sign]" << endl;
     247           1 :     cout << "sign = " << print_array<int8_t>(num_data, sign.data()) << endl;
     248           1 :     cout << "in_mask = " << print_array<bool>(num_data, mask.data()) << endl;
     249           1 :     list<pair<size_t,size_t>> mylines;
     250           1 :     mylines.push_back(pair<size_t,size_t>(2,2));
     251           1 :     mylines.push_back(pair<size_t,size_t>(7,7));
     252           1 :     mylines.push_back(pair<size_t,size_t>(12,12));
     253           1 :     cout << "input line:" << endl;
     254           1 :     print_line(mylines);
     255           1 :     LineFinderUtils::extendRangeBySign(num_data, sign.data(), mask.data(), mylines);
     256           1 :     cout << "extended line:" << endl;
     257           1 :     print_line(mylines);
     258             : 
     259           1 :     cout << "[Merge Lines by false]" << endl;
     260           1 :     mylines.clear();
     261           1 :     mylines.push_back(pair<size_t,size_t>(5,10));
     262           1 :     mylines.push_back(pair<size_t,size_t>(16,18));
     263          21 :     for (size_t i = 0; i < num_data; ++i) {
     264          20 :       mask[i] = (i>mylines.front().second && i<mylines.back().first)? false : true;
     265             :     }
     266           1 :     size_t maxgap = 5;
     267           1 :     cout << "max gap = " << maxgap << endl;
     268           1 :     cout << "mask = " << print_array<bool>(num_data, mask.data()) << endl;
     269           1 :     cout << "input line = ";
     270           1 :     print_line(mylines);
     271           1 :     LineFinderUtils::mergeGapByFalse(num_data, mask.data(), maxgap, mylines);
     272           1 :     cout << "output line: ";
     273           1 :     print_line(mylines);
     274             :     // change max gap to merge. This time lines would not be merged.
     275           1 :     maxgap = 4;
     276           1 :     mylines.clear();
     277           1 :     mylines.push_back(pair<size_t,size_t>(5,10));
     278           1 :     mylines.push_back(pair<size_t,size_t>(16,18));
     279           1 :     cout << "max gap = " << maxgap << endl;
     280           1 :     cout << "mask = " << print_array<bool>(num_data, mask.data()) << endl;
     281           1 :     cout << "input line = ";
     282           1 :     print_line(mylines);
     283           1 :     LineFinderUtils::mergeGapByFalse(num_data, mask.data(), maxgap, mylines);
     284           1 :     cout << "output line: ";
     285           1 :     print_line(mylines);
     286           1 :   }
     287           1 :   if (dolinefinder) {
     288           0 :     cout << "\n**********\nTest line finding\n**********" << endl;
     289           0 :     string table_name = "/almadev/work/reg_test/IRC+10216_rawACSmod_cal";
     290             :     //string table_name = "/almadev/work/OrionS_rawACSmod_calTPave.asap";
     291           0 :     size_t row_idx = 0;
     292           0 :     cout << "Table: " << table_name << endl;
     293           0 :     cout << "idx: " << row_idx << endl;
     294           0 :     Table mytab(table_name, Table::Old);
     295           0 :     assert(row_idx<mytab.nrow());
     296           0 :     ScalarColumn<unsigned int> flagRCol(mytab, "FLAGROW");
     297           0 :     assert(flagRCol.get(row_idx)==0);
     298           0 :     ArrayColumn<float> specCol(mytab, "SPECTRA");
     299           0 :     ArrayColumn<uint8_t> flagCol(mytab, "FLAGTRA");
     300           0 :     Vector<float> specvec(specCol.get(row_idx));
     301           0 :     Vector<uint8_t> flagvec(flagCol.get(row_idx));
     302           0 :     size_t num_data(specvec.nelements());
     303           0 :     cout << "nchan: " << num_data << endl;
     304           0 :     Vector<float> data(num_data);
     305           0 :     Vector<bool> mask(num_data);
     306           0 :     for (size_t i=0; i<num_data; ++i) {
     307           0 :       data[i] = specvec[i];
     308           0 :       mask[i] = (flagvec[i]==static_cast<uint8_t>(0));
     309             :     }
     310           0 :     pair<size_t,size_t> edge(500,500);
     311             :     list<pair<size_t,size_t>> line_list = \
     312           0 :       linefinder::MADLineFinder(num_data, data.data(), mask.data(), 5.0, 10.0, 3, 1000, 4, edge);
     313           0 :     cout << "[Line finding result]" << endl;
     314           0 :     print_line(line_list);
     315           0 :   }
     316             : 
     317           1 :   return 0;
     318             : }

Generated by: LCOV version 1.16