LCOV - code coverage report
Current view: top level - synthesis/CalTables - CalSet.tcc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 420 0.0 %
Date: 2024-10-29 13:38:20 Functions: 0 22 0.0 %

          Line data    Source code
       1             : //# CalSet.cc: Implementation of Calibration parameter cache
       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 <algorithm>
      28             : #include <synthesis/CalTables/CalSet.h>
      29             : 
      30             : #include <synthesis/CalTables/CalTable2.h>
      31             : //#include <synthesis/CalTables/CalTable.h>
      32             : #include <synthesis/CalTables/CalDescColumns2.h>
      33             : #include <synthesis/CalTables/SolvableVJTable.h>
      34             : #include <synthesis/CalTables/CalMainColumns2.h>
      35             : 
      36             : #include <synthesis/CalTables/TimeVarVJDesc.h>
      37             : #include <synthesis/CalTables/SolvableVJDesc.h>
      38             : #include <synthesis/CalTables/SolvableVJMRec.h>
      39             : #include <synthesis/CalTables/SolvableVJMCol.h>
      40             : 
      41             : #include <casacore/tables/Tables/TableDesc.h>
      42             : #include <casacore/tables/Tables/SetupNewTab.h>
      43             : #include <casacore/tables/Tables/Table.h>
      44             : #include <casacore/tables/Tables/ScaColDesc.h>
      45             : #include <casacore/tables/Tables/ArrColDesc.h>
      46             : #include <casacore/tables/Tables/ScalarColumn.h>
      47             : #include <casacore/tables/Tables/ArrayColumn.h>
      48             : #include <casacore/tables/Tables/RefRows.h>
      49             : 
      50             : #include <casacore/casa/Arrays.h>
      51             : #include <casacore/scimath/Mathematics/MatrixMathLA.h>
      52             : #include <casacore/casa/BasicSL/String.h>
      53             : #include <casacore/casa/Utilities/Assert.h>
      54             : #include <casacore/casa/OS/Timer.h>
      55             : #include <casacore/casa/Exceptions/Error.h>
      56             : #include <casacore/casa/OS/Path.h>
      57             : #include <casacore/casa/sstream.h>
      58             : 
      59             : #include <casacore/casa/Logging/LogMessage.h>
      60             : #include <casacore/casa/Logging/LogSink.h>
      61             : 
      62             : namespace casa { //# NAMESPACE CASA - BEGIN
      63             : 
      64             : // ------------------------------------------------------------------
      65             : 
      66             : // From shape only, this is the solve context
      67           0 : template<class T> CalSet<T>::CalSet(const casacore::Int& nSpw) :
      68           0 :   calTableName_(""),
      69           0 :   nSpw_(nSpw),
      70           0 :   nPar_(0),
      71           0 :   nChan_(0),
      72           0 :   nElem_(0),
      73           0 :   nTime_(0),
      74           0 :   spwOK_(nSpw_,false),
      75           0 :   startChan_(nSpw_,0),  
      76           0 :   freq_(nSpw_,NULL),
      77           0 :   MJDStart_(nSpw_,NULL),
      78           0 :   MJDStop_(nSpw_,NULL),
      79           0 :   MJDTimeStamp_(nSpw_,NULL),
      80           0 :   fieldId_(nSpw_,NULL),
      81           0 :   fieldName_(nSpw_,NULL),
      82           0 :   sourceName_(nSpw_,NULL),
      83           0 :   par_(nSpw_,NULL),
      84           0 :   parOK_(nSpw_,NULL),
      85           0 :   parErr_(nSpw_,NULL),
      86           0 :   parSNR_(nSpw_,NULL),
      87             :   //  iSolutionOK_(nSpw_,NULL),
      88           0 :   iFit_(nSpw_,NULL),
      89           0 :   iFitwt_(nSpw_,NULL),
      90           0 :   solutionOK_(nSpw_,NULL),
      91           0 :   fit_(nSpw_,NULL),
      92           0 :   fitwt_(nSpw_,NULL)
      93             : {
      94           0 :   calTabDesc_=NULL;
      95           0 :   calTab_=NULL;
      96           0 :   svjmcol_=NULL;
      97           0 : };
      98             : 
      99             : // From shape only, this is the solve context
     100             : template<class T> CalSet<T>::CalSet(const casacore::Int& nSpw,
     101             :                                     const casacore::Int& nPar,
     102             :                                     const casacore::Vector<casacore::Int>& nChan,
     103             :                                     const casacore::Int& nElem,
     104             :                                     const casacore::Vector<casacore::Int>& nTime) :
     105             :   calTableName_(""),
     106             :   nSpw_(nSpw),
     107             :   nPar_(nPar),
     108             :   nChan_(nChan),
     109             :   nElem_(nElem),
     110             :   nTime_(nTime),
     111             :   spwOK_(nSpw_,false),
     112             :   startChan_(nSpw_,0),  
     113             :   freq_(nSpw_,NULL),
     114             :   MJDStart_(nSpw_,NULL),
     115             :   MJDStop_(nSpw_,NULL),
     116             :   MJDTimeStamp_(nSpw_,NULL),
     117             :   fieldId_(nSpw_,NULL),
     118             :   fieldName_(nSpw_,NULL),
     119             :   sourceName_(nSpw_,NULL),
     120             :   par_(nSpw_,NULL),
     121             :   parOK_(nSpw_,NULL),
     122             :   parErr_(nSpw_,NULL),
     123             :   parSNR_(nSpw_,NULL),
     124             :   //  iSolutionOK_(nSpw_,NULL),
     125             :   iFit_(nSpw_,NULL),
     126             :   iFitwt_(nSpw_,NULL),
     127             :   solutionOK_(nSpw_,NULL),
     128             :   fit_(nSpw_,NULL),
     129             :   fitwt_(nSpw_,NULL)
     130             : {
     131             :   calTabDesc_=NULL;
     132             :   calTab_=NULL;
     133             :   svjmcol_=NULL;
     134             :   // Resize caches
     135             :   inflate();  
     136             : };
     137             : 
     138             : 
     139             : // From existing CalTable name, this is apply context
     140           0 : template<class T> CalSet<T>::CalSet(const casacore::String& calTableName,
     141             :                                     const casacore::String& select,
     142             :                                     const casacore::Int& nSpw,
     143             :                                     const casacore::Int& nPar,
     144             :                                     const casacore::Int& nElem) : 
     145           0 :   calTableName_(calTableName),
     146           0 :   nSpw_(nSpw),
     147           0 :   nPar_(nPar),
     148           0 :   nChan_(nSpw,0),
     149           0 :   nElem_(nElem),
     150           0 :   nTime_(nSpw,0),
     151           0 :   spwOK_(nSpw_,false),
     152           0 :   startChan_(nSpw_,0),  
     153           0 :   freq_(nSpw_,NULL),
     154           0 :   MJDStart_(nSpw_,NULL),
     155           0 :   MJDStop_(nSpw_,NULL),
     156           0 :   MJDTimeStamp_(nSpw_,NULL),
     157           0 :   fieldId_(nSpw_,NULL),
     158           0 :   fieldName_(nSpw_,NULL),
     159           0 :   sourceName_(nSpw_,NULL),
     160           0 :   par_(nSpw_,NULL),
     161           0 :   parOK_(nSpw_,NULL),
     162           0 :   parErr_(nSpw_,NULL),
     163           0 :   parSNR_(nSpw_,NULL),
     164             :   //  iSolutionOK_(nSpw_,NULL),
     165           0 :   iFit_(nSpw_,NULL),
     166           0 :   iFitwt_(nSpw_,NULL),
     167           0 :   solutionOK_(nSpw_,NULL),
     168           0 :   fit_(nSpw_,NULL),
     169           0 :   fitwt_(nSpw_,NULL)
     170             : {
     171           0 :   calTabDesc_=NULL;
     172           0 :   calTab_=NULL;
     173           0 :   svjmcol_=NULL;
     174             : 
     175             :   // Fill from table
     176           0 :   load(calTableName,select);
     177             : 
     178             :   // Set spwOK_ according to available calibration
     179           0 :   setSpwOK();
     180             : 
     181           0 : }
     182             : 
     183           0 : template<class T> CalSet<T>::~CalSet() {
     184           0 :   deflate();
     185           0 : }
     186             : 
     187           0 : template<class T> void CalSet<T>::resize(const casacore::Int& nPar,
     188             :                                          const casacore::Vector<casacore::Int>& nChan,
     189             :                                          const casacore::Int& nElem,
     190             :                                          const casacore::Vector<casacore::Int>& nTime) {
     191           0 :   nPar_=nPar;
     192           0 :   nChan_=nChan;
     193           0 :   nElem_=nElem;
     194           0 :   nTime_=nTime;
     195             : 
     196           0 :   inflate();
     197             : 
     198           0 : }
     199             : 
     200             : 
     201             : 
     202             : // Inflate cache to proper size
     203           0 : template<class T> void CalSet<T>::inflate() {
     204             :   
     205             :   // Construct shaped pointed-to objects in cache
     206             : 
     207             :   // TODO:
     208             :   //  Consider initialization value (per type)
     209             : 
     210             :   // Delete exiting cache
     211           0 :   deflate();
     212             : 
     213           0 :   for (casacore::Int ispw=0; ispw<nSpw_; ispw++) {
     214           0 :     casacore::uInt ntime=nTime_(ispw);
     215           0 :     if (ntime > 0) {
     216             : 
     217           0 :       freq_[ispw]         = new casacore::Vector<casacore::Double>(nChan_(ispw),0.0);
     218             :       
     219           0 :       MJDStart_[ispw]     = new casacore::Vector<casacore::Double>(ntime,0.0);
     220           0 :       MJDStop_[ispw]      = new casacore::Vector<casacore::Double>(ntime,0.0);
     221           0 :       MJDTimeStamp_[ispw] = new casacore::Vector<casacore::Double>(ntime,0.0);
     222           0 :       fieldName_[ispw]    = new casacore::Vector<casacore::String>(ntime,"");
     223           0 :       sourceName_[ispw]   = new casacore::Vector<casacore::String>(ntime,"");
     224           0 :       fieldId_[ispw]      = new casacore::Vector<casacore::Int>(ntime,-1);
     225             : 
     226           0 :       casacore::IPosition parshape(4,nPar_,nChan_(ispw),nElem_,ntime);
     227           0 :       par_[ispw]     = new casacore::Array<T>(parshape,(T)1.0);
     228           0 :       parOK_[ispw]   = new casacore::Array<casacore::Bool>(parshape,false);
     229           0 :       parErr_[ispw]  = new casacore::Array<casacore::Float>(parshape,0.0f);
     230           0 :       parSNR_[ispw]  = new casacore::Array<casacore::Float>(parshape,0.0f);
     231             : 
     232             :       //      iSolutionOK_[ispw]  = new casacore::Matrix<casacore::Bool>(nElem_,ntime,false);
     233           0 :       iFit_[ispw]         = new casacore::Matrix<casacore::Float>(nElem_,ntime,0.0f);
     234           0 :       iFitwt_[ispw]       = new casacore::Matrix<casacore::Float>(nElem_,ntime,0.0f);
     235           0 :       solutionOK_[ispw]   = new casacore::Vector<casacore::Bool>(ntime,false);
     236           0 :       fit_[ispw]          = new casacore::Vector<casacore::Float>(ntime,0.0f);
     237           0 :       fitwt_[ispw]        = new casacore::Vector<casacore::Float>(ntime,0.0f);
     238           0 :     }
     239             :   }
     240             : 
     241           0 : }
     242             : 
     243             : 
     244             : 
     245             : 
     246           0 : template<class T> void CalSet<T>::deflate() {
     247             :   
     248             :   // Delete parameter memory
     249             : 
     250           0 :   for (casacore::Int ispw=0; ispw<nSpw_; ispw++) {
     251           0 :     if (MJDStart_[ispw])     delete MJDStart_[ispw];
     252           0 :     if (MJDStop_[ispw])      delete MJDStop_[ispw];
     253           0 :     if (MJDTimeStamp_[ispw]) delete MJDTimeStamp_[ispw];
     254           0 :     if (fieldName_[ispw])    delete fieldName_[ispw];
     255           0 :     if (sourceName_[ispw])   delete sourceName_[ispw];
     256           0 :     if (fieldId_[ispw])      delete fieldId_[ispw];
     257           0 :     if (par_[ispw])          delete par_[ispw];
     258           0 :     if (parOK_[ispw])        delete parOK_[ispw];
     259           0 :     if (parErr_[ispw])       delete parErr_[ispw];
     260           0 :     if (parSNR_[ispw])       delete parSNR_[ispw];
     261             :     //    if (iSolutionOK_[ispw])  delete iSolutionOK_[ispw];
     262           0 :     if (iFit_[ispw])         delete iFit_[ispw];
     263           0 :     if (iFitwt_[ispw])       delete iFitwt_[ispw];
     264           0 :     if (solutionOK_[ispw])   delete solutionOK_[ispw];
     265           0 :     if (fit_[ispw])          delete fit_[ispw];
     266           0 :     if (fitwt_[ispw])        delete fitwt_[ispw];
     267           0 :     MJDStart_[ispw]=NULL;
     268           0 :     MJDStop_[ispw]=NULL;
     269           0 :     MJDTimeStamp_[ispw]=NULL;
     270           0 :     fieldName_[ispw]=NULL;
     271           0 :     sourceName_[ispw]=NULL;
     272           0 :     fieldId_[ispw]=NULL;
     273           0 :     par_[ispw]=NULL;
     274           0 :     parOK_[ispw]=NULL;
     275           0 :     parErr_[ispw]=NULL;
     276           0 :     parSNR_[ispw]=NULL;
     277             :     //    iSolutionOK_[ispw]=NULL;
     278           0 :     iFit_[ispw]=NULL;
     279           0 :     iFitwt_[ispw]=NULL;
     280           0 :     solutionOK_[ispw]=NULL;
     281           0 :     fit_[ispw]=NULL;
     282           0 :     fitwt_[ispw]=NULL;
     283             :   }
     284           0 : }
     285             : 
     286             : 
     287             : 
     288           0 : template<class T> void CalSet<T>::load (const casacore::String& file, 
     289             :                                         const casacore::String& select)
     290             : {
     291             :   // Load data from a calibration table
     292             :   // casacore::Input:
     293             :   //    file         const casacore::String&       Cal table name
     294             :   //    select       const casacore::String&       Selection string
     295             :   //
     296             : 
     297             : 
     298             :   //  cout << "CalSet::load...(nSpw_=" << nSpw_ << ")" << endl;
     299             : 
     300           0 :   casacore::Timer timer;
     301           0 :   timer.mark();
     302             :   
     303           0 :   casacore::LogMessage message(casacore::LogOrigin("CalSet","load"));
     304             :   
     305             :   // Decode the Jones matrix type
     306             :   /*
     307             :   casacore::Int jonesType = 0;
     308             :   if (nPar_ == 1) jonesType = 1;
     309             :   if (nPar_ == 2) jonesType = 2;
     310             :   if (nPar_ == 4) jonesType = 3;
     311             :   */
     312             : 
     313             :  // Open, select, sort the calibration table
     314           0 :   SolvableVisJonesTable svjtab(file);
     315           0 :   svjtab.select2(select);
     316             : 
     317             :   // Get no. of antennas and time slots
     318           0 :   casacore::Int numberAnt = svjtab.maxAntenna() + 1;
     319             : 
     320             :   //  cout << "Initial selection: " << timer.all_usec()/1.0e6 << endl;
     321           0 :   timer.mark();
     322             : 
     323           0 :   AlwaysAssert(numberAnt==nElem_,casacore::AipsError)
     324             : 
     325           0 :   casacore::Int nDesc=svjtab.nRowDesc();
     326           0 :   casacore::Vector<casacore::Int> spwmap(nDesc,-1);
     327             : 
     328           0 :   casacore::Vector<casacore::Int> nRowPerCDI;
     329           0 :   svjtab.rowsPerCalDescId(nRowPerCDI);
     330             : 
     331             :   //  cout << "Optimized CDI count: " << timer.all_usec()/1.0e6 << endl;
     332           0 :   timer.mark();
     333             : 
     334           0 :   for (casacore::Int idesc=0;idesc<nDesc;idesc++) {
     335             : 
     336             :     // This cal desc
     337           0 :     CalDescRecord* calDescRec = new CalDescRecord (svjtab.getRowDesc(idesc));
     338             : 
     339             :     // Get this spw ID
     340           0 :     casacore::Vector<casacore::Int> spwlist;
     341           0 :     calDescRec->getSpwId(spwlist);
     342           0 :     casacore::Int nSpw; spwlist.shape(nSpw);
     343           0 :     if (nSpw > 1) {};  // ERROR!!!  Should only be one spw per cal desc!
     344           0 :     spwmap(idesc)=spwlist(0);
     345             : 
     346             :     // Trap spwids that do not occur in the MS
     347             :     // (Since we rely on the casacore::MS meta info for the calibration solutions,
     348             :     //  we cannot identify spws that do not occur in the MS.)
     349           0 :     if (spwlist(0)>nSpw_-1)
     350           0 :       throw(casacore::AipsError("Caltable '"+file+"' contains spw = "+
     351           0 :                       casacore::String::toString(spwlist(0))+
     352             :                       " which does not occur in the MS.  Cannot proceed."));
     353             : 
     354             :     // In next few steps, need to watch for repeat spws in new cal descs!!
     355             : 
     356             :     // Get number of channels this spw
     357           0 :     casacore::Vector<casacore::Int> nchanlist;
     358             : 
     359           0 :     calDescRec->getNumChan(nchanlist);
     360           0 :     nChan_(spwmap(idesc))=nchanlist(0);
     361             : 
     362             :     // Get channel range / start channel
     363           0 :     casacore::Cube<casacore::Int> chanRange;
     364           0 :     calDescRec->getChanRange(chanRange);
     365           0 :     startChan_(spwmap(idesc))=chanRange(0,0,0);
     366             : 
     367             :     // Get slot count for this desc's spw
     368           0 :     nTime_(spwmap(idesc))=nRowPerCDI(idesc)/numberAnt;
     369             : 
     370           0 :     delete calDescRec;  
     371             :   }
     372             : 
     373             :   //  cout << "CalDesc sizeup: " << timer.all_usec()/1.0e6 << endl;
     374             :   //  cout << "nTime_ = " << nTime_ << endl;
     375             : 
     376           0 :   timer.mark();
     377             : 
     378             :   // At this point, we know how big our slot-dep caches must be
     379             :   //  (in private data), so initialize them
     380           0 :   inflate();
     381             : 
     382             :   // Remember if we found and filled any solutions
     383           0 :   casacore::Bool solfillok(false);
     384             : 
     385             :   //  cout << "CalSet inflated: " << timer.all_usec()/1.0e6 << endl;
     386             : 
     387             : 
     388             :   // Fill per caldesc
     389           0 :   casacore::Double ttime(0.0);
     390           0 :   for (casacore::Int idesc=0;idesc<nDesc;idesc++) {
     391             : 
     392             :     //    cout << "CDI = " << idesc << " "<< flush;
     393             : 
     394           0 :     timer.mark();
     395             : 
     396           0 :     casacore::Int thisSpw=spwmap(idesc);
     397             :       
     398             :     // Reopen and globally select caltable
     399             :     //SolvableVisJonesTable svjtabspw(file);
     400           0 :     CalTable2 svjtabspw(file);
     401           0 :     svjtabspw.select2(select);
     402             : 
     403             :     //    cout << " Sel: " << timer.all_usec()/1.0e6 << flush;
     404             : 
     405             :     // isolate this caldesc:
     406           0 :     std::ostringstream selectstr;
     407           0 :     selectstr << "CAL_DESC_ID == " << idesc;
     408           0 :     casacore::String caldescsel; caldescsel = selectstr.str();
     409           0 :     svjtabspw.select2(caldescsel);
     410             : 
     411             :     //    cout << " CDIsel: " << timer.all_usec()/1.0e6 << flush;
     412             : 
     413             :     //    cout << "Sorting..." << endl;
     414           0 :     casacore::Block<casacore::String> scol(1);
     415           0 :     scol[0]="TIME";
     416           0 :     svjtabspw.sort2(scol);
     417             : 
     418             :     //    cout << " casacore::Sort: " << timer.all_usec()/1.0e6 << flush;
     419             : 
     420           0 :     casacore::Int nrow = svjtabspw.nRowMain();
     421           0 :     casacore::IPosition out(3,0,0,0);   // par, chan, row
     422           0 :     casacore::IPosition in(4,0,0,0,0);  // par, chan, ant, slot
     423           0 :     if (nrow>0) {
     424             : 
     425             :       // Found some solutions to fill
     426           0 :       solfillok=true;
     427             : 
     428             :       // Ensure sorted on time
     429           0 :       casacore::Block <casacore::String> sortCol(1,"TIME");
     430           0 :       svjtabspw.sort2(sortCol);
     431             :       
     432             :       // Extract the gain table columns
     433             :       //ROSolvableVisJonesMCol svjmcol(svjtabspw);
     434             :       ROSolvableCalSetMCol<T> *svjmcol;
     435           0 :       svjmcol= new ROSolvableCalSetMCol<T>(svjtabspw);
     436             : 
     437           0 :       casacore::Vector<casacore::Int>    calDescId;  (*svjmcol).calDescId().getColumn(calDescId);
     438           0 :       casacore::Vector<casacore::Double> time;       (*svjmcol).time().getColumn(time);
     439           0 :       casacore::Vector<casacore::Double> interval;   (*svjmcol).interval().getColumn(interval);
     440           0 :       casacore::Vector<casacore::Int>    antenna1;   (*svjmcol).antenna1().getColumn(antenna1);
     441             :       //      cout << "antennas = " << antenna1 << endl;
     442           0 :       casacore::Vector<casacore::Int>    fieldId;    (*svjmcol).fieldId().getColumn(fieldId);
     443             :       //      cout << "fieldId = " << fieldId << endl;
     444           0 :       casacore::Vector<casacore::String> fieldName;  (*svjmcol).fieldName().getColumn(fieldName);
     445           0 :       casacore::Vector<casacore::String> sourceName; (*svjmcol).sourceName().getColumn(sourceName);
     446           0 :       casacore::Vector<casacore::Bool>   totalSolOk; (*svjmcol).totalSolnOk().getColumn(totalSolOk);
     447           0 :       casacore::Vector<casacore::Float>  totalFit;   (*svjmcol).totalFit().getColumn(totalFit);
     448           0 :       casacore::Vector<casacore::Float>  totalFitWt; (*svjmcol).totalFitWgt().getColumn(totalFitWt);
     449           0 :       casacore::Array<T> gain;       (*svjmcol).gain().getColumn(gain);
     450           0 :       casacore::Cube<casacore::Bool>     solOk;      (*svjmcol).solnOk().getColumn(solOk);
     451           0 :       casacore::Cube<casacore::Float>    fit;        (*svjmcol).fit().getColumn(fit);
     452           0 :       casacore::Cube<casacore::Float>    fitWt;      (*svjmcol).fitWgt().getColumn(fitWt);
     453           0 :       casacore::Cube<casacore::Bool>     flag;       (*svjmcol).flag().getColumn(flag);
     454           0 :       casacore::Cube<casacore::Float>    snr;        (*svjmcol).snr().getColumn(snr);
     455             : 
     456             :       // Read the calibration information
     457           0 :       casacore::Double /*lastTime(-1.0),*/ thisTime(0.0), thisInterval(0.0);
     458           0 :       casacore::Int islot(-1);
     459             :       casacore::Int iant;
     460             : 
     461           0 :       for (casacore::Int irow=0; irow<nrow; irow++) {
     462           0 :         out(2)=irow;
     463             : 
     464           0 :         thisTime=time(irow);
     465             :         
     466             :         // If this is a new solution
     467           0 :         if (irow%numberAnt==0) {
     468             : 
     469           0 :           islot++;
     470           0 :           in(3)=islot;
     471             :           
     472           0 :           thisInterval=interval(irow);
     473           0 :           (*MJDTimeStamp_[thisSpw])(islot) = thisTime;
     474           0 :           (*MJDStart_[thisSpw])(islot) = thisTime - thisInterval / 2.0;
     475           0 :           (*MJDStop_[thisSpw])(islot) = thisTime + thisInterval / 2.0;
     476           0 :           (*fieldId_[thisSpw])(islot) = fieldId(irow);
     477           0 :           (*fieldName_[thisSpw])(islot) = fieldName(irow);
     478           0 :           (*sourceName_[thisSpw])(islot) = sourceName(irow);
     479             :           
     480           0 :           (*solutionOK_[thisSpw])(islot) = totalSolOk(irow);
     481           0 :           (*fit_[thisSpw])(islot) = totalFit(irow);
     482           0 :           (*fitwt_[thisSpw])(islot) = totalFitWt(irow);
     483             :           
     484             :           //lastTime = thisTime;
     485             :         };
     486             :         
     487           0 :         iant=antenna1(irow);
     488           0 :         in(2)=iant;
     489             : 
     490             :         //      (*iSolutionOK_[thisSpw])(iant,islot) = solOk(0,0,irow);
     491           0 :         (*iFit_[thisSpw])(iant,islot) = fit(0,0,irow);
     492           0 :         (*iFitwt_[thisSpw])(iant,islot) = fitWt(0,0,irow);
     493             :         
     494           0 :         for (casacore::Int ichan=0; ichan<nChan_(thisSpw); ichan++) {
     495             : 
     496             : 
     497           0 :           out(1)=in(1)=ichan;
     498             : 
     499           0 :           for (casacore::Int ipar=0; ipar<nPar_; ipar++) {
     500           0 :             in(0)=out(0)=ipar;
     501           0 :             (*par_[thisSpw])(in)=gain(out);
     502           0 :             (*parOK_[thisSpw])(in) = (solOk(out) && !flag(out));
     503           0 :             (*parSNR_[thisSpw])(in) = snr(out);
     504             :           }
     505             :         }
     506             :         
     507             :       } // irow
     508           0 :     } // nrow>0
     509             : 
     510             :     //    cout << "cs fields = " << *fieldId_[thisSpw] << endl;
     511             : 
     512           0 :     casacore::Double itime=timer.all_usec()/1.0e6;
     513           0 :     ttime+=itime;
     514             : 
     515             :     //    cout << " Totals: " << itime << " " << ttime << endl;
     516             : 
     517             :   } // idesc
     518             : 
     519             :   // If we found no solutions in selected table, abort:
     520           0 :   if (!solfillok) {
     521           0 :       throw(casacore::AipsError(" Specified cal table selection selects no solutions in this table.  Please review setapply settings."));
     522             :   }
     523             : 
     524             : 
     525           0 : };
     526             : 
     527           0 : template<class T> void CalSet<T>::initCalTableDesc(const casacore::String& type, const casacore::Int& parType)
     528             : {
     529           0 :   if (calTabDesc_) {delete calTabDesc_;calTabDesc_=NULL;}
     530           0 :   calTabDesc_=new CalTableDesc2(type,parType);
     531           0 : }
     532             : 
     533           0 : template<class T> void CalSet<T>::attach()
     534             : {
     535           0 : }
     536             : 
     537             : 
     538           0 : template<class T> void CalSet<T>::store (const casacore::String& file, 
     539             :                                          const casacore::String& type,
     540             :                                          const casacore::Bool& append,
     541             :                                          const casacore::String& msname)
     542             : {
     543             :   // Write the solutions to an output calibration table
     544             :   // casacore::Input:
     545             :   //    file           casacore::String        Cal table name
     546             :   //    append         casacore::Bool          Append if true, else overwrite
     547             :   //
     548             : 
     549             :   // total rows to be written per Spw
     550           0 :   casacore::Vector<casacore::Int> nRow(nSpw_,0);
     551           0 :   for (casacore::Int iSpw=0;iSpw<nSpw_;iSpw++) 
     552           0 :     if (solutionOK_[iSpw])
     553           0 :       nRow(iSpw)=nElem_*ntrue(*(solutionOK_[iSpw]));
     554             : 
     555             :   // Escape if nothing to write
     556           0 :   if (sum(nRow)==0)
     557           0 :     throw(casacore::AipsError("No valid calibration solutions; no table written."));
     558             : 
     559             :   // Initialization:
     560             :   // No. of rows in cal_main, cal_desc and cal_history
     561           0 :   casacore::Int nMain = 0; 
     562           0 :   casacore::Int nDesc = 0;
     563             :   //casacore::Int nHist = 0;
     564             :   
     565           0 :   if (calTabDesc_ == NULL)
     566             :     {
     567           0 :       std::ostringstream str;
     568             :       str << "CalSet::store(): Perhaps CalSet.initCalTableDesc() was not called "
     569             :           << "before calling CalSet::store()?"
     570           0 :           << "  Jones = " << type << "   File = " << file;
     571             :       
     572           0 :       throw(casacore::AipsError(str.str()));
     573           0 :     }
     574             : 
     575           0 :   calTabDesc_->addDesc(calTabDesc_->defaultFitDesc(),calTabDesc_->calMainDesc());
     576             : 
     577             :   // Calibration table
     578             :   //  SolvableVisJonesTable *tab;
     579             :   
     580             :   // Open the output file if it already exists and is being appended to.
     581           0 :   if (calTab_) delete calTab_; calTab_=NULL;
     582             : 
     583           0 :   if (append && casacore::Table::isWritable (file)) {
     584             :     //    tab  = new SolvableVisJonesTable (file, casacore::Table::Update);
     585           0 :     calTab_  = new CalTable2 (file, *calTabDesc_, casacore::Table::Update);
     586           0 :     nMain = calTab_->nRowMain();
     587           0 :     nDesc = calTab_->nRowDesc();
     588             :     //nHist = calTab_->nRowHistory();
     589             :   } else {
     590             :     // Create a new calibration table
     591           0 :     casacore::Table::TableOption access = casacore::Table::New;
     592             :     //    tab = new SolvableVisJonesTable (file, type, access);
     593           0 :     calTab_ = new CalTable2 (file, *calTabDesc_, access);
     594             :   };
     595             :   
     596             :   // Write every spw w/ max number of channels 
     597             :   //  (eventually, CalTable should permit variable-shape cols)
     598           0 :   casacore::Int maxNumChan(1);
     599           0 :   for (casacore::Int iSpw=0; iSpw<nSpw_; iSpw++) 
     600           0 :     if (par_[iSpw]!=NULL) 
     601           0 :       maxNumChan=std::max(maxNumChan,nChan_(iSpw));
     602             : 
     603             :   // Some default values
     604           0 :   casacore::Double dzero = 0;
     605           0 :   casacore::IPosition ip(2,1,maxNumChan);
     606             : 
     607             :   // CalDesc Sub-table records
     608             :   CalDescRecord* descRec;
     609           0 :   casacore::Vector<casacore::Int> calDescNum(nSpw_); calDescNum=-1;
     610           0 :   for (casacore::Int iSpw=0; iSpw<nSpw_; iSpw++) {
     611             : 
     612             :     // Write a CalDesc for each spw which has solutions
     613             :     // Note: CalDesc index != SpwId, in general
     614             : 
     615           0 :     if (nRow(iSpw)>0 && par_[iSpw]!=NULL) {
     616             : 
     617             :       // Access to existing CAL_DESC columns:
     618           0 :       CalDescColumns2 cd(*calTab_);
     619             : 
     620             :       // Check if this spw already in CAL_DESC 
     621             :       //      cout << "spwCol = " << cd.spwId().getColumn() << endl;
     622             : 
     623           0 :       casacore::Bool newCD(true);
     624           0 :       for (casacore::Int iCD=0;iCD<nDesc;iCD++) {
     625             : 
     626           0 :         casacore::IPosition iCDip(1,0);
     627           0 :         if ( iSpw==(cd.spwId()(iCD))(iCDip) ) {
     628             :           // Don't need new CAL_DESC entry
     629           0 :           newCD=false;
     630           0 :           calDescNum(iSpw)=iCD;
     631           0 :           break;
     632             :         }
     633             :       }
     634             : 
     635           0 :       if (newCD) {
     636             : 
     637             :         // Cal_desc fields
     638           0 :         casacore::Vector <casacore::Int> spwId(1,iSpw);
     639           0 :         casacore::Matrix <casacore::Double> chanFreq(ip, dzero); 
     640           0 :         casacore::Matrix <casacore::Double> chanWidth(ip, dzero);
     641           0 :         casacore::Array <casacore::String> polznType(ip, casacore::String(""));
     642           0 :         casacore::Cube <casacore::Int> chanRange(casacore::IPosition(3,2,1,maxNumChan), 0);
     643           0 :         casacore::Vector <casacore::Int> numChan(1,nChan_(iSpw));
     644           0 :         for (casacore::Int ichan=0; ichan<nChan_(iSpw); ichan++) {
     645           0 :           chanRange(0,0,ichan)=startChan_(iSpw);
     646           0 :           chanRange(1,0,ichan)=startChan_(iSpw) + nChan_(iSpw) -1;
     647             :         }
     648             :         
     649             :         // Fill the cal_desc record
     650           0 :         descRec = new CalDescRecord;
     651           0 :         descRec->defineNumSpw (1);
     652           0 :         descRec->defineNumChan (numChan);
     653           0 :         descRec->defineNumReceptors (2);
     654           0 :         descRec->defineNJones (2);
     655           0 :         descRec->defineSpwId (spwId);
     656           0 :         descRec->defineChanFreq (chanFreq);
     657           0 :         descRec->defineChanWidth (chanWidth);
     658           0 :         descRec->defineChanRange (chanRange);
     659           0 :         descRec->definePolznType (polznType);
     660           0 :         descRec->defineJonesType ("full");
     661           0 :         descRec->defineMSName (casacore::Path(msname).baseName());
     662             :         //      descRec->defineMSName ("");
     663             :         
     664             :         // Write the cal_desc record
     665             : 
     666           0 :         calTab_->putRowDesc (nDesc, *descRec);
     667           0 :         delete descRec;
     668             :         
     669             :         // This spw will have this calDesc index in main table
     670           0 :         calDescNum(iSpw) = nDesc;
     671           0 :         nDesc++;
     672           0 :       }
     673             : 
     674           0 :     }
     675             :     
     676             :   }
     677             : 
     678             : 
     679             :   // Now write MAIN table in column-wise fashion
     680             :   
     681             :   // Starting row in this slot
     682             : 
     683           0 :   for (casacore::Int iSpw=0; iSpw<nSpw_; iSpw++) {
     684             : 
     685             :     // Write table for spws which have solutions
     686           0 :     if (par_[iSpw]!=NULL) {
     687             : 
     688             :       // Create references to cal data for this spw
     689           0 :       casacore::Vector<casacore::Bool>    thisSolOK;        thisSolOK.reference(*(solutionOK_[iSpw]));
     690           0 :       casacore::Vector<casacore::Double>  thisMJDTimeStamp; thisMJDTimeStamp.reference(*(MJDTimeStamp_[iSpw]));
     691           0 :       casacore::Vector<casacore::Double>  thisMJDStart;     thisMJDStart.reference(*(MJDStart_[iSpw]));
     692           0 :       casacore::Vector<casacore::Double>  thisMJDStop;      thisMJDStop.reference(*(MJDStop_[iSpw]));
     693           0 :       casacore::Vector<casacore::Int>     thisFieldId;      thisFieldId.reference(*(fieldId_[iSpw]));
     694           0 :       casacore::Vector<casacore::String>  thisFieldName;    thisFieldName.reference(*(fieldName_[iSpw]));
     695           0 :       casacore::Vector<casacore::String>  thisSourceName;   thisSourceName.reference(*(sourceName_[iSpw]));
     696           0 :       casacore::Vector<casacore::Float>   thisFit;          thisFit.reference(*(fit_[iSpw]));
     697           0 :       casacore::Vector<casacore::Float>   thisFitwt;        thisFitwt.reference(*(fitwt_[iSpw]));
     698             :       //      casacore::Array<casacore::Complex>  thisAntGain;      thisAntGain.reference(*(par_[iSpw]));
     699           0 :       casacore::Array<T>  thisAntGain;      thisAntGain.reference(*(par_[iSpw]));
     700             :       //      casacore::Matrix<casacore::Bool>    thisISolutionOK;  thisISolutionOK.reference(*(iSolutionOK_[iSpw]));
     701           0 :       casacore::Matrix<casacore::Float>   thisIFit;         thisIFit.reference(*(iFit_[iSpw]));
     702           0 :       casacore::Matrix<casacore::Float>   thisIFitwt;       thisIFitwt.reference(*(iFitwt_[iSpw]));
     703             : 
     704           0 :       casacore::Int thisnRow=nRow(iSpw);
     705             :       
     706             :       // Only if there are rows to add to table
     707           0 :       if (thisnRow > 0) {
     708             : 
     709             :         // These are constant columns (with boring values, currently)
     710           0 :         casacore::Vector<casacore::Double> timeEP(thisnRow,0.0);
     711           0 :         casacore::Vector<casacore::Int> feed1(thisnRow,0);
     712           0 :         casacore::Vector<casacore::Int> arrayId(thisnRow,0);
     713           0 :         casacore::Vector<casacore::Int> obsId(thisnRow,0);
     714           0 :         casacore::Vector<casacore::Int> scanNum(thisnRow,0);
     715           0 :         casacore::Vector<casacore::Int> procId(thisnRow,0);
     716           0 :         casacore::Vector<casacore::Int> stateId(thisnRow,0);
     717           0 :         casacore::Vector<casacore::Int> phaseId(thisnRow,0);
     718           0 :         casacore::Vector<casacore::Int> pulsarBin(thisnRow,0);
     719           0 :         casacore::Vector<casacore::Int> pulsarGateId(thisnRow,0);
     720           0 :         casacore::Vector<casacore::Int> freqGroup(thisnRow,0);
     721           0 :         casacore::Vector<casacore::Int> calHistId(thisnRow,0);
     722             :         
     723             :         // This is constant
     724           0 :         casacore::Vector<casacore::Int> calDescId(thisnRow,calDescNum(iSpw));
     725             :         
     726             :         // These are constant per slot
     727             :         //   (these cols should be incremental)
     728           0 :         casacore::Vector<casacore::Double> time(thisnRow,0.0);
     729           0 :         casacore::Vector<casacore::Double> interval(thisnRow,0.0);
     730           0 :         casacore::Vector<casacore::Int>    fieldId(thisnRow,0);
     731           0 :         casacore::Vector<casacore::String> fieldName(thisnRow,"");
     732           0 :         casacore::Vector<casacore::String> sourceName(thisnRow,"");
     733           0 :         casacore::Vector<casacore::Bool>   totalSolOk(thisnRow,false);
     734           0 :         casacore::Vector<casacore::Float>  totalFit(thisnRow,0.0);
     735           0 :         casacore::Vector<casacore::Float>  totalFitWt(thisnRow,0.0);
     736             :         
     737             :         // These vary
     738           0 :         casacore::Vector<casacore::Int>    antenna1(thisnRow,0);
     739           0 :         casacore::Cube<T>  gain(casacore::IPosition(3,nPar(),maxNumChan,thisnRow),T(0.0));
     740           0 :         casacore::Cube<casacore::Bool>     solOk(nPar(),maxNumChan,thisnRow,false);
     741           0 :         casacore::Cube<casacore::Float>    fit(1,maxNumChan,thisnRow,0.0);
     742           0 :         casacore::Cube<casacore::Float>    fitWt(1,maxNumChan,thisnRow,0.0);
     743           0 :         casacore::Cube<casacore::Bool>     flag(nPar(),maxNumChan,thisnRow,false);
     744           0 :         casacore::Cube<casacore::Float>    snr(nPar(),maxNumChan,thisnRow,false);
     745             : 
     746           0 :         casacore::IPosition out(3,0,0,0);   // par, chan, row
     747           0 :         casacore::IPosition in(4,0,0,0,0);  // par, chan, ant, slot
     748           0 :         casacore::Int thisRow(0);
     749           0 :         for (casacore::Int islot = 0; islot < nTime_(iSpw); islot++) {
     750           0 :           in(3)=islot;
     751           0 :           if (thisSolOK(islot)) {
     752             :             
     753             :             // Fill slot-constant cols:
     754           0 :             casacore::Slice thisSlice(thisRow,nElem_);
     755           0 :             time(thisSlice)=thisMJDTimeStamp(islot);
     756           0 :             casacore::Double dt=(thisMJDStop(islot) - thisMJDStart(islot));
     757           0 :             if (dt<0.0) dt=1.0;
     758           0 :             interval(thisSlice)=dt;
     759           0 :             fieldId(thisSlice)=thisFieldId(islot);
     760           0 :             fieldName(thisSlice)=thisFieldName(islot);
     761           0 :             sourceName(thisSlice)=thisSourceName(islot);
     762           0 :             totalSolOk(thisSlice)=thisSolOK(islot);
     763           0 :             totalFit(thisSlice)=thisFit(islot);
     764           0 :             totalFitWt(thisSlice)=thisFitwt(islot);
     765             :             
     766             :             // Loop over the number of antennas
     767           0 :             for (casacore::Int iant = 0; iant < nElem_; iant++) {
     768           0 :               out(2)=thisRow;
     769           0 :               in(2)=iant;
     770             :               // Antenna index
     771           0 :               antenna1(thisRow)=iant;
     772             :               
     773           0 :               gain.xyPlane(thisRow)(casacore::IPosition(2,0,0),casacore::IPosition(2,nPar()-1,nChan_(iSpw)-1))=
     774           0 :                 thisAntGain(casacore::IPosition(4,0,0,iant,islot),
     775           0 :                             casacore::IPosition(4,nPar()-1,nChan_(iSpw)-1,iant,islot)).nonDegenerate(2);
     776             : 
     777             :               // Per-chan fit pars
     778           0 :               for (casacore::Int ichan=0; ichan<nChan_(iSpw); ichan++) {
     779             :                 // Gain stats  (slot constant, per spw?)
     780             :                 //solOk(0,ichan,thisRow) = thisISolutionOK(iant,islot);
     781           0 :                 fit(0,ichan,thisRow) = thisIFit(iant,islot);
     782           0 :                 fitWt(0,ichan,thisRow) = thisIFitwt(iant,islot);
     783             : 
     784             : 
     785           0 :                 for (casacore::Int ipar=0; ipar<nPar(); ++ipar) {
     786           0 :                   solOk(ipar,ichan,thisRow) = parOK(iSpw)(casacore::IPosition(4,ipar,ichan,iant,islot));
     787           0 :                   flag(ipar,ichan,thisRow) = !solOk(ipar,ichan,thisRow);
     788           0 :                   snr(ipar,ichan,thisRow) = parSNR(iSpw)(casacore::IPosition(4,ipar,ichan,iant,islot));
     789             :                 } // ipar
     790             :               } // ichan
     791             :               
     792             :               // next time round is next row
     793           0 :               thisRow++;
     794             :             }; // iant
     795             : 
     796             :             
     797             :           }; // thisSolOK(islot)
     798             :         }; // islot
     799             :         
     800             :         // Now push everything to the disk table
     801           0 :         calTab_->addRowMain(thisnRow);
     802             :         //      SolvableVisJonesMCol svjmcol(*tab);
     803           0 :         if (svjmcol_) {delete svjmcol_; svjmcol_=NULL;}
     804           0 :         svjmcol_ = new SolvableCalSetMCol<T>(*calTab_);
     805             : 
     806           0 :         casacore::RefRows refRows(nMain,nMain+thisnRow-1);
     807           0 :         svjmcol_->time().putColumnCells(refRows,time);
     808           0 :         svjmcol_->timeEP().putColumnCells(refRows,timeEP);
     809           0 :         svjmcol_->interval().putColumnCells(refRows,interval);
     810           0 :         svjmcol_->antenna1().putColumnCells(refRows,antenna1);
     811           0 :         svjmcol_->feed1().putColumnCells(refRows,feed1);
     812           0 :         svjmcol_->fieldId().putColumnCells(refRows,fieldId);
     813           0 :         svjmcol_->arrayId().putColumnCells(refRows,arrayId);
     814           0 :         svjmcol_->obsId().putColumnCells(refRows,obsId);
     815           0 :         svjmcol_->scanNo().putColumnCells(refRows,scanNum);
     816           0 :         svjmcol_->processorId().putColumnCells(refRows,procId);
     817           0 :         svjmcol_->stateId().putColumnCells(refRows,stateId);
     818           0 :         svjmcol_->phaseId().putColumnCells(refRows,phaseId);
     819           0 :         svjmcol_->pulsarBin().putColumnCells(refRows,pulsarBin);
     820           0 :         svjmcol_->pulsarGateId().putColumnCells(refRows,pulsarGateId);
     821           0 :         svjmcol_->freqGrp().putColumnCells(refRows,freqGroup);
     822           0 :         svjmcol_->fieldName().putColumnCells(refRows,fieldName);
     823           0 :         svjmcol_->sourceName().putColumnCells(refRows,sourceName);
     824           0 :         svjmcol_->gain().putColumnCells(refRows,gain);
     825           0 :         svjmcol_->totalSolnOk().putColumnCells(refRows,totalSolOk);
     826           0 :         svjmcol_->totalFit().putColumnCells(refRows,totalFit);
     827           0 :         svjmcol_->totalFitWgt().putColumnCells(refRows,totalFitWt);
     828           0 :         svjmcol_->solnOk().putColumnCells(refRows,solOk);
     829           0 :         svjmcol_->fit().putColumnCells(refRows,fit);
     830           0 :         svjmcol_->fitWgt().putColumnCells(refRows,fitWt);
     831           0 :         svjmcol_->calDescId().putColumnCells(refRows,calDescId);
     832           0 :         svjmcol_->calHistoryId().putColumnCells(refRows,calHistId);
     833           0 :         svjmcol_->flag().putColumnCells(refRows,flag);
     834           0 :         svjmcol_->snr().putColumnCells(refRows,snr);
     835             :         
     836           0 :         nMain = calTab_->nRowMain();
     837             :         
     838           0 :       } // thisnRow > 0
     839           0 :     } // par_[iSpw]!=NULL
     840             :   } // iSpw
     841             : 
     842           0 :   delete calTab_;
     843             : 
     844           0 : };
     845             : /*
     846             : template<class T> void CalSet<T>::store (const casacore::String& file, 
     847             :                                          const casacore::String& type,
     848             :                                          const casacore::String& msname,
     849             :                                          const casacore::Bool& append)
     850             : {
     851             :   // Write the solutions to an output calibration table
     852             :   // casacore::Input:
     853             :   //    file           casacore::String        Cal table name
     854             :   //    append         casacore::Bool          Append if true, else overwrite
     855             :   //
     856             : 
     857             :   // total rows to be written per Spw
     858             :   casacore::Vector<casacore::Int> nRow(nSpw_,0);
     859             :   for (casacore::Int iSpw=0;iSpw<nSpw_;iSpw++) 
     860             :     if (solutionOK_[iSpw])
     861             :       nRow(iSpw)=nElem_*ntrue(*(solutionOK_[iSpw]));
     862             : 
     863             :   // Escape if nothing to write
     864             :   if (sum(nRow)==0)
     865             :     throw(casacore::AipsError("No valid calibration solutions; no table written."));
     866             : 
     867             :   // Initialization:
     868             :   // No. of rows in cal_main, cal_desc and cal_history
     869             :   casacore::Int nMain = 0; 
     870             :   casacore::Int nDesc = 0;
     871             :   //casacore::Int nHist = 0;
     872             :   
     873             :   // Calibration table
     874             :   SolvableVisJonesTable *tab;
     875             :   
     876             :   // Open the output file if it already exists and is being appended to.
     877             :   if (append && casacore::Table::isWritable (file)) {
     878             :     tab  = new SolvableVisJonesTable (file, casacore::Table::Update);
     879             :     nMain = tab->nRowMain();
     880             :     nDesc = tab->nRowDesc();
     881             :     //nHist = tab->nRowHistory();
     882             :   } else {
     883             :     // Create a new calibration table
     884             :     casacore::Table::TableOption access = casacore::Table::New;
     885             :     tab = new SolvableVisJonesTable (file, type, access);
     886             :   };
     887             :   
     888             :   // Write every spw w/ max number of channels 
     889             :   //  (eventually, CalTable should permit variable-shape cols)
     890             :   casacore::Int maxNumChan(1);
     891             :   for (casacore::Int iSpw=0; iSpw<nSpw_; iSpw++) 
     892             :     if (par_[iSpw]!=NULL) 
     893             :       maxNumChan=max(maxNumChan,nChan_(iSpw));
     894             : 
     895             :   // Some default values
     896             :   casacore::Double dzero = 0;
     897             :   casacore::IPosition ip(2,1,maxNumChan);
     898             : 
     899             :   // CalDesc Sub-table records
     900             :   CalDescRecord* descRec;
     901             :   casacore::Vector<casacore::Int> calDescNum(nSpw_); calDescNum=-1;
     902             :   for (casacore::Int iSpw=0; iSpw<nSpw_; iSpw++) {
     903             : 
     904             :     // Write a CalDesc for each spw which has solutions
     905             :     // Note: CalDesc index != SpwId, in general
     906             : 
     907             :     if (nRow(iSpw)>0 && par_[iSpw]!=NULL) {
     908             : 
     909             :       // Access to existing CAL_DESC columns:
     910             :       CalDescColumns cd(*tab);
     911             : 
     912             :       // Check if this spw already in CAL_DESC 
     913             :       //      cout << "spwCol = " << cd.spwId().getColumn() << endl;
     914             : 
     915             :       casacore::Bool newCD(true);
     916             :       for (casacore::Int iCD=0;iCD<nDesc;iCD++) {
     917             : 
     918             :         casacore::IPosition iCDip(1,0);
     919             :         if ( iSpw==(cd.spwId()(iCD))(iCDip) ) {
     920             :           // Don't need new CAL_DESC entry
     921             :           newCD=false;
     922             :           calDescNum(iSpw)=iCD;
     923             :           break;
     924             :         }
     925             :       }
     926             : 
     927             :       if (newCD) {
     928             : 
     929             :         // Cal_desc fields
     930             :         casacore::Vector <casacore::Int> spwId(1,iSpw);
     931             :         casacore::Matrix <casacore::Double> chanFreq(ip, dzero); 
     932             :         casacore::Matrix <casacore::Double> chanWidth(ip, dzero);
     933             :         casacore::Array <casacore::String> polznType(ip, "");
     934             :         casacore::Cube <casacore::Int> chanRange(casacore::IPosition(3,2,1,maxNumChan), 0);
     935             :         casacore::Vector <casacore::Int> numChan(1,nChan_(iSpw));
     936             :         for (casacore::Int ichan=0; ichan<nChan_(iSpw); ichan++) {
     937             :           chanRange(0,0,ichan)=startChan_(iSpw);
     938             :           chanRange(1,0,ichan)=startChan_(iSpw) + nChan_(iSpw) -1;
     939             :         }
     940             :         
     941             :         // Fill the cal_desc record
     942             :         descRec = new CalDescRecord;
     943             :         descRec->defineNumSpw (1);
     944             :         descRec->defineNumChan (numChan);
     945             :         descRec->defineNumReceptors (2);
     946             :         descRec->defineNJones (2);
     947             :         descRec->defineSpwId (spwId);
     948             :         descRec->defineChanFreq (chanFreq);
     949             :         descRec->defineChanWidth (chanWidth);
     950             :         descRec->defineChanRange (chanRange);
     951             :         descRec->definePolznType (polznType);
     952             :         descRec->defineJonesType ("full");
     953             :         descRec->defineMSName (casacore::Path(msname).baseName());
     954             :         
     955             :         // Write the cal_desc record
     956             : 
     957             :         tab->putRowDesc (nDesc, *descRec);
     958             :         delete descRec;
     959             :         
     960             :         // This spw will have this calDesc index in main table
     961             :         calDescNum(iSpw) = nDesc;
     962             :         nDesc++;
     963             :       }
     964             : 
     965             :     }
     966             :     
     967             :   }
     968             : 
     969             : 
     970             :   // Now write MAIN table in column-wise fashion
     971             :   
     972             :   // Starting row in this slot
     973             : 
     974             :   for (casacore::Int iSpw=0; iSpw<nSpw_; iSpw++) {
     975             : 
     976             :     // Write table for spws which have solutions
     977             :     if (par_[iSpw]!=NULL) {
     978             : 
     979             :       // Create references to cal data for this spw
     980             :       casacore::Vector<casacore::Bool>    thisSolOK;        thisSolOK.reference(*(solutionOK_[iSpw]));
     981             :       casacore::Vector<casacore::Double>  thisMJDTimeStamp; thisMJDTimeStamp.reference(*(MJDTimeStamp_[iSpw]));
     982             :       casacore::Vector<casacore::Double>  thisMJDStart;     thisMJDStart.reference(*(MJDStart_[iSpw]));
     983             :       casacore::Vector<casacore::Double>  thisMJDStop;      thisMJDStop.reference(*(MJDStop_[iSpw]));
     984             :       casacore::Vector<casacore::Int>     thisFieldId;      thisFieldId.reference(*(fieldId_[iSpw]));
     985             :       casacore::Vector<casacore::String>  thisFieldName;    thisFieldName.reference(*(fieldName_[iSpw]));
     986             :       casacore::Vector<casacore::String>  thisSourceName;   thisSourceName.reference(*(sourceName_[iSpw]));
     987             :       casacore::Vector<casacore::Float>   thisFit;          thisFit.reference(*(fit_[iSpw]));
     988             :       casacore::Vector<casacore::Float>   thisFitwt;        thisFitwt.reference(*(fitwt_[iSpw]));
     989             :       casacore::Array<casacore::Complex>  thisAntGain;      thisAntGain.reference(*(par_[iSpw]));
     990             :       //      casacore::Matrix<casacore::Bool>    thisISolutionOK;  thisISolutionOK.reference(*(iSolutionOK_[iSpw]));
     991             :       casacore::Matrix<casacore::Float>   thisIFit;         thisIFit.reference(*(iFit_[iSpw]));
     992             :       casacore::Matrix<casacore::Float>   thisIFitwt;       thisIFitwt.reference(*(iFitwt_[iSpw]));
     993             : 
     994             :       casacore::Int thisnRow=nRow(iSpw);
     995             :       
     996             :       // Only if there are rows to add to table
     997             :       if (thisnRow > 0) {
     998             : 
     999             :         // These are constant columns (with boring values, currently)
    1000             :         casacore::Vector<casacore::Double> timeEP(thisnRow,0.0);
    1001             :         casacore::Vector<casacore::Int> feed1(thisnRow,0);
    1002             :         casacore::Vector<casacore::Int> arrayId(thisnRow,0);
    1003             :         casacore::Vector<casacore::Int> obsId(thisnRow,0);
    1004             :         casacore::Vector<casacore::Int> scanNum(thisnRow,0);
    1005             :         casacore::Vector<casacore::Int> procId(thisnRow,0);
    1006             :         casacore::Vector<casacore::Int> stateId(thisnRow,0);
    1007             :         casacore::Vector<casacore::Int> phaseId(thisnRow,0);
    1008             :         casacore::Vector<casacore::Int> pulsarBin(thisnRow,0);
    1009             :         casacore::Vector<casacore::Int> pulsarGateId(thisnRow,0);
    1010             :         casacore::Vector<casacore::Int> freqGroup(thisnRow,0);
    1011             :         casacore::Vector<casacore::Int> calHistId(thisnRow,0);
    1012             :         
    1013             :         // This is constant
    1014             :         casacore::Vector<casacore::Int> calDescId(thisnRow,calDescNum(iSpw));
    1015             :         
    1016             :         // These are constant per slot
    1017             :         //   (these cols should be incremental)
    1018             :         casacore::Vector<casacore::Double> time(thisnRow,0.0);
    1019             :         casacore::Vector<casacore::Double> interval(thisnRow,0.0);
    1020             :         casacore::Vector<casacore::Int>    fieldId(thisnRow,0);
    1021             :         casacore::Vector<casacore::String> fieldName(thisnRow,"");
    1022             :         casacore::Vector<casacore::String> sourceName(thisnRow,"");
    1023             :         casacore::Vector<casacore::Bool>   totalSolOk(thisnRow,false);
    1024             :         casacore::Vector<casacore::Float>  totalFit(thisnRow,0.0);
    1025             :         casacore::Vector<casacore::Float>  totalFitWt(thisnRow,0.0);
    1026             :         
    1027             :         // These vary
    1028             :         casacore::Vector<casacore::Int>    antenna1(thisnRow,0);
    1029             :         casacore::Cube<casacore::Complex>  gain(casacore::IPosition(3,nPar(),maxNumChan,thisnRow),casacore::Complex(0.0,0.0));
    1030             :         casacore::Cube<casacore::Bool>     solOk(nPar(),maxNumChan,thisnRow,false);
    1031             :         casacore::Cube<casacore::Float>    fit(1,maxNumChan,thisnRow,0.0);
    1032             :         casacore::Cube<casacore::Float>    fitWt(1,maxNumChan,thisnRow,0.0);
    1033             :         casacore::Cube<casacore::Bool>     flag(nPar(),maxNumChan,thisnRow,false);
    1034             :         casacore::Cube<casacore::Float>    snr(nPar(),maxNumChan,thisnRow,false);
    1035             : 
    1036             :         casacore::IPosition out(3,0,0,0);   // par, chan, row
    1037             :         casacore::IPosition in(4,0,0,0,0);  // par, chan, ant, slot
    1038             :         casacore::Int thisRow(0);
    1039             :         for (casacore::Int islot = 0; islot < nTime_(iSpw); islot++) {
    1040             :           in(3)=islot;
    1041             :           if (thisSolOK(islot)) {
    1042             :             
    1043             :             // Fill slot-constant cols:
    1044             :             casacore::Slice thisSlice(thisRow,nElem_);
    1045             :             time(thisSlice)=thisMJDTimeStamp(islot);
    1046             :             casacore::Double dt=(thisMJDStop(islot) - thisMJDStart(islot));
    1047             :             if (dt<0.0) dt=1.0;
    1048             :             interval(thisSlice)=dt;
    1049             :             fieldId(thisSlice)=thisFieldId(islot);
    1050             :             fieldName(thisSlice)=thisFieldName(islot);
    1051             :             sourceName(thisSlice)=thisSourceName(islot);
    1052             :             totalSolOk(thisSlice)=thisSolOK(islot);
    1053             :             totalFit(thisSlice)=thisFit(islot);
    1054             :             totalFitWt(thisSlice)=thisFitwt(islot);
    1055             :             
    1056             :             // Loop over the number of antennas
    1057             :             for (casacore::Int iant = 0; iant < nElem_; iant++) {
    1058             :               out(2)=thisRow;
    1059             :               in(2)=iant;
    1060             :               // Antenna index
    1061             :               antenna1(thisRow)=iant;
    1062             :               
    1063             : 
    1064             :               gain.xyPlane(thisRow)(casacore::IPosition(2,0,0),casacore::IPosition(2,nPar()-1,nChan_(iSpw)-1))=
    1065             :                 thisAntGain(casacore::IPosition(4,0,0,iant,islot),casacore::IPosition(4,nPar()-1,nChan_(iSpw)-1,iant,islot)).nonDegenerate(2);
    1066             : 
    1067             :               
    1068             :               // Per-chan fit pars
    1069             :               for (casacore::Int ichan=0; ichan<nChan_(iSpw); ichan++) {
    1070             :                 // Gain stats  (slot constant, per spw?)
    1071             :                 //solOk(0,ichan,thisRow) = thisISolutionOK(iant,islot);
    1072             :                 fit(0,ichan,thisRow) = thisIFit(iant,islot);
    1073             :                 fitWt(0,ichan,thisRow) = thisIFitwt(iant,islot);
    1074             : 
    1075             : 
    1076             :                 for (casacore::Int ipar=0; ipar<nPar(); ++ipar) {
    1077             :                   solOk(ipar,ichan,thisRow) = parOK(iSpw)(casacore::IPosition(4,ipar,ichan,iant,islot));
    1078             :                   flag(ipar,ichan,thisRow) = !solOk(ipar,ichan,thisRow);
    1079             :                   snr(ipar,ichan,thisRow) = parSNR(iSpw)(casacore::IPosition(4,ipar,ichan,iant,islot));
    1080             :                 }
    1081             :               }
    1082             :               
    1083             :               // next time round is next row
    1084             :               thisRow++;
    1085             :             };
    1086             :             
    1087             :           };
    1088             :         };
    1089             :         
    1090             :         // Now push everything to the disk table
    1091             :         tab->addRowMain(thisnRow);
    1092             :         SolvableVisJonesMCol svjmcol(*tab);
    1093             :         
    1094             :         casacore::RefRows refRows(nMain,nMain+thisnRow-1);
    1095             :         svjmcol.time().putColumnCells(refRows,time);
    1096             :         svjmcol.timeEP().putColumnCells(refRows,timeEP);
    1097             :         svjmcol.interval().putColumnCells(refRows,interval);
    1098             :         svjmcol.antenna1().putColumnCells(refRows,antenna1);
    1099             :         svjmcol.feed1().putColumnCells(refRows,feed1);
    1100             :         svjmcol.fieldId().putColumnCells(refRows,fieldId);
    1101             :         svjmcol.arrayId().putColumnCells(refRows,arrayId);
    1102             :         svjmcol.obsId().putColumnCells(refRows,obsId);
    1103             :         svjmcol.scanNo().putColumnCells(refRows,scanNum);
    1104             :         svjmcol.processorId().putColumnCells(refRows,procId);
    1105             :         svjmcol.stateId().putColumnCells(refRows,stateId);
    1106             :         svjmcol.phaseId().putColumnCells(refRows,phaseId);
    1107             :         svjmcol.pulsarBin().putColumnCells(refRows,pulsarBin);
    1108             :         svjmcol.pulsarGateId().putColumnCells(refRows,pulsarGateId);
    1109             :         svjmcol.freqGrp().putColumnCells(refRows,freqGroup);
    1110             :         svjmcol.fieldName().putColumnCells(refRows,fieldName);
    1111             :         svjmcol.sourceName().putColumnCells(refRows,sourceName);
    1112             :         svjmcol.gain().putColumnCells(refRows,gain);
    1113             :         svjmcol.totalSolnOk().putColumnCells(refRows,totalSolOk);
    1114             :         svjmcol.totalFit().putColumnCells(refRows,totalFit);
    1115             :         svjmcol.totalFitWgt().putColumnCells(refRows,totalFitWt);
    1116             :         svjmcol.solnOk().putColumnCells(refRows,solOk);
    1117             :         svjmcol.fit().putColumnCells(refRows,fit);
    1118             :         svjmcol.fitWgt().putColumnCells(refRows,fitWt);
    1119             :         svjmcol.calDescId().putColumnCells(refRows,calDescId);
    1120             :         svjmcol.calHistoryId().putColumnCells(refRows,calHistId);
    1121             :         svjmcol.flag().putColumnCells(refRows,flag);
    1122             :         svjmcol.snr().putColumnCells(refRows,snr);
    1123             :         
    1124             :         
    1125             :         nMain = tab->nRowMain();
    1126             :         
    1127             :       }
    1128             :     }
    1129             :   }
    1130             : 
    1131             :   delete tab;
    1132             : 
    1133             : };
    1134             : */
    1135             : } //# NAMESPACE CASA - END
    1136             : 

Generated by: LCOV version 1.16