LCOV - code coverage report
Current view: top level - synthesis/CalTables - CalInterp.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 463 0.0 %
Date: 2024-10-10 15:00:01 Functions: 0 20 0.0 %

          Line data    Source code
       1             : //# CalInterp.cc: Implementation of Calibration Interpolation
       2             : //# Copyright (C) 1996,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: casa-feedback@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             : 
      27             : #include <synthesis/CalTables/CalInterp.h>
      28             : 
      29             : #include <casacore/casa/Arrays.h>
      30             : #include <casacore/scimath/Mathematics/MatrixMathLA.h>
      31             : #include <casacore/casa/BasicSL/String.h>
      32             : #include <casacore/casa/Utilities/Assert.h>
      33             : #include <casacore/casa/Utilities/BinarySearch.h>
      34             : #include <casacore/casa/Exceptions/Error.h>
      35             : 
      36             : #include <sstream>
      37             : 
      38             : #include <casacore/casa/Logging/LogMessage.h>
      39             : #include <casacore/casa/Logging/LogSink.h>
      40             : 
      41             : using namespace casacore;
      42             : namespace casa { //# NAMESPACE CASA - BEGIN
      43             : 
      44           0 : CalInterp::CalInterp(CalSet<Complex>& cs,
      45             :                      const String& timetype,
      46           0 :                      const String& freqtype) :
      47           0 :   cs_(&cs),
      48           0 :   timeType_(timetype),
      49           0 :   freqType_(freqtype),
      50           0 :   spwMap_(cs.nSpw(),-1),
      51           0 :   spwOK_(cs.nSpw(),false),
      52           0 :   lastTime_(cs.nSpw(),-1.0e99),
      53           0 :   finit_(cs.nSpw(),false),
      54           0 :   nFreq_(cs.nSpw(),1),
      55           0 :   solFreq_(cs.nSpw(),NULL),
      56           0 :   datFreq_(cs.nSpw(),NULL),
      57           0 :   currSpw_(-1),
      58           0 :   currSlot_(cs.nSpw(),-1),
      59           0 :   exactTime_(false),
      60             : 
      61           0 :   ip4d_(cs.nSpw(),NULL),
      62           0 :   ip3d_(cs.nSpw(),NULL),
      63           0 :   ip2d_(cs.nSpw(),NULL),
      64             : 
      65           0 :   t0_(cs.nSpw(),0.0),
      66           0 :   tS_(cs.nSpw(),0.0),
      67           0 :   lastlo_(cs.nSpw(),-1),
      68             : 
      69           0 :   tAC_(cs.nSpw(),NULL),
      70           0 :   tPC_(cs.nSpw(),NULL),
      71           0 :   tCC_(cs.nSpw(),NULL),
      72           0 :   tOk_(cs.nSpw(),NULL),
      73             : 
      74           0 :   ch0_(cs.nSpw(),NULL),
      75           0 :   ef_(cs.nSpw(),NULL),
      76           0 :   df_(cs.nSpw(),NULL),
      77           0 :   fdf_(cs.nSpw(),NULL),
      78             : 
      79           0 :   fAC_(cs.nSpw(),NULL),
      80           0 :   fPC_(cs.nSpw(),NULL),
      81           0 :   fCC_(cs.nSpw(),NULL),
      82           0 :   fOk_(cs.nSpw(),NULL),
      83             : 
      84           0 :   verbose_(false)
      85             : 
      86             : {
      87             : 
      88           0 :   if (verbose_) cout << "CalInterp::constructor" << endl;
      89             : 
      90           0 :   if (verbose_) cout << " timeType_ = " << timeType_ << endl;
      91           0 :   if (verbose_) cout << " freqType_ = " << freqType_ << endl;
      92             : 
      93             :   // Nominally, spwOK_ follows CalSet
      94           0 :   spwOK_ = cs_->spwOK();
      95             : 
      96             :   // Allocate (zero-size) working arrays and shapes
      97             :   //  (will resize non-trivially as needed)
      98           0 :   for (currSpw_=0;currSpw_<cs.nSpw();currSpw_++) {
      99             : 
     100             :     // nFreq()=1 here, will set this in initFreqInterp
     101           0 :     ip4d_[currSpw()] = new IPosition(4,2,nPar(),nFreq(),nElem());
     102           0 :     ip3d_[currSpw()] = new IPosition(3,nPar(),nFreq(),nElem());
     103           0 :     ip2d_[currSpw()] = new IPosition(2,nFreq(),nElem());
     104             : 
     105           0 :     tAC_[currSpw()] = new Array<Float>();
     106           0 :     tOk_[currSpw()] = new Cube<Bool>();
     107           0 :     tPC_[currSpw()] = new Array<Float>();
     108           0 :     tCC_[currSpw()] = new Array<Complex>();
     109             :     
     110           0 :     fAC_[currSpw()] = new Array<Float>();
     111           0 :     fOk_[currSpw()] = new Cube<Bool>();
     112           0 :     fPC_[currSpw()] = new Array<Float>();
     113           0 :     fCC_[currSpw()] = new Array<Complex>();
     114             :     
     115           0 :     df_[currSpw()]  = new Vector<Double>();
     116           0 :     fdf_[currSpw()] = new Vector<Double>();
     117           0 :     ch0_[currSpw()] = new Vector<Int>();
     118           0 :     ef_[currSpw()]  = new Vector<Bool>();
     119             :   }
     120             : 
     121           0 :   currSpw_=-1;
     122             : 
     123           0 : };
     124             : 
     125             : 
     126           0 : CalInterp::~CalInterp() {
     127             : 
     128           0 :   if (verbose_) cout << "CalInterp::destructor" << endl;
     129           0 :   deflTimeC();
     130           0 :   deflFreqC();
     131           0 :   deflFreqA();
     132           0 : }
     133             : 
     134             : 
     135           0 : Bool CalInterp::interpolate(const Double& time,
     136             :                             const Int& spw,
     137             :                             const Vector<Double>& /*freq*/) {
     138             : 
     139           0 :   if (verbose_) cout << endl << "CalInterp::interpolate()" << endl;
     140             : 
     141             :   // TODO:
     142             :   //  - catch case where requested spw has no solutions
     143             : 
     144             :   // Assume no change, for starters
     145           0 :   Bool newInterp(false);
     146             : 
     147             :   // If spw has changed, re-map spw
     148           0 :   currSpw()=spw;
     149             : 
     150           0 :   newInterp = interpTime(time);
     151             : 
     152             :   // Interpolate in Freq
     153             :   //  if (newInterp) interpFreq(freq);
     154             : 
     155             :   // Finalize interpolation
     156           0 :   finalize();
     157             : 
     158           0 :   return newInterp;
     159             : 
     160             : }
     161             : 
     162             : 
     163           0 : Bool CalInterp::interpTime(const Double& time) {
     164             : 
     165             :   // Interpolate in Time
     166           0 :   if (verbose_) cout << "CalInterp::interpTime()" << endl;
     167             : 
     168           0 :   Bool newTime=false;         // assume no new calculations needed
     169             : 
     170           0 :   Bool newSlot(false);
     171           0 :   if (time != lastTime() ) {
     172           0 :     lastTime()=time;
     173             : 
     174             :     // if not "nearest", must recalcuate time interp
     175           0 :     if ( !nearestT() ) newTime=true;
     176             : 
     177             :     // Find relevant time slot
     178           0 :     newSlot = findSlot(time);
     179             : 
     180           0 :     if (newSlot) 
     181           0 :       newTime = true;
     182             : 
     183           0 :     if (!exactTime() && !nearestT())
     184           0 :       updTimeCoeff();
     185             :     
     186             :   }
     187             : 
     188           0 :   if (verbose_) cout << "   " << boolalpha 
     189           0 :                      << "newTime = " << newTime << " " 
     190           0 :                      << "newSlot = " << newSlot << " " 
     191           0 :                      << "currSlot() = " << currSlot() << " "
     192           0 :                      << "fieldId = " << cs_->fieldId(currSpwMap())(currSlot()) << " "
     193           0 :                      << "exactTime() = " << exactTime()  << " "
     194           0 :                      << "nearestT() = " << nearestT()  << " "
     195           0 :                      << endl;
     196             : 
     197             :   // newTime=true here if we need to re-calc time interp (*any* mode)
     198             : 
     199           0 :   if (newTime) {
     200             :     
     201           0 :     if ( nearestT() || exactTime() ) {
     202           0 :       exactTime_=true;   // Behave as exact
     203             : 
     204           0 :       if (verbose_) cout << "   "
     205           0 :                          << "FOUND EXACT TIME!" << endl;
     206             :       // Just reference CalSet parameter
     207           0 :       IPosition blc(4,0,0,0,currSlot());
     208           0 :       IPosition trc(4,nPar()-1,nChan()-1,nElem()-1,currSlot());
     209             : 
     210           0 :       Cube<Complex> t;
     211           0 :       t.reference(csPar()(blc,trc).reform(IPosition(3,nPar(),nChan(),nElem())));
     212           0 :       r_.reference(t);
     213           0 :       tOk().reference(csParOK()(blc,trc).reform(IPosition(3,nPar(),nChan(),nElem())));
     214             : 
     215           0 :     } else {
     216             : 
     217           0 :       if (verbose_) cout << "   "
     218           0 :                          << "NON-EXACT TIME." << endl;
     219             : 
     220             :       // Do non-trivial interpolation
     221             :       //      r_.resize(0,0,0);
     222             : 
     223             : 
     224           0 :       interpTimeCalc(time);
     225             :     }
     226             :     
     227           0 :   if (verbose_) 
     228           0 :     cout << " CalInterp addr: " << r_.data()
     229           0 :          << endl;
     230             : 
     231             : 
     232             : 
     233             :   } 
     234             : 
     235           0 :   return newTime;  // signals whether new interp calc required
     236             : 
     237             : }
     238             : 
     239           0 : void CalInterp::interpFreq(const Vector<Double>& freq) {
     240             : 
     241           0 :   if (verbose_) cout << "CalInterp::interpFreq()" << endl;
     242             : 
     243             :   // Only if more than one cal channel is freq interp (potentially) necessary 
     244           0 :   if (nChan() > 1) {
     245             : 
     246             :     // setup freq interp info (~no-op if already done)
     247           0 :     initFreqInterp(freq);
     248             : 
     249             :     // if all exact freqs, just reference time interp result:
     250           0 :     if ( allEQ(ef(),true) ) {
     251             : 
     252             :       // un-reference r
     253           0 :       r.resize();
     254             : 
     255             :     } else {
     256             :       // do non-trivial freq interpolation
     257             : 
     258             :       // ensure correct info available from time interpolation
     259           0 :       calcAPC();
     260             : 
     261             :       // update coeffs
     262           0 :       updFreqCoeff();
     263             : 
     264             :       // do freq interp calc
     265           0 :       interpFreqCalc();
     266             :        
     267             :     }
     268             : 
     269             :   }
     270             : 
     271           0 : }
     272             : 
     273           0 : Bool CalInterp::findSlot(const Double& time) {
     274             : 
     275           0 :   if (verbose_) cout << "CalInterp::findSlot()" << endl;
     276             : 
     277           0 :   Int slot(-1);
     278             : 
     279           0 :   Bool newSlot(false);               // Assume no change
     280             : 
     281             :   // If only one slot, we've found it
     282           0 :   if (nTime()==1) {
     283           0 :     slot=0;
     284           0 :     exactTime_=true;
     285             : 
     286             :   // More than one slot, find the right one:
     287             :   } else {
     288             : 
     289           0 :     Vector<Double> timelist(csTimes());
     290             : 
     291           0 :     if (exactTime_) newSlot=true;
     292             : 
     293             :     // Behave as nearest outside absolute range of available calibration   
     294             :     //   to avoid wild extrapolation, else search for the correct soln slot
     295           0 :     if (time<timelist(0)) {
     296             :       // Before first timestamp, use first slot as nearest one
     297           0 :       slot=0;
     298           0 :       exactTime_=true;
     299             :     }
     300           0 :     else if (time>timelist(nTime()-1)) {
     301             :       // After last timestamp, use last slot as nearest one
     302           0 :       slot=nTime()-1;
     303           0 :       exactTime_=true;
     304             :     }
     305             :     else
     306             :       // Find index in timelist where time would be:
     307           0 :       slot=binarySearch(exactTime_,timelist,time,nTime(),0);
     308             : 
     309             :     //    cout << "time = " << time << "  slot = " << slot << " nTime() = " << nTime() << endl;
     310             :     // If not already an exact match...
     311           0 :     if ( !exactTime_ ) {
     312             : 
     313             :       // identify this time via index just prior
     314           0 :       if (slot>0) slot--;
     315             : 
     316             :       // If nearest, fine-tune slot to actual nearest:
     317           0 :       if ( timeType()=="nearest" ) {
     318           0 :         exactTime_=true;   // Nearest behaves like exact match
     319           0 :         if (slot!=nTime()-1 && 
     320           0 :             (timelist(slot+1)-time) < (time-timelist(slot)) )
     321           0 :           slot++;
     322             :       } else {
     323             :         // linear modes require one later slot
     324           0 :         if (slot==nTime()-1) slot--;
     325             :       }
     326             :     }
     327             : 
     328           0 :   }
     329           0 :   newSlot = (slot!=currSlot());
     330           0 :   if (newSlot) {
     331           0 :     currSlot_(currSpw_)=slot;
     332             :   }
     333             : 
     334           0 :   return newSlot;
     335             : 
     336             : }
     337             : 
     338           0 : void CalInterp::updTimeCoeff() {
     339             : 
     340           0 :   if (verbose_) cout << "CalInterp::updTimeCoeff()" << endl;
     341             : 
     342           0 :   if ( currSlot() != lastlo() ) {
     343           0 :     lastlo()=currSlot();
     344             : 
     345             :     // Resize Coefficient arrays 
     346           0 :     IPosition ip4s(4,2,nPar(),nChan(),nElem());
     347           0 :     IPosition ip3s(3,nPar(),nChan(),nElem());
     348             : 
     349           0 :     tAC().resize(ip4s);
     350           0 :     tOk().resize(); // ensure not referencing csParOK!
     351           0 :     tOk().resize(ip3s);
     352             : 
     353           0 :     if ( timeType()=="linear") 
     354           0 :       tPC().resize(ip4s);
     355           0 :     else if (timeType()=="aipslin") 
     356           0 :       tCC().resize(ip4s);
     357             :     
     358             :     // Time ref/step for this interval
     359           0 :     t0()=csTimes()(currSlot());
     360           0 :     tS()=csTimes()(currSlot()+1)-t0();
     361             :     
     362             :     // For indexing parameter cache
     363           0 :     IPosition lo(4,0,0,0,currSlot()), hi(4,0,0,0,currSlot()+1);
     364           0 :     IPosition ref(4,0,0,0,0), slope(4,1,0,0,0);
     365             : 
     366           0 :     for (Int ielem=0;ielem<nElem();ielem++) {
     367           0 :       lo(2)=hi(2)=ref(3)=slope(3)=ielem;
     368           0 :       for (Int ichan=0;ichan<nChan();ichan++) {
     369           0 :         lo(1)=hi(1)=ref(2)=slope(2)=ichan;
     370           0 :         for (Int ipar=0;ipar<nPar();ipar++) {
     371           0 :           lo(0)=hi(0)=ref(1)=slope(1)=ipar;
     372             : 
     373           0 :           tOk()(ipar,ichan,ielem) = (csParOK()(lo) && csParOK()(hi));
     374             :           
     375           0 :           if (tOk()(ipar,ichan,ielem)) {
     376             :             // Intercept
     377           0 :             tAC()(ref) = abs(csPar()(lo));
     378           0 :             tAC()(slope) = abs(csPar()(hi)) - tAC()(ref);
     379             :             
     380           0 :             if (timeType()=="linear") {
     381           0 :               tPC()(ref) = arg(csPar()(lo));
     382             :               
     383             :               // Slope
     384           0 :               Float pslope = arg(csPar()(hi)) - tPC()(ref);
     385             :               // Catch simple phase wraps
     386           0 :               if (pslope > C::pi)
     387           0 :                 pslope-=(2*C::pi);
     388           0 :               else if (pslope < -C::pi)
     389           0 :                 pslope+=(2*C::pi);
     390           0 :               tPC()(slope) = pslope;
     391             :               
     392           0 :             } else if (timeType()=="aipslin") {
     393           0 :               tCC()(ref) = csPar()(lo);
     394           0 :               tCC()(slope) = csPar()(hi)-tCC()(ref);
     395             :               
     396             :             }
     397             :             
     398             :           } else {
     399           0 :             tAC()(ref)=1.0;
     400           0 :             tAC()(slope)=0.0;
     401           0 :             if (timeType()=="linear") {
     402           0 :               tPC()(ref)=0.0;
     403           0 :               tPC()(slope)=0.0;
     404           0 :             } else if (timeType()=="aipslin") {
     405           0 :               tCC()(ref)=Complex(1.0,0.0);
     406           0 :               tCC()(slope)=Complex(0.0,0.0);
     407             :             }
     408             :           }
     409             :         }
     410             :       }
     411             :     }
     412           0 :   }
     413             : 
     414           0 : }
     415             : 
     416             : 
     417           0 : void CalInterp::interpTimeCalc(const Double& time) {
     418             : 
     419           0 :   if (verbose_) cout << "CalInterp::interpTimeCalc()" << endl;
     420             : 
     421             :   // TODO:
     422             :   //  a. Use matrix math instead of loops?  (tOk() usage?)
     423             : 
     424             :   // Fractional time interval for this timestamp
     425           0 :   Float dt( Float( (time-t0())/tS() ) );
     426             : 
     427             :   // Ensure intermediate results cache is properly sized and ref'd
     428           0 :   if (tA_.nelements()==0) {
     429           0 :     tA_.resize(nPar(),nChan(),nElem());
     430           0 :     a.reference(tA_);
     431           0 :     ok.reference(tOk());
     432           0 :     if (timeType()=="linear") {
     433           0 :       tP_.resize(nPar(),nChan(),nElem());
     434           0 :       p.reference(tP_);
     435           0 :       c.resize(); 
     436             :     }
     437           0 :     else if (timeType()=="aipslin") {
     438           0 :       tC_.resize(nPar(),nChan(),nElem());
     439           0 :       c.reference(tC_);
     440           0 :       p.resize();
     441             :     }
     442             :   }
     443             :   
     444           0 :   IPosition ref(4,0,0,0,0),slope(4,1,0,0,0);
     445           0 :   for (Int ielem=ref(3)=slope(3)=0; 
     446           0 :        ielem<nElem();
     447           0 :        ielem++,ref(3)++,slope(3)++) {
     448           0 :     for (Int ichan=ref(2)=slope(2)=0;
     449           0 :          ichan<nChan();
     450           0 :          ichan++,ref(2)++,slope(2)++) {
     451           0 :       for (Int ipar=ref(1)=slope(1)=0;
     452           0 :            ipar<nPar();
     453           0 :            ipar++,ref(1)++,slope(1)++) {
     454             :         
     455           0 :         if (tOk()(ipar,ichan,ielem)) {
     456             : 
     457           0 :           tA_(ipar,ichan,ielem) = tAC()(ref) + tAC()(slope)*dt;
     458           0 :           if (timeType()=="linear") {
     459           0 :             tP_(ipar,ichan,ielem) = tPC()(ref) + tPC()(slope)*dt;
     460           0 :           } else if (timeType()=="aipslin") {
     461           0 :             Complex tCtmp(tCC()(ref) + tCC()(slope)*dt);
     462           0 :             Float Amp(abs(tCtmp));
     463           0 :             if (Amp>0.0)
     464           0 :               tC_(ipar,ichan,ielem) = tCtmp/abs(tCtmp);
     465             :             else
     466           0 :               tC_(ipar,ichan,ielem) = Complex(1.0);
     467             :           }
     468             :         } 
     469             :         else {
     470           0 :           tA_(ipar,ichan,ielem) = 1.0;
     471           0 :           if (timeType()=="linear") {
     472           0 :             tP_(ipar,ichan,ielem) = 0.0;
     473           0 :           } else if (timeType()=="aipslin") {
     474           0 :             tC_(ipar,ichan,ielem) = Complex(1.0,0.0);
     475             :           }
     476             :         }       // tOk()
     477             :       } // ipar
     478             :     } // ichan
     479             :   } // ielem
     480             :   
     481           0 :   if (verbose_) {
     482           0 :     cout << "tA_ = " << tA_.nonDegenerate() << endl;
     483           0 :     if (timeType()=="linear") 
     484           0 :       cout << "tP_ = " << tP_.nonDegenerate() << endl;
     485           0 :     else if (timeType()=="aipslin")
     486           0 :       cout << "tC_ = " << tC_.nonDegenerate() << endl;
     487             :   }
     488             : 
     489           0 : }
     490             : 
     491             : 
     492           0 : void CalInterp::initFreqInterp(const Vector<Double> freq) {
     493             : 
     494           0 :   if (verbose_) cout << "CalInterp::initFreqInterp()" << endl;
     495             : 
     496             :   // Initialize freq interpolation if
     497             :   //  a. not yet initialized (first time thru), or,
     498             :   //  b. # of requested frequencies not equal to previous, or,
     499             :   //  (c. # of requested freqs same, but freqs different --- NYI)
     500             : 
     501             : 
     502           0 :   if (nFreq() != Int(freq.nelements()) ||
     503           0 :       !allEQ(freq,datFreq()) )
     504           0 :     finit()=false;
     505             : 
     506           0 :   if (!finit()) {
     507             : 
     508             :     // Remember number of requested frequencies
     509           0 :     nFreq() = freq.nelements();
     510             :     
     511             :     // Remember the frequencies:
     512           0 :     datFreq() = freq;
     513             : 
     514           0 :     ch0().resize(nFreq()); ch0()=-1;
     515           0 :     ef().resize(nFreq());  ef()=false;
     516             : 
     517           0 :     if (nChan()==1) {
     518             :       // one-to-many case (e.g., G)
     519             :       //  need not support non-trivial freq interpolation
     520           0 :       ch0()=0;
     521           0 :       ef()=true;
     522             : 
     523             :     } else {
     524             :       // many-to-many case (e.g., B)
     525             :       //  support non-trivial freq interpolation if some non-exact freqs
     526             : 
     527             :       // Fill ref ch indices for each input freq:
     528           0 :       Int ichan(0);
     529           0 :       for (Int i=0;i<nFreq();i++) {
     530             : 
     531           0 :         ichan = binarySearch(ef()(i),csFreq(),freq(i),nChan(),0);
     532             :         
     533             :         // interp-type adjustments:
     534           0 :         if (!ef()(i)) {
     535           0 :           if ( freqType()=="nearest" ) {
     536             :             // refer to true nearest, behave as exact match
     537           0 :             ef()(i)=true;
     538           0 :             if ( ichan==nChan() || 
     539           0 :                  (ichan>0 && 
     540           0 :                   abs(freq(i)-csFreq()(ichan-1))<abs(csFreq()(ichan)-freq(i))) )
     541           0 :               ichan--;
     542             :           } else {
     543             :             // refer to index at low and of pair that brackets this freq, within bounds
     544           0 :             if (ichan>0) ichan--;
     545           0 :             if (ichan==nChan()-1) ichan--;
     546             :           }
     547             :         }
     548           0 :         ch0()(i)=ichan;
     549             : 
     550             :       }
     551             :       
     552             :       // Fill in frac freq info if some non-exact freqs
     553           0 :       if ( !allEQ(ef(),true) ) {
     554             :         
     555           0 :         df().resize(nFreq());  df()=0.0;
     556           0 :         fdf().resize(nFreq()); fdf()=0.0;
     557             : 
     558             :         // Fill in frac freq info
     559           0 :         for (Int i=0;i<nFreq()-1;i++) {
     560           0 :           if (!ef()(i)) {
     561           0 :             df()(i) = freq(i)-csFreq()(ch0()(i));
     562           0 :             fdf()(i) = df()(i)/abs( csFreq()(ch0()(i)+1)-csFreq()(ch0()(i)) );
     563             :           }
     564             :         }
     565             :       }
     566             :     }
     567             : 
     568             :   }
     569             : 
     570           0 : }
     571             : 
     572             : 
     573           0 : void CalInterp::calcAPC() {
     574             : 
     575           0 :   if (verbose_) cout << "CalInterp::calcAPC()" << endl;
     576             : 
     577             :   // re-package interpTimeCalc result for updFreqCoeff, as necessary
     578             : 
     579           0 :   if (freqType()=="linear") {
     580           0 :     if (timeType()=="nearest") {
     581             :       // need a/p from r
     582           0 :       tA_.resize(nPar(),nChan(),nElem());
     583           0 :       tA_ = amplitude(r);
     584           0 :       tP_.resize(nPar(),nChan(),nElem());
     585           0 :       tP_ = phase(r);
     586           0 :       r.resize(); // drop reference to nearest cached solution
     587             :     }
     588           0 :     else if (timeType()=="aipslin") {
     589             :       // a ok, need p
     590           0 :       tP_.resize(nPar(),nChan(),nElem());
     591           0 :       tP_ = phase(tC_);
     592             :     } 
     593           0 :   } else if (freqType()=="aipslin") {
     594           0 :     if (timeType()=="nearest") {
     595             :       // need a/c
     596           0 :       tA_.resize(nPar(),nChan(),nElem());
     597           0 :       tA_ = amplitude(r);
     598           0 :       tC_.resize(nPar(),nChan(),nElem());
     599           0 :       tC_ = r;
     600           0 :       Array<Float> rp,ip;
     601           0 :       rPart(tC_,rp);
     602           0 :       iPart(tC_,ip);
     603             : 
     604             :       //  NEED TO CHECK for tA_=0 here!      
     605             : 
     606           0 :       rp/=tA_;
     607           0 :       ip/=tA_;
     608             : 
     609           0 :       r.resize(); // drop reference to nearest cached solution
     610           0 :     }
     611           0 :     else if (timeType()=="linear") {
     612             :       // a ok, need c
     613           0 :       tC_.resize(nPar(),nChan(),nElem());
     614           0 :       Array<Float> rp,ip;
     615           0 :       rPart(tC_,rp);
     616           0 :       iPart(tC_,ip);
     617           0 :       rp = cos(tP_);
     618           0 :       ip = sin(tP_);
     619           0 :     } 
     620             :   }    
     621             : 
     622           0 : }
     623             : 
     624           0 : void CalInterp::updFreqCoeff() {
     625             : 
     626           0 :   if (verbose_) cout << "CalInterp::updFreqCoeff()" << endl;
     627             : 
     628             :   // Resize Coefficient arrays (no-op if already correct size)
     629           0 :   ip4d()(2)=ip2d()(0)=nFreq();
     630           0 :   fAC().resize(ip4d());
     631           0 :   fOk().resize(ip3d());
     632           0 :   if ( timeType()=="linear") 
     633           0 :     fPC().resize(ip4d());
     634           0 :   else if (timeType()=="aipslin") 
     635           0 :     fCC().resize(ip4d());
     636             : 
     637             :   // For indexing parameter cache
     638           0 :   IPosition lo(3,0,0,0), hi(3,0,0,0);
     639           0 :   IPosition ref(4,0,0,0,0), slope(4,1,0,0,0);
     640           0 :   for (Int ielem=0;ielem<nElem();ielem++) {
     641           0 :     lo(2)=hi(2)=ref(3)=slope(3)=ielem;
     642           0 :     for (Int ichan=0;ichan<nChan()-1;ichan++) {
     643           0 :       lo(1)=hi(1)=ref(2)=slope(2)=ichan;
     644             :       
     645           0 :       if (!ef()(ichan)) {
     646           0 :         for (Int ipar=0;ipar<nPar();ipar++) {
     647           0 :           lo(0)=hi(0)=ref(1)=slope(1)=ipar;
     648             : 
     649           0 :           fOk()(ipar,ichan,ielem) = tOk()(ipar,ichan,ielem) && 
     650           0 :                                     tOk()(ipar,ichan+1,ielem);
     651           0 :           if (fOk()(ipar,ichan,ielem)) {
     652             :             
     653             :             // Intercept
     654           0 :             fAC()(ref) = tA_(lo);
     655           0 :             fAC()(slope) = tA_(hi) - tA_(lo);
     656             :             
     657           0 :             if (freqType()=="linear") {
     658           0 :               fPC()(ref) = tP_(lo);
     659             :               
     660             :               // Slope
     661           0 :               Float pslope = tP_(hi) - tP_(lo);
     662             :               // Catch/remove simple phase wraps
     663           0 :               if (pslope > C::pi)
     664           0 :                 pslope-=(2*C::pi);
     665           0 :               else if (pslope < -C::pi)
     666           0 :                 pslope+=(2*C::pi);
     667           0 :               fPC()(slope) = pslope;
     668             :               
     669           0 :             } else if (freqType()=="aipslin") {
     670           0 :               fCC()(ref) = tC_(lo);
     671           0 :               fCC()(slope) = tC_(hi)-tC_(lo);
     672             :               
     673             :             }
     674             :           } else {
     675           0 :             fAC()(ref)=1.0;
     676           0 :             fAC()(slope)=0.0;
     677           0 :             if (timeType()=="linear") {
     678           0 :               fPC()(ref)=0.0;
     679           0 :               fPC()(slope)=0.0;
     680           0 :             } else if (timeType()=="aipslin") {
     681           0 :               fCC()(ref)=Complex(1.0,0.0);
     682           0 :               fCC()(slope)=Complex(0.0,0.0);
     683             :             }
     684             :           }   // fOk()
     685             :         }   // ipar
     686             :       }   // !ef()(ichan)
     687             :     } // ichan
     688             :   } // ielem
     689             : 
     690           0 : }
     691             : 
     692             : 
     693           0 : void CalInterp::interpFreqCalc() {
     694             : 
     695           0 :   if (verbose_) cout << "CalInterp::interpFreqCalc()" << endl;
     696             : 
     697             :   // TODO:
     698             :   //  a. Use matrix math instead of loops?  (fOk(), ef() usage?)
     699             : 
     700           0 :   fA_.resize(nPar(),nFreq(),nElem());
     701           0 :   a.reference(fA_);
     702           0 :   ok.reference(fOk());
     703           0 :   if (freqType()=="linear") {
     704           0 :     fP_.resize(nPar(),nFreq(),nElem());
     705           0 :     p.reference(fP_);
     706           0 :     c.resize();
     707             :   }
     708           0 :   else if (freqType()=="aipslin") {
     709           0 :     fC_.resize(nPar(),nFreq(),nElem());
     710           0 :     c.reference(fC_);
     711           0 :     p.resize();
     712             :   }
     713             : 
     714           0 :   IPosition ref(4,0,0,0,0),slope(4,1,0,0,0);
     715           0 :   for (Int ielem=ref(3)=slope(3)=0;
     716           0 :        ielem<nElem();
     717           0 :        ielem++,ref(3)++,slope(3)++) {
     718           0 :     for (Int ichan=ref(2)=slope(2)=0;
     719           0 :          ichan<nFreq();
     720           0 :          ichan++,ref(2)++,slope(2)++) {
     721             :       // if non-exact channel and otherwise ok, calc interp per par
     722           0 :       if ( !ef()(ichan) ) {
     723           0 :         for (Int ipar=ref(1)=slope(1)=0;
     724           0 :              ipar<nPar();
     725           0 :              ipar++,ref(1)++,ref(2)++) {
     726           0 :           if (fOk()(ipar,ichan,ielem) ) {
     727           0 :             fA_(ipar,ichan,ielem) = fAC()(ref) + fAC()(slope)*fdf()(ichan);
     728           0 :             if ( freqType()=="linear") {
     729           0 :               fP_(ipar,ichan,ielem) = fPC()(ref) + fPC()(slope)*fdf()(ichan);
     730           0 :             } else if ( freqType()=="aipslin") {
     731           0 :               fC_(ipar,ichan,ielem) = fCC()(ref) + fCC()(slope)*fdf()(ichan);
     732             :             }
     733             :           } 
     734             :           else {
     735             :             // copy from time interp
     736           0 :             fA_(ipar,ichan,ielem) = tA_(ipar,ch0()(ichan),ielem);
     737           0 :             if ( freqType()=="linear") {
     738           0 :               fP_(ipar,ichan,ielem) = tP_(ipar,ch0()(ichan),ielem);
     739           0 :             } else if ( freqType()=="aipslin") {
     740           0 :               fC_(ipar,ichan,ielem) = tC_(ipar,ch0()(ichan),ielem);
     741             :             }
     742             :           } // fOk()
     743             :         } // ipar
     744             :       } // !ef() 
     745             :     } // ichan
     746             :   } // ielem
     747             : 
     748           0 : }
     749             :   
     750           0 : void CalInterp::finalize() {
     751             : 
     752           0 :   if (verbose_) cout << "CalInterp::finalize()" << endl;
     753             : 
     754           0 :   if (!exactTime()) {
     755           0 :     if (p.nelements() > 0 ) {
     756             :       // if we did phase interp, shape and set r/i parts of r_
     757             :       //      cout << "CalInterp::finalize(): pppppp" << endl;
     758           0 :       c.resize(p.shape());
     759             :       
     760           0 :       Array<Float> rp,ip;
     761           0 :       rPart(c,rp);
     762           0 :       iPart(c,ip);
     763             :       
     764           0 :       rp = a*cos(p);
     765           0 :       ip = a*sin(p);
     766             : 
     767           0 :     } 
     768           0 :     else if (c.nelements() > 0) {
     769             :       
     770             :       // just reference c
     771           0 :       Array<Float> rp,ip;
     772           0 :       rPart(c,rp);
     773           0 :       iPart(c,ip);
     774           0 :       rp*=a;
     775           0 :       ip*=a;
     776             :       
     777           0 :     }
     778           0 :     r_.reference(c);
     779             :   }
     780             : 
     781             :   // make public by reference
     782           0 :   r.reference(r_);
     783             : 
     784           0 :   ok.reference(tOk());
     785             : 
     786           0 : }
     787             : 
     788             : 
     789             : // Deflate in-focus time interpolation coeff cache
     790           0 : void CalInterp::deflTimeC() {
     791             : 
     792           0 :   for (Int ispw=0; ispw<nSpw(); ispw++) {
     793           0 :     if (tAC_[ispw]) delete tAC_[ispw];
     794           0 :     if (tOk_[ispw]) delete tOk_[ispw];
     795           0 :     if (tPC_[ispw]) delete tPC_[ispw];
     796           0 :     if (tCC_[ispw]) delete tCC_[ispw];
     797             :     
     798           0 :     tAC_[ispw]=tPC_[ispw]= NULL;
     799           0 :     tOk_[ispw]=NULL;
     800           0 :     tCC_[ispw]=NULL;
     801             :   }    
     802           0 : }
     803             : 
     804             : // Deflate in-focus freq interpolation coefficient cache
     805           0 : void CalInterp::deflFreqC() {
     806             : 
     807           0 :   for (Int ispw=0;ispw<nSpw();ispw++) {
     808           0 :     if (fAC_[ispw]) delete fAC_[ispw];
     809           0 :     if (fOk_[ispw]) delete fOk_[ispw];
     810           0 :     if (fPC_[ispw]) delete fPC_[ispw];
     811           0 :     if (fCC_[ispw]) delete fCC_[ispw];
     812             :     
     813           0 :     fAC_[ispw]=fPC_[ispw]=NULL;
     814           0 :     fOk_[ispw]=NULL;
     815           0 :     fCC_[ispw]=NULL;
     816             :   }
     817           0 : }
     818             : 
     819             : // Deflate in-focus freq interpolation abscissa data
     820           0 : void CalInterp::deflFreqA() {
     821             : 
     822           0 :   for (Int ispw=0;ispw<nSpw();ispw++) {
     823           0 :     if ( ch0_[ispw] ) delete ch0_[ispw];
     824           0 :     if ( ef_[ispw] )  delete ef_[ispw];
     825           0 :     if ( df_[ispw] )  delete df_[ispw];
     826           0 :     if ( fdf_[ispw] ) delete fdf_[ispw];
     827             :     
     828           0 :     ch0_[ispw] = NULL;
     829           0 :     ef_[ispw] = NULL;
     830           0 :     df_[ispw] = fdf_[ispw] = NULL;
     831             :   }
     832           0 : }
     833             : 
     834           0 : void CalInterp::asFloatArr(const Array<Complex>& in, Array<Float>& out) {
     835           0 :   IPosition ip1(in.shape());
     836           0 :   IPosition ip2(1,2);
     837           0 :   ip2.append(ip1);
     838           0 :   out.takeStorage(ip2,(Float*)(in.data()),SHARE);
     839           0 : }
     840             : 
     841           0 : void CalInterp::part(const Array<Complex>& c, 
     842             :                      const Int& which,
     843             :                      Array<Float>& f) {
     844             : 
     845           0 :   IPosition ip1(c.shape());
     846           0 :   Array<Float> asfl;
     847           0 :   asFloatArr(c,asfl);
     848           0 :   IPosition ip2(asfl.shape());
     849           0 :   IPosition blc(ip2), trc(ip2);
     850           0 :   blc=0; trc-=1;
     851           0 :   blc(0)=trc(0)=which;
     852           0 :   f.reference(asfl(blc,trc).reform(ip1));
     853           0 : }
     854             : 
     855           0 : void CalInterp::setSpwOK() {
     856             : 
     857           0 :   for (Int i=0;i<nSpw();i++)
     858           0 :     if (spwMap(i)>-1)
     859           0 :       spwOK_(i) = cs_->spwOK()(spwMap(i));
     860             :     else
     861           0 :       spwOK_(i) = cs_->spwOK()(i);
     862             : 
     863             :   //  cout << "CalInterp::spwOK() (spwmap) = " << boolalpha << spwOK() << endl;
     864             : 
     865           0 : }
     866             : 
     867             : 
     868             : 
     869             : 
     870             : } //# NAMESPACE CASA - END
     871             : 

Generated by: LCOV version 1.16