LCOV - code coverage report
Current view: top level - synthesis/Utilities - SDPosInterpolator.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 0 210 0.0 %
Date: 2023-11-02 14:27:30 Functions: 0 18 0.0 %

          Line data    Source code
       1             : //# SDPosInterpolator.cc: Implementation of SDPosInterpolator class
       2             : //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: aips2-request@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id$
      27             : 
      28             : #include <synthesis/Utilities/SDPosInterpolator.h>
      29             : 
      30             : using namespace casacore;
      31             : namespace casa {
      32             : 
      33           0 : SDPosInterpolator::SDPosInterpolator(
      34             :   const VisBuffer& vb,
      35           0 :   const String& pointingDirCol_p) {
      36           0 :   const auto & pointingColumns = vb.msColumns().pointing();
      37           0 :   const auto nant = static_cast<size_t>(vb.msColumns().antenna().nrow());
      38           0 :   setup(pointingColumns, pointingDirCol_p, nant);
      39           0 : }
      40           0 : SDPosInterpolator::SDPosInterpolator(
      41             :   const vi::VisBuffer2& vb,
      42           0 :   const String& pointingDirCol_p) {
      43           0 :   const auto & pointingColumns = vb.subtableColumns().pointing();
      44           0 :   const auto nant = static_cast<size_t>(vb.subtableColumns().antenna().nrow());
      45           0 :   setup(pointingColumns, pointingDirCol_p, nant);
      46           0 : }
      47           0 : SDPosInterpolator::SDPosInterpolator(
      48             :   const MSPointing& pointingTable,
      49             :   const String& columnName,
      50           0 :   const size_t nant){
      51           0 :   MSPointingColumns pointingColumns{pointingTable};
      52           0 :   setup(pointingColumns, columnName, nant);
      53           0 : }
      54           0 : SDPosInterpolator::SDPosInterpolator(
      55             :   const MSPointingColumns& pointingColumns,
      56             :   const String& columnName,
      57           0 :   const size_t nant){
      58           0 :   setup(pointingColumns, columnName, nant);
      59           0 : }
      60           0 : SDPosInterpolator::SDPosInterpolator(const Vector<Vector<Double> >& time,
      61           0 :                                      const Vector<Vector<Vector<Double> > >& dir) {
      62           0 :   setup(time, dir);
      63           0 : }
      64           0 : SDPosInterpolator::~SDPosInterpolator() {}
      65             : 
      66           0 : void SDPosInterpolator::setup(const Vector<Vector<Double> >& time,
      67             :                               const Vector<Vector<Vector<Double> > >& dir) {
      68             :   //(1)get number of pointing data for each antennaID
      69           0 :   Int nant = time.nelements();
      70           0 :   Vector<uInt> nPointingData(nant);
      71           0 :   nPointingData = 0;
      72           0 :   for (Int iant = 0; iant < nant; ++iant) {
      73           0 :     nPointingData(iant) = time(iant).nelements();
      74             :   }
      75             : 
      76             :   //(2)setup spline coefficients for each antenna ID
      77           0 :   timePointing.resize(nant);
      78           0 :   dirPointing.resize(nant);
      79           0 :   splineCoeff.resize(nant);
      80           0 :   doSplineInterpolation.resize(nant);
      81           0 :   doSplineInterpolation = false;
      82           0 :   for (Int i = 0; i < nant; ++i) {
      83           0 :     if (nPointingData(i) < 4) continue;
      84             :     
      85           0 :     doSplineInterpolation(i) = true;
      86           0 :     timePointing(i).resize(nPointingData(i));
      87           0 :     dirPointing(i).resize(nPointingData(i));
      88           0 :     splineCoeff(i).resize(nPointingData(i) - 1);
      89           0 :     for (uInt j = 0; j < dirPointing(i).nelements(); ++j) {
      90           0 :       dirPointing(i)(j).resize(2);
      91             :     }
      92           0 :     for (uInt j = 0; j < splineCoeff(i).nelements(); ++j) {
      93           0 :       splineCoeff(i)(j).resize(2);
      94           0 :       splineCoeff(i)(j)(0).resize(4); // x
      95           0 :       splineCoeff(i)(j)(1).resize(4); // y
      96             :     }
      97             :     
      98           0 :     Int npoi = nPointingData(i);
      99           0 :     for (Int j = 0; j < npoi; ++j) {
     100           0 :       timePointing(i)(j) = time(i)(j);
     101           0 :       for (Int k = 0; k < 2; ++k) {
     102           0 :         dirPointing(i)(j)(k) = dir(i)(j)(k);
     103             :       }
     104             :     }
     105             :       
     106           0 :     calcSplineCoeff(timePointing(i), dirPointing(i), splineCoeff(i));
     107             :   }
     108             : 
     109             :   //(3) keep time range
     110           0 :   timeRangeStart.resize(nant);
     111           0 :   timeRangeEnd.resize(nant);
     112           0 :   for (Int iant = 0; iant < nant; ++iant) {
     113           0 :     timeRangeStart(iant) = timePointing(iant)(0);
     114           0 :     timeRangeEnd(iant)   = timePointing(iant)(timePointing(iant).nelements()-1);
     115             :   }
     116           0 : }
     117             : 
     118           0 : void SDPosInterpolator::setup(
     119             :   const MSPointingColumns& act_mspc,
     120             :   const String& pointingDirCol_p,
     121             :   size_t nant) {
     122           0 :   auto check_col = [&](Bool isnull){
     123           0 :     if (isnull) {
     124           0 :       cerr << "No " << pointingDirCol_p << " column in POINTING table" << endl;
     125             :     }
     126           0 :   };
     127           0 :   std::function<Vector<Double>(Int)> get_direction;
     128             : 
     129             :   //(0)check POINTING table and set function to obtain direction data
     130           0 :   if (pointingDirCol_p == "TARGET") {
     131           0 :     get_direction = [&](Int idx){
     132           0 :       return act_mspc.targetMeas(idx).getAngle("rad").getValue();
     133           0 :     };
     134           0 :   } else if (pointingDirCol_p == "POINTING_OFFSET") {
     135           0 :     check_col(act_mspc.pointingOffsetMeasCol().isNull());
     136           0 :     get_direction = [&](Int idx){
     137           0 :       return act_mspc.pointingOffsetMeas(idx).getAngle("rad").getValue();
     138           0 :     };
     139           0 :   } else if (pointingDirCol_p == "SOURCE_OFFSET") {
     140           0 :     check_col(act_mspc.sourceOffsetMeasCol().isNull());
     141           0 :     get_direction = [&](Int idx){
     142           0 :       return act_mspc.sourceOffsetMeas(idx).getAngle("rad").getValue();
     143           0 :     };
     144           0 :   } else if (pointingDirCol_p == "ENCODER") {
     145           0 :     check_col(act_mspc.encoderMeas().isNull());
     146           0 :     get_direction = [&](Int idx){
     147           0 :       return act_mspc.encoderMeas()(idx).getAngle("rad").getValue();
     148           0 :     };
     149             :   } else {
     150           0 :     get_direction = [&](Int idx){
     151           0 :       return act_mspc.directionMeas(idx).getAngle("rad").getValue();
     152           0 :     };
     153             :   }
     154             : 
     155             :   //(1)get number of pointing data for each antennaID
     156           0 :   Vector<uInt> nPointingData(nant, 0);
     157           0 :   auto pointingRows = static_cast<size_t>(act_mspc.nrow());
     158           0 :   for (size_t row = 0; row < pointingRows ; ++row) {
     159           0 :     nPointingData(act_mspc.antennaId()(row)) += 1;
     160             :   }
     161             : 
     162             :   //(2)setup spline coefficients for each antenna ID that
     163             :   //   appear in the main table (spectral data) if there
     164             :   //   are enough number of pointing data (4 or more).
     165             :   //   in case there exists antenna ID for which not enough
     166             :   //   (i.e., 1, 2 or 3) pointing data are given, linear
     167             :   //   interpolation is applied for that antenna ID as
     168             :   //   previously done.
     169           0 :   timePointing.resize(nant);
     170           0 :   dirPointing.resize(nant);
     171           0 :   splineCoeff.resize(nant);
     172           0 :   doSplineInterpolation.resize(nant);
     173           0 :   doSplineInterpolation = false;
     174           0 :   for (uInt i = 0; i < nant; ++i) {
     175           0 :     if (nPointingData(i) < 4) continue;
     176             : 
     177           0 :     doSplineInterpolation(i) = true;
     178           0 :     timePointing(i).resize(nPointingData(i));
     179           0 :     dirPointing(i).resize(nPointingData(i));
     180           0 :     splineCoeff(i).resize(nPointingData(i) - 1);
     181           0 :     for (uInt j = 0; j < dirPointing(i).nelements(); ++j) {
     182           0 :       dirPointing(i)(j).resize(2);
     183             :     }
     184           0 :     for (uInt j = 0; j < splineCoeff(i).nelements(); ++j) {
     185           0 :       splineCoeff(i)(j).resize(2);
     186           0 :       splineCoeff(i)(j)(0).resize(4); // x
     187           0 :       splineCoeff(i)(j)(1).resize(4); // y
     188             :     }
     189             : 
     190             :     //set ptime array etc. need for spline calculation...
     191           0 :     size_t tidx = 0;
     192           0 :     for (size_t j = 0; j < pointingRows; ++j) {
     193           0 :       if (act_mspc.antennaId()(j) != i) continue;
     194             : 
     195           0 :       timePointing(i)(tidx) = act_mspc.time()(j);
     196           0 :       dirPointing(i)(tidx) = get_direction(j);
     197           0 :       tidx++;
     198             :     }
     199             : 
     200           0 :     calcSplineCoeff(timePointing(i), dirPointing(i), splineCoeff(i));
     201             :   }
     202             : 
     203             :   //(3) keep time range
     204           0 :   timeRangeStart.resize(nant);
     205           0 :   timeRangeEnd.resize(nant);
     206           0 :   for (size_t iant = 0; iant < nant; ++iant) {
     207           0 :     timeRangeStart(iant) = timePointing(iant)(0);
     208           0 :     timeRangeEnd(iant)   = timePointing(iant)(timePointing(iant).nelements()-1);
     209             :   }
     210           0 : }
     211             : 
     212           0 : void SDPosInterpolator::calcSplineCoeff(const Vector<Double>& time,
     213             :                                         const Vector<Vector<Double> >& dir,
     214             :                                         Vector<Vector<Vector<Double> > >& coeff) {
     215           0 :   Vector<Double> h, vx, vy;
     216           0 :   Vector<Double> a;
     217           0 :   Vector<Double> c;
     218           0 :   Vector<Double> alpha, beta, gamma;
     219           0 :   Vector<Double> wx, wy;
     220           0 :   Vector<Double> ux, uy;
     221             : 
     222           0 :   Int const num_data = time.nelements();
     223           0 :   h.resize(num_data-1);
     224           0 :   vx.resize(num_data-1);
     225           0 :   vy.resize(num_data-1);
     226           0 :   a.resize(num_data-1);
     227           0 :   c.resize(num_data-1);
     228           0 :   alpha.resize(num_data-1);
     229           0 :   beta.resize(num_data-1);
     230           0 :   gamma.resize(num_data-1);
     231           0 :   wx.resize(num_data-1);
     232           0 :   wy.resize(num_data-1);
     233           0 :   ux.resize(num_data);
     234           0 :   uy.resize(num_data);
     235             : 
     236           0 :   h(0) = time(1) - time(0);
     237           0 :   for (Int i = 1; i < num_data-1; ++i) {
     238           0 :     h(i) = time(i+1) - time(i);
     239           0 :     vx(i) = 6.0*((dir(i+1)(0)-dir(i)(0))/h(i) - (dir(i)(0)-dir(i-1)(0))/h(i-1));
     240           0 :     vy(i) = 6.0*((dir(i+1)(1)-dir(i)(1))/h(i) - (dir(i)(1)-dir(i-1)(1))/h(i-1));
     241           0 :     a(i) = 2.0*(time(i+1) - time(i-1));
     242           0 :     c(i) = h(i);
     243           0 :     gamma(i) = c(i);
     244             :   }
     245           0 :   alpha(2) = c(1)/a(1);
     246           0 :   for (Int i = 3; i < num_data-1; ++i) {
     247           0 :     alpha(i) = c(i-1)/(a(i-1) - alpha(i-1)*c(i-2));
     248             :   }
     249           0 :   beta(1) = a(1);
     250           0 :   for (Int i = 2; i < num_data-2; ++i) {
     251           0 :     beta(i) = c(i)/alpha(i+1);
     252             :   }
     253           0 :   beta(num_data-2) = a(num_data-2) - alpha(num_data-2) * c(num_data-3);
     254           0 :   wx(0) = 0.0;
     255           0 :   wx(1) = vx(1);
     256           0 :   wy(0) = 0.0;
     257           0 :   wy(1) = vy(1);
     258           0 :   for (Int i = 2; i < num_data-1; ++i) {
     259           0 :     wx(i) = vx(i) - alpha(i)*wx(i-1);
     260           0 :     wy(i) = vy(i) - alpha(i)*wy(i-1);
     261             :   }
     262           0 :   ux(num_data-1) = 0.0;
     263           0 :   uy(num_data-1) = 0.0;
     264           0 :   for (Int i = num_data-2; i >= 1; --i) {
     265           0 :     ux(i) = (wx(i) - gamma(i)*ux(i+1))/beta(i);
     266           0 :     uy(i) = (wy(i) - gamma(i)*uy(i+1))/beta(i);
     267             :   }
     268           0 :   ux(0) = 0.0;
     269           0 :   uy(0) = 0.0;
     270             : 
     271           0 :   for (Int i = 0; i < num_data-1; ++i) {
     272           0 :     coeff(i)(0)(0) = dir(i)(0);
     273           0 :     coeff(i)(1)(0) = dir(i)(1);
     274           0 :     coeff(i)(0)(1) = (dir(i+1)(0)-dir(i)(0))/(time(i+1)-time(i)) - (time(i+1)-time(i))*(2.0*ux(i)+ux(i+1))/6.0;
     275           0 :     coeff(i)(1)(1) = (dir(i+1)(1)-dir(i)(1))/(time(i+1)-time(i)) - (time(i+1)-time(i))*(2.0*uy(i)+uy(i+1))/6.0;
     276           0 :     coeff(i)(0)(2) = ux(i)/2.0;
     277           0 :     coeff(i)(1)(2) = uy(i)/2.0;
     278           0 :     coeff(i)(0)(3) = (ux(i+1)-ux(i))/(time(i+1)-time(i))/6.0;
     279           0 :     coeff(i)(1)(3) = (uy(i+1)-uy(i))/(time(i+1)-time(i))/6.0;
     280             :   }
     281           0 : }
     282             : 
     283           0 : MDirection SDPosInterpolator::interpolateDirectionMeasSpline(const MSPointingColumns& mspc,
     284             :                                                              const Double& time,
     285             :                                                              const Int& index,
     286             :                                                              const Int& antid) {
     287           0 :   Int lastIndex = timePointing(antid).nelements() - 1;
     288           0 :   Int aindex = lastIndex;
     289           0 :   for (uInt i = 0; i < timePointing(antid).nelements(); ++i) {
     290           0 :     if (time < timePointing(antid)(i)) {
     291           0 :       aindex = i-1;
     292           0 :       break;
     293             :     }
     294             :   }
     295           0 :   if (aindex < 0) aindex = 0;
     296           0 :   if (lastIndex <= aindex) aindex = lastIndex - 1;
     297             : 
     298           0 :   auto const &coeff = splineCoeff(antid)(aindex);
     299           0 :   Double dt = time - timePointing(antid)(aindex);
     300           0 :   Vector<Double> newdir(2);
     301           0 :   newdir(0) = coeff(0)(0) + coeff(0)(1)*dt + coeff(0)(2)*dt*dt + coeff(0)(3)*dt*dt*dt;
     302           0 :   newdir(1) = coeff(1)(0) + coeff(1)(1)*dt + coeff(1)(2)*dt*dt + coeff(1)(3)*dt*dt*dt;
     303             :   
     304           0 :   Quantity rDirLon(newdir(0), "rad");
     305           0 :   Quantity rDirLat(newdir(1), "rad");
     306           0 :   auto const &directionMeasColumn = mspc.directionMeasCol();
     307           0 :   MDirection::Ref rf(directionMeasColumn.measDesc().getRefCode());
     308           0 :   if (directionMeasColumn.measDesc().isRefCodeVariable()) {
     309           0 :     rf = mspc.directionMeas(index).getRef();
     310             :   }
     311             : 
     312           0 :   return MDirection(rDirLon, rDirLat, rf);
     313             : }
     314             : 
     315           0 : Vector<Vector<Vector<Vector<Double> > > > SDPosInterpolator::getSplineCoeff() {
     316           0 :   return splineCoeff;
     317             : }
     318             : 
     319           0 : Bool SDPosInterpolator::inTimeRange(const Double& time, const Int& antid) {
     320           0 :   Bool inrange = false;
     321           0 :   if ((timeRangeStart(antid) <= time) && (time <= timeRangeEnd(antid))) {
     322           0 :     inrange = true;
     323             :   }
     324           0 :   return inrange;
     325             : }
     326             : 
     327             : } //#End casa namespace

Generated by: LCOV version 1.16