LCOV - code coverage report
Current view: top level - msvis/MSVis - VisibilityIteratorImpl.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 659 1758 37.5 %
Date: 2024-10-28 15:53:10 Functions: 68 173 39.3 %

          Line data    Source code
       1             : //# VisibilityIterator.cc: Step through MeasurementEquation by visibility
       2             : //# Copyright (C) 1996-2012
       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             : //# $Id: VisibilityIterator.cc,v 19.15 2006/02/01 01:25:14 kgolap Exp $
      27             : 
      28             : #include <stdcasa/UtilJ.h>
      29             : #include <msvis/MSVis/VisibilityIteratorImpl.h>
      30             : #include <msvis/MSVis/VisibilityIterator.h>
      31             : #include <msvis/MSVis/VisBuffer.h>
      32             : #include <msvis/MSVis/MSUtil.h>
      33             : ////#include <synthesis/TransformMachines/VisModelData.h>
      34             : #include <casacore/scimath/Mathematics/InterpolateArray1D.h>
      35             : #include <casacore/ms/MeasurementSets/MSColumns.h>
      36             : #include <casacore/ms/MSSel/MSSpwIndex.h>
      37             : #include <casacore/tables/Tables/TableDesc.h>
      38             : #include <casacore/tables/Tables/ColDescSet.h>
      39             : #include <casacore/tables/Tables/TableRecord.h>
      40             : #include <casacore/tables/DataMan/TiledStManAccessor.h>
      41             : #include <casacore/tables/DataMan/StandardStManAccessor.h>
      42             : #include <casacore/tables/DataMan/IncrStManAccessor.h>
      43             : #include <casacore/casa/Arrays/ArrayLogical.h>
      44             : #include <casacore/casa/System/AipsrcValue.h>
      45             : #include <casacore/casa/BasicSL/Constants.h>
      46             : #include <casacore/casa/Quanta/MVTime.h>
      47             : #include <casacore/casa/Containers/Record.h>
      48             : #include <casacore/casa/Arrays/ArrayMath.h>
      49             : #include <casacore/casa/Arrays/MaskedArray.h>
      50             : #include <casacore/casa/Exceptions/Error.h>
      51             : #include <casacore/casa/Utilities/Assert.h>
      52             : #include <casacore/casa/Utilities/Sort.h>
      53             : #include <casacore/casa/OS/EnvVar.h>
      54             : 
      55             : #include <cassert>
      56             : #include <limits>
      57             : #include <memory>
      58             : 
      59             : using std::make_pair;
      60             : 
      61             : using namespace casacore;
      62             : namespace casa { //# NAMESPACE CASA - BEGIN
      63             : 
      64             : SubChunkPair
      65           0 : SubChunkPair::noMoreData ()
      66             : {
      67           0 :     Int maxInt = std::numeric_limits<Int>::max ();
      68           0 :     return SubChunkPair (maxInt, maxInt);
      69             : }
      70             : 
      71             : String
      72           0 : SubChunkPair::toString () const
      73             : {
      74           0 :     return String::format ("(%d,%d)", first, second);
      75             : }
      76             : 
      77           0 : VisibilityIteratorReadImpl::VisibilityIteratorReadImpl ()
      78           0 : : rovi_p (NULL),
      79           0 :   selRows_p (0, 0),
      80           0 :   tileCacheIsSet_p (0)
      81           0 : {}
      82             : 
      83           2 : VisibilityIteratorReadImpl::VisibilityIteratorReadImpl (ROVisibilityIterator * rovi,
      84             :                                                         const Block<MeasurementSet> &mss,
      85             :                                                         const Block<Int> & sortColumns,
      86             :                                                         const Bool addDefaultSort,
      87           2 :                                                         Double timeInterval)
      88           2 : : addDefaultSort_p (addDefaultSort),
      89           2 :   curChanGroup_p (0),
      90           2 :   floatDataFound_p (false),
      91           2 :   initialized_p (false),
      92           2 :   msIterAtOrigin_p (false),
      93           2 :   msIter_p (mss, sortColumns, timeInterval, addDefaultSort, false),
      94           2 :   nChan_p (0),
      95           2 :   nRowBlocking_p (0),
      96           2 :   rovi_p (NULL),
      97           2 :   selRows_p (0, 0),
      98           2 :   sortColumns_p (sortColumns),
      99           2 :   stateOk_p (false),
     100           2 :   tileCacheIsSet_p (0),
     101          10 :   timeInterval_p (timeInterval)
     102             : {
     103             :     // Make sure the pointer to the containing ROVI (rovi_p) is NULL when calling initialize
     104             :     // otherwise the call back to the VI can result in it trying to use an uninitialized pointer
     105             :     // to this object (since it is in the process or being constructed).
     106             : 
     107           2 :     initialize (mss);
     108             : 
     109           2 :     rovi_p = rovi;
     110             : 
     111           2 : }
     112             : 
     113             : void
     114           2 : VisibilityIteratorReadImpl::initialize (const Block<MeasurementSet> &mss)
     115             : {
     116             : 
     117           2 :     AipsrcValue<Bool>::find (autoTileCacheSizing_p, VisibilityIterator::getAipsRcBase () + ".AutoTileCacheSizing", false);
     118             : 
     119           2 :     asyncEnabled_p = false;
     120           2 :     cache_p.lastazelUT_p = -1;
     121           2 :     cache_p.lastazel0UT_p = -1;
     122           2 :     cache_p.lasthourangUT_p = -1;
     123           2 :     cache_p.lastfeedpaUT_p = -1;
     124           2 :     cache_p.lastParangUT_p = -1;
     125           2 :     cache_p.lastParang0UT_p = -1;
     126             : 
     127           2 :     msCounter_p = 0;
     128             : 
     129           2 :     Int numMS = mss.nelements ();
     130           2 :     isMultiMS_p = numMS > 1;
     131             : 
     132           2 :     Block<Vector<Int> > blockNGroup (numMS);
     133           2 :     Block<Vector<Int> > blockStart (numMS);
     134           2 :     Block<Vector<Int> > blockWidth (numMS);
     135           2 :     Block<Vector<Int> > blockIncr (numMS);
     136           2 :     Block<Vector<Int> > blockSpw (numMS);
     137             : 
     138           2 :     measurementSets_p.clear ();
     139             : 
     140           4 :     for (Int k = 0; k < numMS; ++k) {
     141             : 
     142           2 :         MSSpWindowColumns msSpW (mss[k].spectralWindow ());
     143             : 
     144           2 :         Int nspw = msSpW.nrow ();
     145             : 
     146           2 :         blockNGroup[k].resize (nspw);
     147           2 :         blockNGroup[k].set (1);
     148           2 :         blockStart[k].resize (nspw);
     149           2 :         blockStart[k].set (0);
     150           2 :         blockWidth[k].resize (nspw);
     151           2 :         blockWidth[k] = msSpW.numChan ().getColumn ();
     152           2 :         blockIncr[k].resize (nspw);
     153           2 :         blockIncr[k].set (1);
     154           2 :         blockSpw[k].resize (nspw);
     155           2 :         indgen (blockSpw[k]);
     156             : 
     157           2 :         measurementSets_p.push_back (mss [k]);
     158           2 :     }
     159             : 
     160           2 :     selectChannel (blockNGroup, blockStart, blockWidth, blockIncr,
     161             :                   blockSpw);
     162           2 : }
     163             : 
     164             : 
     165           0 : VisibilityIteratorReadImpl::VisibilityIteratorReadImpl (const VisibilityIteratorReadImpl & other,
     166           0 :                                                         ROVisibilityIterator * rovi)
     167           0 : : rovi_p (rovi),
     168           0 :   selRows_p (other.selRows_p) // no default constructor so init it here
     169             : {
     170           0 :     operator=(other);
     171           0 : }
     172             : 
     173           2 : VisibilityIteratorReadImpl::~VisibilityIteratorReadImpl ()
     174             : {
     175           2 : }
     176             : 
     177             : VisibilityIteratorReadImpl &
     178           0 : VisibilityIteratorReadImpl::operator=(const VisibilityIteratorReadImpl & other)
     179             : {
     180           0 :     if (this == &other) {
     181           0 :         return *this;
     182             :     }
     183             : 
     184           0 :     cache_p = other.cache_p;
     185           0 :     channels_p = other.channels_p;
     186           0 :     columns_p = other.columns_p;
     187           0 :     msChannels_p = other.msChannels_p;
     188           0 :     velocity_p = other.velocity_p;
     189             : 
     190           0 :     addDefaultSort_p = other.addDefaultSort_p;
     191           0 :     channelGroupSize_p = other.channelGroupSize_p;
     192           0 :     curChanGroup_p = other.curChanGroup_p;
     193           0 :     curEndRow_p = other.curEndRow_p;
     194           0 :     curChanGroup_p = other.curChanGroup_p;
     195           0 :     curNumRow_p = other.curNumRow_p;
     196           0 :     curStartRow_p = other.curStartRow_p;
     197           0 :     curTableNumRow_p = other.curTableNumRow_p;
     198           0 :     floatDataFound_p = other.floatDataFound_p;
     199           0 :     imwgt_p = other.imwgt_p;
     200           0 :     initialized_p = other.initialized_p;
     201           0 :     isMultiMS_p = other.isMultiMS_p;
     202           0 :     measurementSets_p = other.measurementSets_p;
     203           0 :     more_p = other.more_p;
     204           0 :     msCounter_p = other.msCounter_p;
     205           0 :     msIterAtOrigin_p = other.msIterAtOrigin_p;
     206           0 :     msIter_p = other.msIter_p;
     207           0 :     msIter_p.origin();
     208           0 :     msd_p = other.msd_p;
     209           0 :     nAnt_p = other.nAnt_p;
     210           0 :     nChan_p = other.nChan_p;
     211           0 :     nPol_p = other.nPol_p;
     212           0 :     nRowBlocking_p = other.nRowBlocking_p;
     213           0 :     newChanGroup_p = other.newChanGroup_p;
     214           0 :     selRows_p = other.selRows_p;
     215           0 :     slicer_p = other.slicer_p;
     216           0 :     sortColumns_p = other.sortColumns_p;
     217           0 :     stateOk_p = other.stateOk_p;
     218           0 :     tileCacheIsSet_p.resize ();
     219           0 :     timeInterval_p = other.timeInterval_p;
     220           0 :     time_p.assign (other.time_p);
     221           0 :     useSlicer_p = other.useSlicer_p;
     222           0 :     weightSlicer_p = other.weightSlicer_p;
     223             : 
     224           0 :     return *this;
     225             : }
     226             : 
     227             : VisibilityIteratorReadImpl::Velocity &
     228           0 : VisibilityIteratorReadImpl::Velocity::operator= (const VisibilityIteratorReadImpl::Velocity & other)
     229             : {
     230           0 :     cFromBETA_p = other.cFromBETA_p;
     231           0 :     lsrFreq_p.assign (other.lsrFreq_p);
     232           0 :     nVelChan_p = other.nVelChan_p;
     233           0 :     selFreq_p = other.selFreq_p;
     234           0 :     vDef_p = other.vDef_p;
     235           0 :     vInc_p = other.vInc_p;
     236           0 :     vInterpolation_p = other.vInterpolation_p;
     237           0 :     vPrecise_p = other.vPrecise_p;
     238           0 :     vStart_p = other.vStart_p;
     239           0 :     velSelection_p = other.velSelection_p;
     240             : 
     241           0 :     return * this;
     242             : }
     243             : 
     244           2 : VisibilityIteratorReadImpl::Cache::Cache()
     245           2 : : flagOK_p (false),
     246           2 :   floatDataCubeOK_p (false),
     247           2 :   freqCacheOK_p (false),
     248           2 :   hourang_p (0),
     249           2 :   lastParang0UT_p (-1), // set last cache update as invalid
     250           2 :   lastParangUT_p (-1), // set last cache update as invalid
     251           2 :   lastazelUT_p (-1), // set last cache update as invalid
     252           2 :   lastazel0UT_p (-1), // set last cache update as invalid
     253           2 :   lasthourangUT_p (-1), // set last cache update as invalid
     254           2 :   lastfeedpaUT_p (-1), // set last cache update as invalid
     255           2 :   msHasFC_p(false),
     256           2 :   msHasWtSp_p (false),
     257           2 :   parang0_p (0),
     258           2 :   weightSpOK_p (false)
     259           2 : {}
     260             : 
     261             : VisibilityIteratorReadImpl::Cache &
     262           0 : VisibilityIteratorReadImpl::Cache::operator= (const VisibilityIteratorReadImpl::Cache & other)
     263             : {
     264           0 :     azel0_p = other.azel0_p;
     265           0 :     azel_p.assign (other.azel_p);
     266           0 :     feedpa_p.assign (other.feedpa_p);
     267           0 :     flagCube_p.assign (other.flagCube_p);
     268           0 :     flagOK_p = other.flagOK_p;
     269           0 :     floatDataCubeOK_p = other.floatDataCubeOK_p;
     270           0 :     floatDataCube_p.assign (other.floatDataCube_p);
     271           0 :     freqCacheOK_p = other.freqCacheOK_p;
     272           0 :     frequency_p.assign (frequency_p);
     273           0 :     hourang_p = other.hourang_p;
     274           0 :     lastazelUT_p = other.lastazelUT_p;
     275           0 :     lastazel0UT_p = other.lastazel0UT_p;
     276           0 :     lasthourangUT_p = other.lasthourangUT_p;
     277           0 :     lastfeedpaUT_p = other.lastfeedpaUT_p;
     278           0 :     lastParangUT_p = other.lastParangUT_p;
     279           0 :     lastParang0UT_p = other.lastParang0UT_p;
     280           0 :     msHasFC_p = other.msHasFC_p;
     281           0 :     msHasWtSp_p = other.msHasWtSp_p;
     282           0 :     parang0_p = other.parang0_p;
     283           0 :     parang_p.assign (other.parang_p);
     284           0 :     rowIds_p = other.rowIds_p;
     285           0 :     uvwMat_p.assign (other.uvwMat_p);
     286           0 :     visCube_p.assign (other.visCube_p);
     287           0 :     visOK_p = other.visOK_p;
     288           0 :     weightSpOK_p = other.weightSpOK_p;
     289           0 :     wtSp_p.assign (other.wtSp_p);
     290             : 
     291           0 :     return * this;
     292             : }
     293             : 
     294             : VisibilityIteratorReadImpl::Columns &
     295           0 : VisibilityIteratorReadImpl::Columns::operator= (const VisibilityIteratorReadImpl::Columns & other)
     296             : {
     297           0 :     antenna1_p.reference (other.antenna1_p);
     298           0 :     antenna2_p.reference (other.antenna2_p);
     299           0 :     corrVis_p.reference (other.corrVis_p);
     300           0 :     exposure_p.reference (other.exposure_p);
     301           0 :     feed1_p.reference (other.feed1_p);
     302           0 :     feed2_p.reference (other.feed2_p);
     303           0 :     flag_p.reference (other.flag_p);
     304           0 :     flagCategory_p.reference (other.flagCategory_p);
     305           0 :     flagRow_p.reference (other.flagRow_p);
     306           0 :     floatVis_p.reference (other.floatVis_p);
     307           0 :     modelVis_p.reference (other.modelVis_p);
     308           0 :     observation_p.reference (other.observation_p);
     309           0 :     processor_p.reference (other.processor_p);
     310           0 :     scan_p.reference (other.scan_p);
     311           0 :     sigma_p.reference (other.sigma_p);
     312           0 :     state_p.reference (other.state_p);
     313           0 :     time_p.reference (other.time_p);
     314           0 :     timeCentroid_p.reference (other.timeCentroid_p);
     315           0 :     timeInterval_p.reference (other.timeInterval_p);
     316           0 :     uvw_p.reference (other.uvw_p);
     317           0 :     vis_p.reference (other.vis_p);
     318           0 :     weight_p.reference (other.weight_p);
     319           0 :     weightSpectrum_p.reference (other.weightSpectrum_p);
     320             : 
     321           0 :     return * this;
     322             : }
     323             : 
     324           2 : VisibilityIteratorReadImpl::Velocity::Velocity ()
     325           2 : : nVelChan_p (0),
     326           2 :   velSelection_p (false),
     327           2 :   vPrecise_p (false)
     328           2 : {}
     329             : 
     330             : 
     331             : VisibilityIteratorReadImpl *
     332           0 : VisibilityIteratorReadImpl::clone (ROVisibilityIterator * rovi) const
     333             : {
     334           0 :     return new VisibilityIteratorReadImpl (* this, rovi);
     335             : }
     336             : 
     337             : void
     338           0 : VisibilityIteratorReadImpl::setAsyncEnabled (Bool enabled)
     339             : {
     340           0 :     asyncEnabled_p = enabled;
     341           0 : }
     342             : 
     343             : Bool
     344           0 : VisibilityIteratorReadImpl::isAsyncEnabled () const
     345             : {
     346           0 :     return asyncEnabled_p;
     347             : }
     348             : 
     349             : 
     350             : void
     351           2 : VisibilityIteratorReadImpl::setRowBlocking (Int nRow)
     352             : {
     353           2 :     nRowBlocking_p = nRow;
     354           2 : }
     355             : 
     356             : Bool
     357           0 : VisibilityIteratorReadImpl::existsColumn (VisBufferComponents::EnumType id) const
     358             : {
     359             :     Bool result;
     360           0 :     switch (id){
     361             : 
     362           0 :     case VisBufferComponents::Corrected:
     363             :     case VisBufferComponents::CorrectedCube:
     364             : 
     365           0 :         result = ! columns_p.corrVis_p.isNull();
     366           0 :         break;
     367             : 
     368           0 :     case VisBufferComponents::Model:
     369             :     case VisBufferComponents::ModelCube:
     370             : 
     371           0 :         result = ! columns_p.modelVis_p.isNull();
     372           0 :         break;
     373             : 
     374           0 :     case VisBufferComponents::Observed:
     375             :     case VisBufferComponents::ObservedCube:
     376             : 
     377           0 :         result = ! (columns_p.vis_p.isNull() && columns_p.floatVis_p.isNull());
     378           0 :         break;
     379             : 
     380             :     // RR: I can't tell if the other columns should checked for here or not.
     381             :     //     It's not true that all the other columns are required.
     382             :     //     existsFlagCategory uses caching anyway.
     383             :     // case VisBufferComponents::FlagCategory:
     384             :     //   result = false;
     385             :     //   if(!columns_p.flagCategory().isNull() &&
     386             :     //      columns_p.flagCategory().isDefined(0)){
     387             :     //     IPosition fcshape(columns_p.flagCategory().shape(0));
     388             :     //     IPosition fshape(columns_p.flag().shape(0));
     389             : 
     390             :     //     result = fcshape(0) == fshape(0) && fcshape(1) == fshape(1);
     391             :     //   }
     392             : 
     393           0 :     default:
     394           0 :         result = true; // required columns
     395             :     }
     396             : 
     397           0 :     return result;
     398             : }
     399             : 
     400             : 
     401             : void
     402           1 : VisibilityIteratorReadImpl::useImagingWeight (const VisImagingWeight & imWgt)
     403             : {
     404           1 :     imwgt_p = imWgt;
     405           1 : }
     406             : void
     407          22 : VisibilityIteratorReadImpl::origin ()
     408             : {
     409             : 
     410          22 :     if (!initialized_p) {
     411           0 :         originChunks ();
     412             :     } else {
     413          22 :         curChanGroup_p = 0;
     414          22 :         newChanGroup_p = true;
     415          22 :         curStartRow_p = 0;
     416          22 :         cache_p.freqCacheOK_p = false;
     417          22 :         cache_p.flagOK_p = false;
     418          22 :         cache_p.weightSpOK_p = false;
     419          22 :         cache_p.visOK_p.resize (3);
     420          22 :         cache_p.visOK_p = false;
     421          22 :         cache_p.floatDataCubeOK_p = false;
     422          22 :         setSelTable ();
     423          22 :         attachColumnsSafe (attachTable ());
     424          22 :         getTopoFreqs ();
     425          22 :         updateSlicer ();
     426          22 :         more_p = curChanGroup_p < curNGroups_p;
     427             :         // invalidate any attached VisBuffer
     428          22 :         if (!vbStack_p.empty ()) {
     429          11 :             vbStack_p.top ()->invalidate ();
     430             :         }
     431             : 
     432          22 :         subchunk_p.resetSubChunk ();
     433             :     }
     434          22 : }
     435             : 
     436             : void
     437           8 : VisibilityIteratorReadImpl::originChunks ()
     438             : {
     439           8 :     originChunks (false);
     440           8 : }
     441             : 
     442             : 
     443             : void
     444           8 : VisibilityIteratorReadImpl::originChunks (Bool forceRewind)
     445             : {
     446           8 :     initialized_p = true;
     447           8 :     subchunk_p.resetToOrigin();
     448             : 
     449           8 :     if (forceRewind) {
     450           0 :         msIterAtOrigin_p = false;
     451             :     }
     452             : 
     453           8 :     if (!msIterAtOrigin_p) {
     454             : 
     455           1 :         msIter_p.origin ();
     456           1 :         msIterAtOrigin_p = true;
     457             : 
     458           1 :         while ((! isInSelectedSPW (msIter_p.spectralWindowId ())) &&
     459           0 :                 msIter_p.more ()) {
     460             : 
     461           0 :             msIter_p++;
     462             :         }
     463             : 
     464           1 :         stateOk_p = false;
     465           1 :         msCounter_p = msId ();
     466             : 
     467             :     }
     468             : 
     469           8 :     setState ();
     470           8 :     origin ();
     471           8 :     setTileCache ();
     472           8 : }
     473             : 
     474             : Bool
     475          16 : VisibilityIteratorReadImpl::isInSelectedSPW (const Int & spw)
     476             : {
     477             : 
     478          16 :     for (uInt k = 0; k < msChannels_p.spw_p[msId ()].nelements () ; ++k) {
     479          16 :         if (spw == msChannels_p.spw_p[msId ()][k]) {
     480          16 :             return true;
     481             :         }
     482             :     }
     483           0 :     return false;
     484             : }
     485             : 
     486             : void
     487         266 : VisibilityIteratorReadImpl::advance ()
     488             : {
     489         266 :     newChanGroup_p = false;
     490         266 :     cache_p.flagOK_p = false;
     491         266 :     cache_p.visOK_p = false;
     492         266 :     cache_p.floatDataCubeOK_p = false;
     493         266 :     cache_p.weightSpOK_p = false;
     494         266 :     curStartRow_p = curEndRow_p + 1;
     495         266 :     if (curStartRow_p >= curTableNumRow_p) {
     496          13 :         if (++ curChanGroup_p >= curNGroups_p) {
     497          13 :             curChanGroup_p--;
     498          13 :             more_p = false;
     499             :         } else {
     500           0 :             curStartRow_p = 0;
     501           0 :             newChanGroup_p = true;
     502           0 :             cache_p.freqCacheOK_p = false;
     503           0 :             updateSlicer ();
     504             :         }
     505             :     }
     506         266 :     if (more_p) {
     507         253 :         subchunk_p.incrementSubChunk();
     508         253 :         setSelTable ();
     509         253 :         getTopoFreqs ();
     510             :         // invalidate any attached VisBuffer
     511         253 :         if (!vbStack_p.empty ()) {
     512         253 :             vbStack_p.top ()->invalidate ();
     513             :         }
     514             :     }
     515         266 : }
     516             : 
     517             : SubChunkPair
     518           0 : VisibilityIteratorReadImpl::getSubchunkId () const
     519             : {
     520           0 :     return subchunk_p;
     521             : }
     522             : 
     523           0 : const Block<Int>& VisibilityIteratorReadImpl::getSortColumns() const
     524             : {
     525           0 :   return sortColumns_p;
     526             : }
     527             : 
     528             : VisibilityIteratorReadImpl &
     529          13 : VisibilityIteratorReadImpl::nextChunk ()
     530             : {
     531             : 
     532          13 :     if (msIter_p.more ()) {
     533          13 :         msIter_p++;
     534          13 :         if ((!isInSelectedSPW (msIter_p.spectralWindowId ()))) {
     535           0 :             while ( (!isInSelectedSPW (msIter_p.spectralWindowId ()))
     536           0 :                     && (msIter_p.more ())) {
     537           0 :                 msIter_p++;
     538             :             }
     539           0 :             stateOk_p = false;
     540             :         }
     541             : 
     542          13 :         if (msIter_p.newMS ()) {
     543           0 :             msCounter_p = msId ();
     544           0 :             doChannelSelection ();
     545             :         }
     546          13 :         msIterAtOrigin_p = false;
     547          13 :         stateOk_p = false;
     548             :     }
     549          13 :     if (msIter_p.more ()) {
     550          10 :         subchunk_p.incrementChunk();
     551          10 :         setState ();
     552          10 :         getTopoFreqs ();
     553          10 :         if (!vbStack_p.empty ()) {
     554           5 :             vbStack_p.top ()->invalidate ();
     555             :         }
     556             :     }
     557          13 :     more_p = msIter_p.more ();
     558          13 :     return *this;
     559             : }
     560             : 
     561             : void
     562         288 : VisibilityIteratorReadImpl::setSelTable ()
     563             : {
     564             :     // work out how many rows to return
     565             :     // for the moment we return all rows with the same value for time
     566             :     // unless row blocking is set, in which case we return more rows at once.
     567         288 :     if (nRowBlocking_p > 0) {
     568          14 :         curEndRow_p = curStartRow_p + nRowBlocking_p;
     569          14 :         if (curEndRow_p >= curTableNumRow_p) {
     570          14 :             curEndRow_p = curTableNumRow_p - 1;
     571             :         }
     572             :     } else {
     573      195797 :         for (curEndRow_p = curStartRow_p + 1; curEndRow_p < curTableNumRow_p &&
     574       97895 :                 time_p (curEndRow_p) == time_p (curEndRow_p - 1);
     575       97628 :                 curEndRow_p++) {
     576             :             ;
     577             :         }
     578         274 :         curEndRow_p--;
     579             :     }
     580             : 
     581         288 :     curNumRow_p = curEndRow_p - curStartRow_p + 1;
     582         288 :     selRows_p = RefRows (curStartRow_p, curEndRow_p);
     583         288 :     cache_p.rowIds_p.resize (0);
     584         288 : }
     585             : 
     586             : void
     587         285 : VisibilityIteratorReadImpl::getTopoFreqs ()
     588             : {
     589         285 :     if (velocity_p.velSelection_p) {
     590             : 
     591             :         // Convert selected velocities to TOPO frequencies.
     592             :         // First convert observatory vel to correct frame (for this time).
     593             : 
     594           0 :         msd_p.setEpoch (msIter_p.msColumns ().timeMeas ()(curStartRow_p));
     595           0 :         if (msIter_p.newMS ()) {
     596           0 :             msd_p.setObservatoryPosition (msIter_p.telescopePosition ());
     597             :         }
     598             : 
     599           0 :         MRadialVelocity obsRV = msd_p.obsVel (); // get obs velocity in required frame
     600             : 
     601           0 :         Double obsVel = velocity_p.cFromBETA_p (obsRV.toDoppler ()).getValue ().get ().getValue ();
     602             :         // convert to doppler in required definition and get out in m/s
     603             : 
     604             :         // Now compute corresponding TOPO freqs
     605             : 
     606           0 :         velocity_p.selFreq_p.resize (velocity_p.nVelChan_p);
     607           0 :         velocity_p.lsrFreq_p.resize (velocity_p.nVelChan_p);
     608           0 :         Double v0 = velocity_p.vStart_p.getValue ();
     609           0 :         Double dv = velocity_p.vInc_p.getValue ();
     610             : 
     611           0 :         if (aips_debug) {
     612           0 :             cout << "obsVel=" << obsVel << endl;
     613             :         }
     614             : 
     615           0 :         for (Int i = 0; i < velocity_p.nVelChan_p; i++) {
     616             : 
     617           0 :             Double vTopo = v0 + i * dv - obsVel;
     618           0 :             MDoppler dTopo (Quantity (vTopo, "m/s"), velocity_p.vDef_p);
     619           0 :             velocity_p.selFreq_p (i) = MFrequency::fromDoppler
     620           0 :                            (dTopo, msIter_p.restFrequency ().getValue ()).getValue ().getValue ();
     621             : 
     622             :             // also calculate the frequencies in the requested frame for matching
     623             :             // up with the image planes
     624             :             // (they are called lsr here, but don't need to be in that frame)
     625             : 
     626           0 :             MDoppler dLSR (Quantity (v0 + i * dv, "m/s"), velocity_p.vDef_p);
     627           0 :             const MFrequency & restFrequency = msIter_p.restFrequency ();
     628           0 :             velocity_p.lsrFreq_p (i) = MFrequency::fromDoppler (dLSR, restFrequency.getValue ()).getValue ().getValue ();
     629           0 :         }
     630           0 :     }
     631         285 : }
     632             : 
     633             : void
     634           0 : VisibilityIteratorReadImpl::getTopoFreqs (Vector<Double> & lsrFreq, Vector<Double> & selFreq)
     635             : {
     636           0 :     getTopoFreqs ();
     637           0 :     lsrFreq.assign (velocity_p.lsrFreq_p);
     638           0 :     selFreq.assign (velocity_p.selFreq_p);
     639           0 : }
     640             : 
     641             : 
     642             : 
     643             : void
     644          18 : VisibilityIteratorReadImpl::setState ()
     645             : {
     646          18 :     if (stateOk_p) {
     647           5 :         return;
     648             :     }
     649             : 
     650          13 :     curTableNumRow_p = msIter_p.table ().nrow ();
     651             :     // get the times for this (major) iteration, so we can do (minor)
     652             :     // iteration by constant time (needed for VisBuffer averaging).
     653          13 :     ScalarColumn<Double> lcolTime (msIter_p.table (), MS::columnName (MS::TIME));
     654          13 :     time_p.resize (curTableNumRow_p);
     655          13 :     lcolTime.getColumn (time_p);
     656           0 :     ScalarColumn<Double> lcolTimeInterval (msIter_p.table (),
     657          13 :                                             MS::columnName (MS::INTERVAL));
     658             :     ///////////timeInterval_p.resize (curTableNumRow_p);
     659             :     ///////////lcolTimeInterval.getColumn (timeInterval_p);
     660          13 :     curStartRow_p = 0;
     661          13 :     setSelTable ();
     662          13 :     attachColumnsSafe (attachTable ());
     663             :     // If this is a new MeasurementSet then set up the antenna locations
     664          13 :     if (msIter_p.newMS ()) {
     665           3 :         nAnt_p = msd_p.setAntennas (msIter_p.msColumns ().antenna ());
     666           3 :         cache_p.feedpa_p.resize (nAnt_p);
     667           3 :         cache_p.feedpa_p.set (0);
     668           3 :         cache_p.lastfeedpaUT_p = -1;
     669           3 :         cache_p.parang_p.resize (nAnt_p);
     670           3 :         cache_p.parang_p.set (0);
     671           3 :         cache_p.lastParangUT_p = -1;
     672           3 :         cache_p.parang0_p = 0;
     673           3 :         cache_p.lastParang0UT_p = -1;
     674           3 :         cache_p.azel_p.resize (nAnt_p);
     675           3 :         cache_p.lastazelUT_p = -1;
     676           3 :         cache_p.lastazel0UT_p = -1;
     677           3 :         cache_p.lasthourangUT_p = -1;
     678             : 
     679             :     }
     680          13 :     if (msIter_p.newField () || msIterAtOrigin_p) {
     681          13 :         msd_p.setFieldCenter (msIter_p.phaseCenter ());
     682             :     }
     683          13 :     if ( msIter_p.newDataDescriptionId () || msIterAtOrigin_p) {
     684           3 :         Int spw = msIter_p.spectralWindowId ();
     685           3 :         nChan_p = msColumns ().spectralWindow ().numChan ()(spw);
     686           3 :         nPol_p = msColumns ().polarization ().numCorr ()(msIter_p.polarizationId ());
     687             : 
     688           6 :         if (Int (channels_p.nGroups_p.nelements ()) <= spw ||
     689           3 :                 channels_p.nGroups_p[spw] == 0) {
     690             :             // no selection set yet, set default = all
     691             :             // for a reference MS this will normally be set appropriately in VisSet
     692           0 :             selectChannel (1, 0, nChan_p);
     693             :         }
     694           3 :         channelGroupSize_p = channels_p.width_p[spw];
     695           3 :         curNGroups_p = channels_p.nGroups_p[spw];
     696           3 :         cache_p.freqCacheOK_p = false;
     697             :     }
     698             : 
     699          13 :     stateOk_p = true;
     700          13 : }
     701             : 
     702             : const MSDerivedValues &
     703           0 : VisibilityIteratorReadImpl::getMSD () const
     704             : {
     705           0 :     return msd_p;
     706             : }
     707             : 
     708             : 
     709             : void
     710          22 : VisibilityIteratorReadImpl::updateSlicer ()
     711             : {
     712             : 
     713          22 :     if (msIter_p.newMS ()) {
     714          12 :         channels_p.nGroups_p.resize (0, true, false);
     715          12 :         doChannelSelection ();
     716             :     }
     717             : 
     718             :     // set the Slicer to get the selected part of spectrum out of the table
     719          22 :     Int spw = msIter_p.spectralWindowId ();
     720             :     //Fixed what i think was a confusion between chanWidth and chanInc
     721             :     // 2007/11/12
     722          22 :     Int start = channels_p.start_p[spw] + curChanGroup_p * channels_p.width_p[spw];
     723          22 :     AlwaysAssert (start >= 0 && start + channelGroupSize_p <= nChan_p, AipsError);
     724             :     //  slicer_p=Slicer (Slice (),Slice (start,channelGroupSize_p));
     725             :     // above is slow, use IPositions instead.
     726          44 :     slicer_p = Slicer (IPosition (2, 0, start),
     727          44 :                       IPosition (2, nPol_p, channelGroupSize_p),
     728          66 :                       IPosition (2, 1, (channels_p.inc_p[spw] <= 0) ? 1 : channels_p.inc_p[spw] ));
     729          44 :     weightSlicer_p = Slicer (IPosition (1, start), IPosition (1, channelGroupSize_p),
     730          66 :                             IPosition (1, (channels_p.inc_p[spw] <= 0) ? 1 : channels_p.inc_p[spw]));
     731          22 :     useSlicer_p = channelGroupSize_p < nChan_p;
     732             : 
     733             :     //if (msIter_p.newDataDescriptionId ()){
     734          22 :     setTileCache ();
     735             :     //}
     736          22 : }
     737             : 
     738             : 
     739             : 
     740             : void
     741          30 : VisibilityIteratorReadImpl::setTileCache ()
     742             : {
     743             :     // This function sets the tile cache because of a feature in
     744             :     // sliced data access that grows memory dramatically in some cases
     745             :     //  if (useSlicer_p){
     746             : 
     747          30 :     if (autoTileCacheSizing_p){
     748          10 :         return; // rest of method does manual sizing so skip it
     749             :     }
     750             : 
     751          30 :     if (! (msIter_p.newDataDescriptionId () || msIter_p.newMS ()) ) {
     752          10 :         return;
     753             :     }
     754             : 
     755          20 :     const MeasurementSet & theMs = msIter_p.ms ();
     756          20 :     if (theMs.tableType () == Table::Memory) {
     757           0 :         return;
     758             :     }
     759             : 
     760          20 :     const ColumnDescSet & cds = theMs.tableDesc ().columnDescSet ();
     761             : 
     762          20 :     uInt startrow = msIter_p.table ().rowNumbers ()(0); // Get the first row number for this DDID.
     763             : 
     764          20 :     if (tileCacheIsSet_p.nelements () != 8) {
     765           2 :         tileCacheIsSet_p.resize (8);
     766           2 :         tileCacheIsSet_p.set (false);
     767             :     }
     768             : 
     769          20 :     Vector<String> columns (8);
     770          20 :     columns (0) = MS::columnName (MS::DATA);            // complex
     771          20 :     columns (1) = MS::columnName (MS::CORRECTED_DATA);  // complex
     772          20 :     columns (2) = MS::columnName (MS::MODEL_DATA);      // complex
     773          20 :     columns (3) = MS::columnName (MS::FLAG);            // boolean
     774          20 :     columns (4) = MS::columnName (MS::WEIGHT_SPECTRUM); // float
     775          20 :     columns (5) = MS::columnName (MS::WEIGHT);          // float
     776          20 :     columns (6) = MS::columnName (MS::SIGMA);           // float
     777          20 :     columns (7) = MS::columnName (MS::UVW);             // double
     778             : 
     779         180 :     for (uInt k = 0; k < columns.nelements (); ++k) {
     780             : 
     781         160 :         if (! cds.isDefined (columns (k)) || ! usesTiledDataManager (columns[k], theMs)){
     782          30 :             continue;
     783             :         }
     784             : 
     785             :         try {
     786             :             //////////////////
     787             :             //////Temporary fix for virtual ms of multiple real ms's ...miracle of statics
     788             :             //////setting the cache size of hypercube at row 0 of each ms.
     789             :             ///will not work if each subms of a virtual ms has multi hypecube being
     790             :             ///accessed.
     791         130 :             if (theMs.tableInfo ().subType () == "CONCATENATED" &&
     792         130 :                 msIterAtOrigin_p &&
     793           0 :                 ! tileCacheIsSet_p[k]) {
     794             : 
     795           0 :                 Block<String> refTables = theMs.getPartNames (true);
     796             : 
     797           0 :                 for (uInt kk = 0; kk < refTables.nelements (); ++kk) {
     798             : 
     799           0 :                     Table elms (refTables[kk]);
     800           0 :                     ROTiledStManAccessor tacc (elms, columns[k], true);
     801             : 
     802             :                     // Cleverly sense full-row cache size (in tiles)
     803           0 :                     uInt cacheSizeInTiles(1);
     804             : 
     805             :                     // Is startrow correct for each subMS?
     806             :                     //uInt rRow=startrow;
     807           0 :                     uInt rRow=0;    // This preserves previous "single-hypercube" assumption
     808             :                                     
     809           0 :                     IPosition hypercubeShape=tacc.hypercubeShape(rRow);
     810           0 :                     IPosition tileShape=tacc.tileShape(rRow);
     811           0 :                     uInt nax=hypercubeShape.size();  // how many axes
     812             :                     
     813             :                     // Accumulate axis factors up to--but NOT including--row (last) axis
     814             :                     //  "ceil" catches partially filled tiles...
     815           0 :                     for (uInt iax=0;iax<nax-1;++iax)    
     816           0 :                       cacheSizeInTiles*= (uInt) ceil(hypercubeShape[iax]/ (Float)(tileShape[iax]));
     817             :                     
     818             :                     // Double for ALMA data
     819             :                     //   (this satisfies cases where required rows require >1 non-contiguous tiles)
     820           0 :                     cacheSizeInTiles*=2;
     821             : 
     822             :                     // Now set it
     823           0 :                     tacc.setCacheSize (rRow, cacheSizeInTiles);  
     824           0 :                     tileCacheIsSet_p[k] = true;
     825             :                     //cerr << "set cache on kk " << kk << " vol " << columns[k] << "  " << refTables[kk] << endl;
     826           0 :                 }
     827           0 :             }
     828             :             else {
     829             : 
     830         130 :                 ROTiledStManAccessor tacc (theMs, columns[k], true);
     831             : 
     832             : 
     833             :                 // Cleverly sense full-row cache size (in tiles)
     834         130 :                 uInt cacheSizeInTiles(1);
     835             : 
     836         130 :                 IPosition hypercubeShape=tacc.hypercubeShape(startrow);
     837         130 :                 IPosition tileShape=tacc.tileShape(startrow);
     838         130 :                 uInt nax=hypercubeShape.size();  // how many axes
     839             : 
     840             :                 // Accumulate axis factors up to--but NOT including--row (last) axis
     841             :                 //  "ceil" catches partially filled tiles...
     842         338 :                 for (uInt iax=0;iax<nax-1;++iax)    
     843         208 :                   cacheSizeInTiles*= (uInt) ceil(hypercubeShape[iax]/ (Float)(tileShape[iax]));
     844             : 
     845             :                 // Double for ALMA data
     846             :                 //   (this satisfies cases where required rows require >1 non-contiguous tiles)
     847         130 :                 cacheSizeInTiles*=2;
     848             : 
     849         130 :                 Bool setCache = true;
     850         130 :                 if (! useSlicer_p){        // always set cache if slicer in use
     851         378 :                     for (uInt jj = 0 ; jj <  tacc.nhypercubes (); ++jj) {
     852         248 :                         if (tacc.getBucketSize (jj) == 0) {
     853         118 :                             setCache = false;
     854             :                         }
     855             :                     }
     856             :                 }
     857             : 
     858             : 
     859             :                 /// If some bucketSize is 0...there is trouble in setting cache
     860             :                 /// but if slicer is used it gushes anyways if one does not set cache
     861             :                 /// need to fix the 0 bucket size in the filler anyways...then this is not needed
     862         130 :                 if (setCache) {
     863             :                   /*
     864             :                   cout << columns[k] 
     865             :                        << " bucketSize=" << tacc.bucketSize(startrow)
     866             :                        << " hcShape=" << hypercubeShape
     867             :                        << " tShape=" << tileShape
     868             :                        << " cacheSizeInTiles = " << cacheSizeInTiles << "  (nhypercubes=" << tacc.nhypercubes() <<")"<< endl;
     869             :                   */
     870          12 :                     if (tacc.nhypercubes () == 1) {
     871          12 :                         tacc.setCacheSize (0, cacheSizeInTiles);
     872             :                     } else {
     873           0 :                         tacc.setCacheSize (startrow, cacheSizeInTiles);
     874             :                     }
     875             :                 }
     876             : 
     877             : 
     878             : 
     879         130 :             }
     880             :         }
     881           0 :         catch (AipsError x) {
     882             :             //  cerr << "Data man type " << dataManType << "  " << dataManType.contains ("Tiled") << "  && " << (!String (cdesc.dataManagerGroup ()).empty ()) << endl;
     883             :             //  cerr << "Failed to set settilecache due to " << x.getMesg () << " column " << columns[k]  <<endl;
     884             :             //It failed so leave the caching as is
     885           0 :             continue;
     886           0 :         }
     887             :     }
     888          20 : }
     889             : 
     890             : Bool
     891         152 : VisibilityIteratorReadImpl::usesTiledDataManager (const String & columnName,
     892             :                                                   const MeasurementSet & theMs) const
     893             : {
     894         152 :     Bool noData = false;
     895             : 
     896             :     // Have to do something special about weight_spectrum as it tend to exist but
     897             :     // has no valid data.
     898             : 
     899         304 :     noData = noData ||
     900         152 :              (columnName == MS::columnName (MS::WEIGHT_SPECTRUM) && ! existsWeightSpectrum ());
     901             : 
     902             :     // Check to see if the column exist and have valid data
     903             : 
     904         304 :     noData = noData ||
     905         172 :              (columnName == MS::columnName (MS::DATA) &&
     906          40 :               (columns_p.vis_p.isNull () || ! columns_p.vis_p.isDefined (0)));
     907             : 
     908         304 :     noData = noData ||
     909         172 :              (columnName == MS::columnName (MS::MODEL_DATA) &&
     910          40 :               (columns_p.modelVis_p.isNull () || ! columns_p.modelVis_p.isDefined (0)));
     911             : 
     912         297 :     noData = noData ||
     913         165 :              (columnName == MS::columnName (MS::CORRECTED_DATA) &&
     914          40 :               (columns_p.corrVis_p.isNull () || ! columns_p.corrVis_p.isDefined (0)));
     915             : 
     916         290 :     noData = noData ||
     917         158 :              (columnName == MS::columnName (MS::FLAG) &&
     918          40 :               (columns_p.flag_p.isNull () || ! columns_p.flag_p.isDefined (0)));
     919             : 
     920         290 :     noData = noData ||
     921         158 :              (columnName == MS::columnName (MS::WEIGHT) &&
     922          40 :               (columns_p.weight_p.isNull () || ! columns_p.weight_p.isDefined (0)));
     923             : 
     924         290 :     noData = noData ||
     925         158 :              (columnName == MS::columnName (MS::SIGMA) &&
     926          40 :               (columns_p.sigma_p.isNull () || ! columns_p.sigma_p.isDefined (0)));
     927             : 
     928         290 :     noData = noData ||
     929         158 :              (columnName == MS::columnName (MS::UVW) &&
     930          40 :               (columns_p.uvw_p.isNull () || ! columns_p.uvw_p.isDefined (0)));
     931             : 
     932         152 :     Bool usesTiles = false;
     933             : 
     934         152 :     if (! noData){
     935         138 :         String dataManType = RODataManAccessor (theMs, columnName, true).dataManagerType ();
     936             : 
     937         138 :         usesTiles = dataManType.contains ("Tiled");
     938         138 :     }
     939             : 
     940         152 :     return usesTiles;
     941             : }
     942             : 
     943             : 
     944             : /*
     945             : void VisibilityIteratorReadImpl::setTileCache (){
     946             :   // This function sets the tile cache because of a feature in
     947             :   // sliced data access that grows memory dramatically in some cases
     948             :   //if (useSlicer_p){
     949             : 
     950             :   {
     951             :     const MeasurementSet& thems=msIter_p.ms ();
     952             :     const ColumnDescSet& cds=thems.tableDesc ().columnDescSet ();
     953             :     ArrayColumn<Complex> columns_p.vis_p;
     954             :     ArrayColumn<Float> colwgt;
     955             :     Vector<String> columns (3);
     956             :     columns (0)=MS::columnName (MS::DATA);
     957             :     columns (1)=MS::columnName (MS::CORRECTED_DATA);
     958             :     columns (2)=MS::columnName (MS::MODEL_DATA);
     959             :     //cout << "COL " << columns << endl;
     960             :     for (uInt k=0; k< 3; ++k){
     961             :       //cout << "IN loop k " << k << endl;
     962             :       if (thems.tableDesc ().isColumn (columns (k)) ) {
     963             : 
     964             :         columns_p.vis_p.attach (thems,columns (k));
     965             :         String dataManType;
     966             :         dataManType = columns_p.vis_p.columnDesc ().dataManagerType ();
     967             :         //cout << "dataManType " << dataManType << endl;
     968             :         if (dataManType.contains ("Tiled")){
     969             : 
     970             :           ROTiledStManAccessor tacc (thems,
     971             :                                     columns_p.vis_p.columnDesc ().dataManagerGroup ());
     972             :           uInt nHyper = tacc.nhypercubes ();
     973             :           // Find smallest tile shape
     974             :           Int lowestProduct = 0;
     975             :           Int lowestId = 0;
     976             :           Bool firstFound = false;
     977             :           for (uInt id=0; id < nHyper; id++) {
     978             :             Int product = tacc.getTileShape (id).product ();
     979             :             if (product > 0 && (!firstFound || product < lowestProduct)) {
     980             :               lowestProduct = product;
     981             :               lowestId = id;
     982             :               if (!firstFound) firstFound = true;
     983             :             }
     984             :           }
     985             :           Int nchantile;
     986             :           IPosition tileshape=tacc.getTileShape (lowestId);
     987             :           IPosition axisPath (3,2,0,1);
     988             :           //nchantile=tileshape (1);
     989             :           tileshape (1)=channelGroupSize_p;
     990             :           tileshape (2)=curNumRow_p;
     991             :           //cout << "cursorshape " << tileshape << endl;
     992             :           nchantile=tacc.calcCacheSize (0, tileshape, axisPath);
     993             : 
     994             :         //  if (nchantile > 0)
     995             :          //   nchantile=channelGroupSize_p/nchantile*10;
     996             :          // if (nchantile<3)
     997             :           //  nchantile=10;
     998             : 
     999             :           ///////////////
    1000             :           //nchantile *=8;
    1001             :           nchantile=1;
    1002             :           //tileshape (2)=tileshape (2)*8;
    1003             :           //////////////
    1004             :           //cout << tacc.cacheSize (0) << " nchantile "<< nchantile << " max cache size " << tacc.maximumCacheSize () << endl;
    1005             :           tacc.clearCaches ();
    1006             :           tacc.setCacheSize (0, 1);
    1007             :           //tacc.setCacheSize (0, tileshape, axisPath);
    1008             :           //cout << k << "  " << columns (k) << " cache size  " <<  tacc.cacheSize (0) << endl;
    1009             : 
    1010             :         }
    1011             :       }
    1012             :     }
    1013             :   }
    1014             : 
    1015             : }
    1016             :  */
    1017             : 
    1018             : void
    1019          35 : VisibilityIteratorReadImpl::attachColumnsSafe (const Table & t)
    1020             : {
    1021             :     // Normally, the call to attachColumns is redirected back to the ROVI class.
    1022             :     // This allows writable VIs to attach columns in both the read and write impls.
    1023             :     // However, this referral to the ROVI doesn't work during construction of this
    1024             :     // class (VIRI) since there is as yet no pointer to the object under construction.
    1025             :     // In that case, simply perform it locally.
    1026             : 
    1027          35 :     if (rovi_p == NULL){
    1028           4 :         attachColumns (t);
    1029             :     }
    1030             :     else{
    1031          31 :         rovi_p->attachColumns (t);
    1032             :     }
    1033          35 : }
    1034             : 
    1035             : 
    1036             : void
    1037          35 : VisibilityIteratorReadImpl::attachColumns (const Table & t)
    1038             : {
    1039          35 :     const ColumnDescSet & cds = t.tableDesc ().columnDescSet ();
    1040             : 
    1041          35 :     columns_p.antenna1_p.attach (t, MS::columnName (MS::ANTENNA1));
    1042          35 :     columns_p.antenna2_p.attach (t, MS::columnName (MS::ANTENNA2));
    1043             : 
    1044          35 :     if (cds.isDefined ("CORRECTED_DATA")) {
    1045          35 :         columns_p.corrVis_p.attach (t, "CORRECTED_DATA");
    1046             :     }
    1047             : 
    1048          35 :     columns_p.exposure_p.attach (t, MS::columnName (MS::EXPOSURE));
    1049          35 :     columns_p.feed1_p.attach (t, MS::columnName (MS::FEED1));
    1050          35 :     columns_p.feed2_p.attach (t, MS::columnName (MS::FEED2));
    1051          35 :     columns_p.flag_p.attach (t, MS::columnName (MS::FLAG));
    1052          35 :     columns_p.flagCategory_p.attach (t, MS::columnName (MS::FLAG_CATEGORY));
    1053          35 :     columns_p.flagRow_p.attach (t, MS::columnName (MS::FLAG_ROW));
    1054             : 
    1055          35 :     if (cds.isDefined (MS::columnName (MS::FLOAT_DATA))) {
    1056           0 :         columns_p.floatVis_p.attach (t, MS::columnName (MS::FLOAT_DATA));
    1057           0 :         floatDataFound_p = true;
    1058             :     } else {
    1059          35 :         floatDataFound_p = false;
    1060             :     }
    1061             : 
    1062          35 :     if (cds.isDefined ("MODEL_DATA")) {
    1063          35 :         columns_p.modelVis_p.attach (t, "MODEL_DATA");
    1064             :     }
    1065             : 
    1066          35 :     columns_p.observation_p.attach (t, MS::columnName (MS::OBSERVATION_ID));
    1067          35 :     columns_p.processor_p.attach (t, MS::columnName (MS::PROCESSOR_ID));
    1068          35 :     columns_p.scan_p.attach (t, MS::columnName (MS::SCAN_NUMBER));
    1069          35 :     columns_p.sigma_p.attach (t, MS::columnName (MS::SIGMA));
    1070          35 :     columns_p.state_p.attach (t, MS::columnName (MS::STATE_ID));
    1071          35 :     columns_p.time_p.attach (t, MS::columnName (MS::TIME));
    1072          35 :     columns_p.timeCentroid_p.attach (t, MS::columnName (MS::TIME_CENTROID));
    1073          35 :     columns_p.timeInterval_p.attach (t, MS::columnName (MS::INTERVAL));
    1074          35 :     columns_p.uvw_p.attach (t, MS::columnName (MS::UVW));
    1075             : 
    1076          35 :     if (cds.isDefined (MS::columnName (MS::DATA))) {
    1077          35 :         columns_p.vis_p.attach (t, MS::columnName (MS::DATA));
    1078             :     }
    1079             : 
    1080          35 :     columns_p.weight_p.attach (t, MS::columnName (MS::WEIGHT));
    1081             : 
    1082          35 :     if (cds.isDefined ("WEIGHT_SPECTRUM")) {
    1083          29 :         columns_p.weightSpectrum_p.attach (t, "WEIGHT_SPECTRUM");
    1084             :     }
    1085          35 : }
    1086             : 
    1087             : void
    1088           0 : VisibilityIteratorReadImpl::update_rowIds () const
    1089             : {
    1090           0 :     if (cache_p.rowIds_p.nelements () == 0) {
    1091           0 :         cache_p.rowIds_p = selRows_p.convert ();
    1092             : 
    1093           0 :         Vector<uInt> msIter_rowIds (msIter_p.table ().rowNumbers (msIter_p.ms ()));
    1094             : 
    1095           0 :         for (uInt i = 0; i < cache_p.rowIds_p.nelements (); i++) {
    1096           0 :             cache_p.rowIds_p (i) = msIter_rowIds (cache_p.rowIds_p (i));
    1097             :         }
    1098           0 :     }
    1099           0 :     return;
    1100             : }
    1101             : 
    1102             : 
    1103             : Int
    1104           0 : VisibilityIteratorReadImpl::getDataDescriptionId () const
    1105             : {
    1106           0 :     return msIter_p.dataDescriptionId ();
    1107             : }
    1108             : 
    1109             : 
    1110             : const MeasurementSet &
    1111           0 : VisibilityIteratorReadImpl::getMeasurementSet () const
    1112             : {
    1113           0 :     return msIter_p.ms ();
    1114             : }
    1115             : 
    1116             : Int
    1117           0 : VisibilityIteratorReadImpl::getMeasurementSetId () const
    1118             : {
    1119           0 :     return msIter_p.msId ();
    1120             : }
    1121             : 
    1122             : 
    1123             : Int
    1124           0 : VisibilityIteratorReadImpl::getNAntennas () const
    1125             : {
    1126           0 :     Int nAntennas = msIter_p.receptorAngle ().shape ()(1);
    1127             : 
    1128           0 :     return nAntennas;
    1129             : }
    1130             : 
    1131             : MEpoch
    1132           0 : VisibilityIteratorReadImpl::getEpoch () const
    1133             : {
    1134           0 :     MEpoch mEpoch = msIter_p.msColumns ().timeMeas ()(0);
    1135             : 
    1136           0 :     return mEpoch;
    1137             : }
    1138             : 
    1139             : Vector<Float>
    1140           0 : VisibilityIteratorReadImpl::getReceptor0Angle ()
    1141             : {
    1142           0 :     Int nAntennas = getNAntennas ();
    1143             : 
    1144           0 :     Vector<Float> receptor0Angle (nAntennas);
    1145             : 
    1146           0 :     for (int i = 0; i < nAntennas; i++) {
    1147           0 :         receptor0Angle [i] = msIter_p.receptorAngle ()(0, i);
    1148             :     }
    1149             : 
    1150           0 :     return receptor0Angle;
    1151           0 : }
    1152             : 
    1153             : Vector<rownr_t>
    1154           0 : VisibilityIteratorReadImpl::getRowIds () const
    1155             : {
    1156           0 :     update_rowIds ();
    1157             : 
    1158           0 :     return cache_p.rowIds_p;
    1159             : }
    1160             : 
    1161             : 
    1162             : Vector<rownr_t> &
    1163           0 : VisibilityIteratorReadImpl::rowIds (Vector<rownr_t> & rowids) const
    1164             : {
    1165             :     /* Calculate the row numbers in the original MS only when needed,
    1166             :      i.e. when this function is called */
    1167           0 :     update_rowIds ();
    1168           0 :     rowids.resize (cache_p.rowIds_p.nelements ());
    1169           0 :     rowids = cache_p.rowIds_p;
    1170           0 :     return rowids;
    1171             : }
    1172             : 
    1173             : 
    1174             : Vector<Int> &
    1175         200 : VisibilityIteratorReadImpl::antenna1(Vector<Int> & ant1) const
    1176             : {
    1177         200 :     ant1.resize (curNumRow_p);
    1178         200 :     getCol (columns_p.antenna1_p, ant1);
    1179         200 :     return ant1;
    1180             : }
    1181             : 
    1182             : Vector<Int> &
    1183         200 : VisibilityIteratorReadImpl::antenna2(Vector<Int> & ant2) const
    1184             : {
    1185         200 :     ant2.resize (curNumRow_p);
    1186         200 :     getCol (columns_p.antenna2_p, ant2);
    1187         200 :     return ant2;
    1188             : }
    1189             : 
    1190             : Vector<Int> &
    1191           0 : VisibilityIteratorReadImpl::feed1(Vector<Int> & fd1) const
    1192             : {
    1193           0 :     fd1.resize (curNumRow_p);
    1194           0 :     getCol (columns_p.feed1_p, fd1);
    1195           0 :     return fd1;
    1196             : }
    1197             : 
    1198             : Vector<Int> &
    1199           0 : VisibilityIteratorReadImpl::feed2(Vector<Int> & fd2) const
    1200             : {
    1201           0 :     fd2.resize (curNumRow_p);
    1202           0 :     getCol (columns_p.feed2_p, fd2);
    1203           0 :     return fd2;
    1204             : }
    1205             : 
    1206             : Vector<Int> &
    1207         260 : VisibilityIteratorReadImpl::channel (Vector<Int> & chan) const
    1208             : {
    1209         260 :     Int spw = msIter_p.spectralWindowId ();
    1210         260 :     chan.resize (channelGroupSize_p);
    1211         260 :     Int inc = channels_p.inc_p[spw] <= 0 ? 1 : channels_p.inc_p[spw];
    1212       24040 :     for (Int i = 0; i < channelGroupSize_p; i++) {
    1213       23780 :         chan (i) = channels_p.start_p[spw] + curChanGroup_p * channels_p.width_p[spw] + i * inc;
    1214             :     }
    1215         260 :     return chan;
    1216             : }
    1217             : 
    1218             : Vector<Int> &
    1219         207 : VisibilityIteratorReadImpl::corrType (Vector<Int> & corrTypes) const
    1220             : {
    1221         207 :     Int polId = msIter_p.polarizationId ();
    1222         207 :     msIter_p.msColumns ().polarization ().corrType ().get (polId, corrTypes, true);
    1223         207 :     return corrTypes;
    1224             : }
    1225             : 
    1226             : Cube<Bool> &
    1227         260 : VisibilityIteratorReadImpl::flag (Cube<Bool> & flags) const
    1228             : {
    1229         260 :     if (useSlicer_p) {
    1230           0 :         getCol (columns_p.flag_p, slicer_p, flags, true);
    1231             :     } else {
    1232         260 :         getCol (columns_p.flag_p, flags, true);
    1233             :     }
    1234         260 :     return flags;
    1235             : }
    1236             : 
    1237             : Matrix<Bool> &
    1238         200 : VisibilityIteratorReadImpl::flag (Matrix<Bool> & flags) const
    1239             : {
    1240         200 :     if (useSlicer_p) {
    1241           0 :         getCol (columns_p.flag_p, slicer_p, cache_p.flagCube_p, true);
    1242             :     } else {
    1243         200 :         getCol (columns_p.flag_p, cache_p.flagCube_p, true);
    1244             :     }
    1245             : 
    1246         200 :     flags.resize (channelGroupSize_p, curNumRow_p);
    1247             :     // need to optimize this...
    1248             :     //for (Int row=0; row<curNumRow_p; row++) {
    1249             :     //  for (Int chn=0; chn<channelGroupSize_p; chn++) {
    1250             :     //    flags (chn,row)=flagCube (0,chn,row);
    1251             :     //    for (Int pol=1; pol<nPol_p; pol++) {
    1252             :     //    flags (chn,row)|=flagCube (pol,chn,row);
    1253             :     //    }
    1254             :     //  }
    1255             :     //}
    1256             :     Bool deleteIt1;
    1257             :     Bool deleteIt2;
    1258         200 :     const Bool * pcube = cache_p.flagCube_p.getStorage (deleteIt1);
    1259         200 :     Bool * pflags = flags.getStorage (deleteIt2);
    1260       70400 :     for (uInt row = 0; row < curNumRow_p; row++) {
    1261     7090200 :         for (Int chn = 0; chn < channelGroupSize_p; chn++) {
    1262     7020000 :             *pflags = *pcube++;
    1263    28080000 :             for (Int pol = 1; pol < nPol_p; pol++, pcube++) {
    1264    21060000 :                 *pflags = *pcube ? *pcube : *pflags;
    1265             :             }
    1266     7020000 :             pflags++;
    1267             :         }
    1268             :     }
    1269         200 :     cache_p.flagCube_p.freeStorage (pcube, deleteIt1);
    1270         200 :     flags.putStorage (pflags, deleteIt2);
    1271         200 :     return flags;
    1272             : }
    1273             : 
    1274           0 : Bool VisibilityIteratorReadImpl::existsFlagCategory() const
    1275             : {
    1276           0 :   if(msIter_p.newMS()){ // Cache to avoid testing unnecessarily.
    1277             :     try{
    1278           0 :       cache_p.msHasFC_p = columns_p.flagCategory_p.hasContent();
    1279             :     }
    1280           0 :     catch (AipsError x){
    1281           0 :       cache_p.msHasFC_p = false;
    1282           0 :     }
    1283             :   }
    1284           0 :   return cache_p.msHasFC_p;
    1285             : }
    1286             : 
    1287             : Array<Bool> &
    1288           0 : VisibilityIteratorReadImpl::flagCategory (Array<Bool> & flagCategories) const
    1289             : {
    1290           0 :     if (columns_p.flagCategory_p.isNull () || !columns_p.flagCategory_p.isDefined (0)) { // It often is.
    1291           0 :         flagCategories.resize ();    // Zap it.
    1292             :     } else {
    1293           0 :         if (velocity_p.velSelection_p) {
    1294           0 :             throw (AipsError ("velocity selection not allowed in flagCategory ()."));
    1295             :         } else {
    1296           0 :             if (useSlicer_p) {
    1297           0 :                 getCol (columns_p.flagCategory_p, slicer_p, flagCategories, true);
    1298             :             } else {
    1299           0 :                 getCol (columns_p.flagCategory_p, flagCategories, true);
    1300             :             }
    1301             :         }
    1302             :     }
    1303           0 :     return flagCategories;
    1304             : }
    1305             : 
    1306             : Vector<Bool> &
    1307         200 : VisibilityIteratorReadImpl::flagRow (Vector<Bool> & rowflags) const
    1308             : {
    1309         200 :     rowflags.resize (curNumRow_p);
    1310         200 :     getCol (columns_p.flagRow_p, rowflags);
    1311         200 :     return rowflags;
    1312             : }
    1313             : 
    1314             : Vector<Int> &
    1315           0 : VisibilityIteratorReadImpl::observationId (Vector<Int> & obsIDs) const
    1316             : {
    1317           0 :     obsIDs.resize (curNumRow_p);
    1318           0 :     getCol (columns_p.observation_p, obsIDs);
    1319           0 :     return obsIDs;
    1320             : }
    1321             : 
    1322             : Vector<Int> &
    1323           0 : VisibilityIteratorReadImpl::processorId (Vector<Int> & procIDs) const
    1324             : {
    1325           0 :     procIDs.resize (curNumRow_p);
    1326           0 :     getCol (columns_p.processor_p, procIDs);
    1327           0 :     return procIDs;
    1328             : }
    1329             : 
    1330             : Vector<Int> &
    1331           0 : VisibilityIteratorReadImpl::scan (Vector<Int> & scans) const
    1332             : {
    1333           0 :     scans.resize (curNumRow_p);
    1334           0 :     getCol (columns_p.scan_p, scans);
    1335           0 :     return scans;
    1336             : }
    1337             : 
    1338             : Vector<Int> &
    1339           0 : VisibilityIteratorReadImpl::stateId (Vector<Int> & stateIds) const
    1340             : {
    1341           0 :     stateIds.resize (curNumRow_p);
    1342           0 :     getCol (columns_p.state_p, stateIds);
    1343           0 :     return stateIds;
    1344             : }
    1345             : 
    1346             : Vector<Double> &
    1347         201 : VisibilityIteratorReadImpl::frequency (Vector<Double> & freq) const
    1348             : {
    1349         201 :     if (velocity_p.velSelection_p) {
    1350           0 :         freq.resize (velocity_p.nVelChan_p);
    1351           0 :         freq = velocity_p.selFreq_p;
    1352             :     } else {
    1353         201 :         if (! cache_p.freqCacheOK_p) {
    1354           2 :             cache_p.freqCacheOK_p = true;
    1355           2 :             Int spw = msIter_p.spectralWindowId ();
    1356           2 :             cache_p.frequency_p.resize (channelGroupSize_p);
    1357           2 :             const Vector<Double> & chanFreq = msIter_p.frequency ();
    1358           2 :             Int start = channels_p.start_p[spw];
    1359           2 :             Int inc = channels_p.inc_p[spw] <= 0 ? 1 : channels_p.inc_p[spw];
    1360         202 :             for (Int i = 0; i < channelGroupSize_p; i++) {
    1361         200 :                 cache_p.frequency_p (i) = chanFreq (start + curChanGroup_p * channels_p.width_p[spw] + i * inc);
    1362             :             }
    1363             :         }
    1364         201 :         freq.resize (channelGroupSize_p);
    1365         201 :         freq = cache_p.frequency_p;
    1366             :     }
    1367         201 :     return freq;
    1368             : }
    1369             : 
    1370             : 
    1371             : Vector<Double> &
    1372         201 : VisibilityIteratorReadImpl::time (Vector<Double> & t) const
    1373             : {
    1374         201 :     t.resize (curNumRow_p);
    1375             : 
    1376         201 :     getCol (columns_p.time_p, t);
    1377             : 
    1378         201 :     return t;
    1379             : }
    1380             : 
    1381             : Vector<Double> &
    1382           0 : VisibilityIteratorReadImpl::timeCentroid (Vector<Double> & t) const
    1383             : {
    1384           0 :     t.resize (curNumRow_p);
    1385           0 :     getCol (columns_p.timeCentroid_p, t);
    1386           0 :     return t;
    1387             : }
    1388             : 
    1389             : Vector<Double> &
    1390           0 : VisibilityIteratorReadImpl::timeInterval (Vector<Double> & t) const
    1391             : {
    1392           0 :     t.resize (curNumRow_p);
    1393           0 :     getCol (columns_p.timeInterval_p, t);
    1394           0 :     return t;
    1395             : }
    1396             : 
    1397             : Vector<Double> &
    1398           0 : VisibilityIteratorReadImpl::exposure (Vector<Double> & expo) const
    1399             : {
    1400           0 :     expo.resize (curNumRow_p);
    1401           0 :     getCol (columns_p.exposure_p, expo);
    1402           0 :     return expo;
    1403             : }
    1404             : 
    1405             : Cube<Complex> &
    1406         266 : VisibilityIteratorReadImpl::visibility (Cube<Complex> & vis, DataColumn whichOne) const
    1407             : {
    1408             : 
    1409         266 :     if (useSlicer_p) {
    1410           0 :         getDataColumn (whichOne, slicer_p, vis);
    1411             :     } else {
    1412         266 :         getDataColumn (whichOne, vis);
    1413             :     }
    1414             : 
    1415         266 :     return vis;
    1416             : }
    1417             : 
    1418             : 
    1419             : // helper function to swap the y and z axes of a Cube
    1420             : void
    1421           0 : swapyz (Cube<Complex> & out, const Cube<Complex> & in)
    1422             : {
    1423           0 :     IPosition inShape = in.shape ();
    1424           0 :     uInt nx = inShape (0), ny = inShape (2), nz = inShape (1);
    1425           0 :     out.resize (nx, ny, nz);
    1426             :     Bool deleteIn, deleteOut;
    1427           0 :     const Complex * pin = in.getStorage (deleteIn);
    1428           0 :     Complex * pout = out.getStorage (deleteOut);
    1429           0 :     uInt i = 0, zOffset = 0;
    1430           0 :     for (uInt iz = 0; iz < nz; iz++, zOffset += nx) {
    1431           0 :         Int yOffset = zOffset;
    1432           0 :         for (uInt iy = 0; iy < ny; iy++, yOffset += nx * nz) {
    1433           0 :             for (uInt ix = 0; ix < nx; ix++) {
    1434           0 :                 pout[i++] = pin[ix + yOffset];
    1435             :             }
    1436             :         }
    1437             :     }
    1438           0 :     out.putStorage (pout, deleteOut);
    1439           0 :     in.freeStorage (pin, deleteIn);
    1440           0 : }
    1441             : 
    1442             : // helper function to swap the y and z axes of a Cube
    1443             : void
    1444           0 : swapyz (Cube<Bool> & out, const Cube<Bool> & in)
    1445             : {
    1446           0 :     IPosition inShape = in.shape ();
    1447           0 :     uInt nx = inShape (0), ny = inShape (2), nz = inShape (1);
    1448           0 :     out.resize (nx, ny, nz);
    1449             :     Bool deleteIn, deleteOut;
    1450           0 :     const Bool * pin = in.getStorage (deleteIn);
    1451           0 :     Bool * pout = out.getStorage (deleteOut);
    1452           0 :     uInt i = 0, zOffset = 0;
    1453           0 :     for (uInt iz = 0; iz < nz; iz++, zOffset += nx) {
    1454           0 :         Int yOffset = zOffset;
    1455           0 :         for (uInt iy = 0; iy < ny; iy++, yOffset += nx * nz) {
    1456           0 :             for (uInt ix = 0; ix < nx; ix++) {
    1457           0 :                 pout[i++] = pin[ix + yOffset];
    1458             :             }
    1459             :         }
    1460             :     }
    1461           0 : }
    1462             : 
    1463             : Cube<Float> &
    1464           0 : VisibilityIteratorReadImpl::floatData (Cube<Float> & fcube) const
    1465             : {
    1466           0 :     if (useSlicer_p) {
    1467           0 :         getFloatDataColumn (slicer_p, fcube);
    1468             :     } else {
    1469           0 :         getFloatDataColumn (fcube);
    1470             :     }
    1471           0 :     return fcube;
    1472             : }
    1473             : 
    1474             : // transpose a matrix
    1475             : void
    1476           0 : transpose (Matrix<Float> & out, const Matrix<Float> & in)
    1477             : {
    1478           0 :     uInt ny = in.nrow (), nx = in.ncolumn ();
    1479           0 :     out.resize (nx, ny);
    1480             :     Bool deleteIn, deleteOut;
    1481           0 :     const Float * pin = in.getStorage (deleteIn);
    1482           0 :     Float * pout = out.getStorage (deleteOut);
    1483           0 :     uInt i = 0;
    1484           0 :     for (uInt iy = 0; iy < ny; iy++) {
    1485           0 :         uInt yOffset = 0;
    1486           0 :         for (uInt ix = 0; ix < nx; ix++, yOffset += ny) {
    1487           0 :             pout[i++] = pin[iy + yOffset];
    1488             :         }
    1489             :     }
    1490           0 :     out.putStorage (pout, deleteOut);
    1491           0 :     in.freeStorage (pin, deleteIn);
    1492           0 : }
    1493             : 
    1494             : void
    1495           0 : VisibilityIteratorReadImpl::getDataColumn (DataColumn whichOne,
    1496             :                                           const Slicer & slicer,
    1497             :                                           Cube<Complex> & data) const
    1498             : {
    1499             : 
    1500             : 
    1501             :     // Return the visibility (observed, model or corrected);
    1502             :     // deal with DATA and FLOAT_DATA seamlessly for observed data.
    1503           0 :     switch (whichOne) {
    1504             : 
    1505           0 :     case ROVisibilityIterator::Observed:
    1506           0 :         if (floatDataFound_p) {
    1507           0 :             Cube<Float> dataFloat;
    1508           0 :             getCol (columns_p.floatVis_p, slicer, dataFloat, true);
    1509           0 :             data.resize (dataFloat.shape ());
    1510           0 :             convertArray (data, dataFloat);
    1511           0 :         } else {
    1512           0 :             getCol (columns_p.vis_p, slicer, data, true);
    1513             :         }
    1514           0 :         break;
    1515             : 
    1516           0 :     case ROVisibilityIterator::Corrected:
    1517           0 :         getCol (columns_p.corrVis_p, slicer, data, true);
    1518           0 :         break;
    1519             : 
    1520           0 :     case ROVisibilityIterator::Model:
    1521           0 :         getCol (columns_p.modelVis_p, slicer, data, true);
    1522           0 :         break;
    1523             : 
    1524           0 :     default:
    1525           0 :         Assert (false);
    1526             :     }
    1527             : 
    1528           0 : }
    1529             : 
    1530             : void
    1531         266 : VisibilityIteratorReadImpl::getDataColumn (DataColumn whichOne,
    1532             :                                           Cube<Complex> & data) const
    1533             : {
    1534             :     // Return the visibility (observed, model or corrected);
    1535             :     // deal with DATA and FLOAT_DATA seamlessly for observed data.
    1536             : 
    1537         266 :     switch (whichOne) {
    1538             : 
    1539           6 :     case ROVisibilityIterator::Observed:
    1540           6 :         if (floatDataFound_p) {
    1541           0 :             Cube<Float> dataFloat;
    1542           0 :             getCol (columns_p.floatVis_p, dataFloat, true);
    1543           0 :             data.resize (dataFloat.shape ());
    1544           0 :             convertArray (data, dataFloat);
    1545           0 :         } else {
    1546           6 :             getCol (columns_p.vis_p, data, true);
    1547             :         }
    1548           6 :         break;
    1549             : 
    1550          60 :     case ROVisibilityIterator::Corrected:
    1551          60 :         getCol (columns_p.corrVis_p, data, true);
    1552          60 :         break;
    1553             : 
    1554         200 :     case ROVisibilityIterator::Model:
    1555         200 :         getCol (columns_p.modelVis_p, data, true);
    1556         200 :         break;
    1557             : 
    1558           0 :     default:
    1559           0 :         Assert (false);
    1560             :     }
    1561         266 : }
    1562             : 
    1563             : void
    1564           0 : VisibilityIteratorReadImpl::getFloatDataColumn (const Slicer & slicer,
    1565             :                                                Cube<Float> & data) const
    1566             : {
    1567             :     // Return FLOAT_DATA as real Floats.
    1568           0 :     if (floatDataFound_p) {
    1569           0 :         getCol (columns_p.floatVis_p, slicer, data, true);
    1570             :     }
    1571           0 : }
    1572             : 
    1573             : void
    1574           0 : VisibilityIteratorReadImpl::getFloatDataColumn (Cube<Float> & data) const
    1575             : {
    1576             :     // Return FLOAT_DATA as real Floats.
    1577           0 :     if (floatDataFound_p) {
    1578           0 :         getCol (columns_p.floatVis_p, data, true);
    1579             :     }
    1580           0 : }
    1581             : 
    1582             : Matrix<CStokesVector> &
    1583           0 : VisibilityIteratorReadImpl::visibility (Matrix<CStokesVector> & vis,
    1584             :                                        DataColumn whichOne) const
    1585             : {
    1586           0 :     if (useSlicer_p) {
    1587           0 :         getDataColumn (whichOne, slicer_p, cache_p.visCube_p);
    1588             :     } else {
    1589           0 :         getDataColumn (whichOne, cache_p.visCube_p);
    1590             :     }
    1591             : 
    1592           0 :     vis.resize (channelGroupSize_p, curNumRow_p);
    1593             :     Bool deleteIt;
    1594           0 :     Complex * pcube = cache_p.visCube_p.getStorage (deleteIt);
    1595           0 :     if (deleteIt) {
    1596           0 :         cerr << "Problem in ROVisIter::visibility - deleteIt true" << endl;
    1597             :     }
    1598             :     // Here we cope in a limited way with cases where not all 4
    1599             :     // polarizations are present: if only 2, assume XX,YY or RR,LL
    1600             :     // if only 1, assume it's an estimate of Stokes I (one of RR,LL,XX,YY)
    1601             :     // The cross terms are zero filled in these cases.
    1602           0 :     switch (nPol_p) {
    1603           0 :     case 4: {
    1604           0 :         for (uInt row = 0; row < curNumRow_p; row++) {
    1605           0 :             for (Int chn = 0; chn < channelGroupSize_p; chn++, pcube += 4) {
    1606           0 :                 vis (chn, row) = pcube;
    1607             :             }
    1608             :         }
    1609           0 :         break;
    1610             :     }
    1611           0 :     case 2: {
    1612           0 :         vis.set (CStokesVector (Complex (0., 0.)));
    1613           0 :         for (uInt row = 0; row < curNumRow_p; row++) {
    1614           0 :             for (Int chn = 0; chn < channelGroupSize_p; chn++, pcube += 2) {
    1615           0 :                 CStokesVector & v = vis (chn, row);
    1616           0 :                 v (0) = *pcube;
    1617           0 :                 v (3) = *(pcube + 1);
    1618             :             }
    1619             :         }
    1620           0 :         break;
    1621             :     }
    1622           0 :     case 1: {
    1623           0 :         vis.set (CStokesVector (Complex (0., 0.)));
    1624           0 :         for (uInt row = 0; row < curNumRow_p; row++) {
    1625           0 :             for (Int chn = 0; chn < channelGroupSize_p; chn++, pcube++) {
    1626           0 :                 CStokesVector & v = vis (chn, row);
    1627           0 :                 v (0) = v (3) = *pcube;
    1628             :             }
    1629             :         }
    1630             :     } //# case 1
    1631             :     } //# switch
    1632           0 :     return vis;
    1633             : }
    1634             : 
    1635             : Vector<RigidVector<Double, 3> > &
    1636         200 : VisibilityIteratorReadImpl::uvw (Vector<RigidVector<Double, 3> > & uvwvec) const
    1637             : {
    1638         200 :     uvwvec.resize (curNumRow_p);
    1639         200 :     getColArray<Double>(columns_p.uvw_p, cache_p.uvwMat_p, true);
    1640             :     // get a pointer to the raw storage for quick access
    1641             :     Bool deleteIt;
    1642         200 :     Double * pmat = cache_p.uvwMat_p.getStorage (deleteIt);
    1643       70400 :     for (uInt row = 0; row < curNumRow_p; row++, pmat += 3) {
    1644       70200 :         uvwvec (row) = pmat;
    1645             :     }
    1646         200 :     return uvwvec;
    1647             : }
    1648             : 
    1649             : Matrix<Double> &
    1650           0 : VisibilityIteratorReadImpl::uvwMat (Matrix<Double> & uvwmat) const
    1651             : {
    1652           0 :     getCol (columns_p.uvw_p, uvwmat, true);
    1653           0 :     return uvwmat;
    1654             : }
    1655             : 
    1656             : // Fill in parallactic angle.
    1657             : Vector<Float>
    1658           0 : VisibilityIteratorReadImpl::feed_pa (Double time) const
    1659             : {
    1660             :     //  LogMessage message (LogOrigin ("VisibilityIteratorReadImpl","feed_pa"));
    1661             : 
    1662             :     // Absolute UT
    1663           0 :     Double ut = time;
    1664             : 
    1665           0 :     if (ut != cache_p.lastfeedpaUT_p) {
    1666             : 
    1667             :         // Set up the Epoch using the absolute MJD in seconds
    1668             :         // get the Epoch reference from the column
    1669             : 
    1670           0 :         MEpoch mEpoch = getEpoch ();
    1671             : 
    1672           0 :         const Matrix<Double> & angles = receptorAngles ().xyPlane(0);
    1673           0 :         Int nAnt = angles.shape ()(1);
    1674             : 
    1675           0 :         Vector<Float> receptor0Angle (nAnt, 0);
    1676             : 
    1677           0 :         for (int i = 0; i < nAnt; i++) {
    1678           0 :             receptor0Angle [i] = angles (0, i);
    1679             :         }
    1680             : 
    1681           0 :         cache_p.feedpa_p.assign (feed_paCalculate (time, msd_p, nAnt, mEpoch, receptor0Angle));
    1682             : 
    1683           0 :         cache_p.lastfeedpaUT_p = ut;
    1684           0 :     }
    1685           0 :     return cache_p.feedpa_p;
    1686             : }
    1687             : 
    1688             : Vector<Float>
    1689           0 : VisibilityIteratorReadImpl::feed_paCalculate (Double time, MSDerivedValues & msd,
    1690             :                                               Int nAntennas, const MEpoch & mEpoch0,
    1691             :                                               const Vector<Float> & receptor0Angle)
    1692             : {
    1693           0 :     MEpoch mEpoch = mEpoch0;
    1694             : 
    1695           0 :     mEpoch.set (MVEpoch (Quantity (time, "s")));
    1696             : 
    1697           0 :     msd.setEpoch (mEpoch);
    1698             : 
    1699             :     // Calculate pa for all antennas.
    1700             : 
    1701           0 :     Vector<Float> feedpa (nAntennas);
    1702             : 
    1703           0 :     for (Int iant = 0; iant < nAntennas; iant++) {
    1704             : 
    1705           0 :         msd.setAntenna (iant);
    1706           0 :         feedpa (iant) = msd.parAngle ();
    1707             : 
    1708             :         // add angle for receptor 0
    1709             : 
    1710           0 :         feedpa (iant) += receptor0Angle (iant);
    1711             : 
    1712           0 :         if (aips_debug && iant == 0) {
    1713             : 
    1714           0 :             cout << "Antenna " << iant << " at time: " << MVTime (mEpoch.getValue ()) <<
    1715           0 :                     " has PA = " << feedpa (iant) * 57.28 << endl;
    1716             :         }
    1717             :     }
    1718             : 
    1719           0 :     return feedpa;
    1720           0 : }
    1721             : 
    1722             : // Fill in parallactic angle.
    1723             : const Float &
    1724           0 : VisibilityIteratorReadImpl::parang0(Double time) const
    1725             : {
    1726             :     //  LogMessage message (LogOrigin ("VisibilityIteratorReadImpl","parang0"));
    1727             : 
    1728             :     // Absolute UT
    1729           0 :     Double ut = time;
    1730             : 
    1731           0 :     if (ut != cache_p.lastParang0UT_p) {
    1732             : 
    1733           0 :         cache_p.lastParang0UT_p = ut;
    1734             : 
    1735             :         // Set up the Epoch using the absolute MJD in seconds
    1736             :         // get the Epoch reference from the column
    1737           0 :         MEpoch mEpoch = msIter_p.msColumns ().timeMeas ()(0);
    1738           0 :         cache_p.parang0_p = parang0Calculate (time, msd_p, mEpoch);
    1739           0 :     }
    1740           0 :     return cache_p.parang0_p;
    1741             : }
    1742             : 
    1743             : Float
    1744           0 : VisibilityIteratorReadImpl::parang0Calculate (Double time, MSDerivedValues & msd, const MEpoch & mEpoch0)
    1745             : {
    1746           0 :     MEpoch mEpoch = mEpoch0;
    1747             : 
    1748           0 :     mEpoch.set (MVEpoch (Quantity (time, "s")));
    1749           0 :     msd.setEpoch (mEpoch);
    1750             : 
    1751             :     // Calculate pa for all antennas.
    1752           0 :     msd.setAntenna (-1);
    1753           0 :     Float parang0 = msd.parAngle ();
    1754             : 
    1755           0 :     if (aips_debug)
    1756           0 :         cout << "At time: " << MVTime (mEpoch.getValue ()) <<
    1757           0 :              " PA = " << parang0 * 57.28 << " deg" << endl;
    1758             : 
    1759           0 :     return parang0;
    1760           0 : }
    1761             : 
    1762             : 
    1763             : // Fill in parallactic angle (NO FEED PA offset!).
    1764             : Vector<Float>
    1765           0 : VisibilityIteratorReadImpl::parang (Double time) const
    1766             : {
    1767             :     //  LogMessage message (LogOrigin ("VisibilityIteratorReadImpl","parang"));
    1768             : 
    1769             :     // Absolute UT
    1770           0 :     Double ut = time;
    1771             : 
    1772           0 :     if (ut != cache_p.lastParangUT_p) {
    1773             : 
    1774           0 :         cache_p.lastParangUT_p = ut;
    1775             : 
    1776             :         // Set up the Epoch using the absolute MJD in seconds
    1777             :         // get the Epoch reference from the column
    1778             : 
    1779           0 :         MEpoch mEpoch = msIter_p.msColumns ().timeMeas ()(0);
    1780           0 :         Int nAnt = msIter_p.receptorAngle ().shape ()(1);
    1781             : 
    1782           0 :         cache_p.parang_p = parangCalculate (time, msd_p, nAnt, mEpoch);
    1783             : 
    1784           0 :     }
    1785           0 :     return cache_p.parang_p;
    1786             : }
    1787             : 
    1788             : Vector<Float>
    1789           0 : VisibilityIteratorReadImpl::parangCalculate (Double time, MSDerivedValues & msd, int nAntennas, const MEpoch mEpoch0)
    1790             : {
    1791           0 :     MEpoch mEpoch = mEpoch0;
    1792           0 :     mEpoch.set (MVEpoch (Quantity (time, "s")));
    1793             : 
    1794           0 :     msd.setEpoch (mEpoch);
    1795             : 
    1796             :     // Calculate pa for all antennas.
    1797             : 
    1798           0 :     Vector<Float> parang (nAntennas);
    1799             : 
    1800           0 :     for (Int iant = 0; iant < nAntennas; iant++) {
    1801             : 
    1802           0 :         msd.setAntenna (iant);
    1803           0 :         parang (iant) = msd.parAngle ();
    1804             : 
    1805           0 :         if (aips_debug && iant == 0) {
    1806           0 :             cout << "Antenna " << iant << " at time: " << MVTime (mEpoch.getValue ()) <<
    1807           0 :                  " has PA = " << parang (iant) * 57.28 << endl;
    1808             :         }
    1809             :     }
    1810             : 
    1811           0 :     return parang;
    1812           0 : }
    1813             : 
    1814             : // Fill in azimuth/elevation of the antennas.
    1815             : // Cloned from feed_pa, we need to check that this is all correct!
    1816             : Vector<MDirection>
    1817           0 : VisibilityIteratorReadImpl::azel (Double time) const
    1818             : {
    1819             :     //  LogMessage message (LogOrigin ("VisibilityIteratorReadImpl","azel"));
    1820             : 
    1821             :     // Absolute UT
    1822           0 :     Double ut = time;
    1823             : 
    1824           0 :     if (ut != cache_p.lastazelUT_p) {
    1825             : 
    1826           0 :         cache_p.lastazelUT_p = ut;
    1827           0 :         Int nAnt = msIter_p.receptorAngle ().shape ()(1);
    1828           0 :         MEpoch mEpoch = msIter_p.msColumns ().timeMeas ()(0);
    1829             : 
    1830           0 :         azelCalculate (ut, msd_p, cache_p.azel_p, nAnt, mEpoch);
    1831             : 
    1832           0 :     }
    1833           0 :     return cache_p.azel_p;
    1834             : }
    1835             : 
    1836             : void
    1837           0 : VisibilityIteratorReadImpl::azelCalculate (Double time, MSDerivedValues & msd, Vector<MDirection> & azel,
    1838             :         Int nAnt, const MEpoch & mEpoch0)
    1839             : {
    1840             :     // Refactored into a static method to allow VisBufferAsync to use
    1841             : 
    1842           0 :     MEpoch mEpoch = mEpoch0;
    1843             : 
    1844           0 :     mEpoch.set (MVEpoch (Quantity (time, "s")));
    1845             : 
    1846           0 :     msd.setEpoch (mEpoch);
    1847             : 
    1848             :     // Calculate az/el for all antennas.
    1849             : 
    1850           0 :     azel.resize (nAnt);
    1851             : 
    1852           0 :     for (Int iant = 0; iant < nAnt; iant++) {
    1853           0 :         msd.setAntenna (iant);
    1854           0 :         azel (iant) = msd.azel ();
    1855           0 :         if (aips_debug) {
    1856           0 :             if (iant == 0)
    1857           0 :                 cout << "Antenna " << iant << " at time: " << MVTime (mEpoch.getValue ()) <<
    1858           0 :                      " has AzEl = " << azel (iant).getAngle ("deg") << endl;
    1859             :         }
    1860             :     }
    1861           0 : }
    1862             : 
    1863             : // Fill in azimuth/elevation of the antennas.
    1864             : // Cloned from feed_pa, we need to check that this is all correct!
    1865             : MDirection
    1866           0 : VisibilityIteratorReadImpl::azel0(Double time) const
    1867             : {
    1868             :     //  LogMessage message (LogOrigin ("VisibilityIteratorReadImpl","azel0"));
    1869             : 
    1870             :     // Absolute UT
    1871           0 :     Double ut = time;
    1872             : 
    1873           0 :     if (ut != cache_p.lastazel0UT_p) {
    1874             : 
    1875           0 :         cache_p.lastazel0UT_p = ut;
    1876             : 
    1877           0 :         MEpoch mEpoch = msIter_p.msColumns ().timeMeas ()(0);
    1878             : 
    1879           0 :         azel0Calculate (time, msd_p, cache_p.azel0_p, mEpoch);
    1880             : 
    1881           0 :     }
    1882           0 :     return cache_p.azel0_p;
    1883             : }
    1884             : 
    1885             : void
    1886           0 : VisibilityIteratorReadImpl::azel0Calculate (Double time, MSDerivedValues & msd,
    1887             :         MDirection & azel0, const MEpoch & mEpoch0)
    1888             : {
    1889             :     // Refactored into a static method to allow VisBufferAsync to use
    1890             : 
    1891           0 :     MEpoch mEpoch = mEpoch0;
    1892             : 
    1893           0 :     mEpoch.set (MVEpoch (Quantity (time, "s")));
    1894             : 
    1895           0 :     msd.setEpoch (mEpoch);
    1896             : 
    1897           0 :     msd.setAntenna (-1);
    1898             : 
    1899           0 :     azel0 = msd.azel ();
    1900             : 
    1901           0 :     if (aips_debug) {
    1902           0 :         cout << "At time: " << MVTime (mEpoch.getValue ()) <<
    1903           0 :              " AzEl = " << azel0.getAngle ("deg") << endl;
    1904             :     }
    1905             : 
    1906           0 : }
    1907             : 
    1908             : // Hour angle at specified time.
    1909             : Double
    1910           0 : VisibilityIteratorReadImpl::hourang (Double time) const
    1911             : {
    1912             :     //  LogMessage message (LogOrigin ("VisibilityIteratorReadImpl","azel"));
    1913             : 
    1914             :     // Absolute UT
    1915           0 :     Double ut = time;
    1916             : 
    1917           0 :     if (ut != cache_p.lasthourangUT_p) {
    1918             : 
    1919           0 :         cache_p.lasthourangUT_p = ut;
    1920             : 
    1921             :         // Set up the Epoch using the absolute MJD in seconds
    1922             :         // get the Epoch reference from the column keyword
    1923             : 
    1924           0 :         MEpoch mEpoch = msIter_p.msColumns ().timeMeas ()(0);
    1925             : 
    1926           0 :         cache_p.hourang_p = hourangCalculate (time, msd_p, mEpoch);
    1927             : 
    1928           0 :     }
    1929           0 :     return cache_p.hourang_p;
    1930             : }
    1931             : 
    1932             : Double
    1933           0 : VisibilityIteratorReadImpl::hourangCalculate (Double time, MSDerivedValues & msd, const MEpoch & mEpoch0)
    1934             : {
    1935           0 :     MEpoch mEpoch = mEpoch0;
    1936             : 
    1937           0 :     mEpoch.set (MVEpoch (Quantity (time, "s")));
    1938             : 
    1939           0 :     msd.setEpoch (mEpoch);
    1940             : 
    1941           0 :     msd.setAntenna (-1);
    1942             : 
    1943           0 :     Double hourang = msd.hourAngle ();
    1944             : 
    1945           0 :     return hourang;
    1946           0 : }
    1947             : 
    1948             : Vector<Float> &
    1949           0 : VisibilityIteratorReadImpl::sigma (Vector<Float> & sig) const
    1950             : {
    1951           0 :     Matrix<Float> sigmat;
    1952           0 :     getCol (columns_p.sigma_p, sigmat);
    1953             :     // Do a rough average of the parallel hand polarizations to get a single
    1954             :     // sigma. Should do this properly someday, or return all values
    1955           0 :     sig.resize (sigmat.ncolumn ());
    1956           0 :     sig = sigmat.row (0);
    1957           0 :     sig += sigmat.row (nPol_p - 1);
    1958           0 :     sig /= 2.0f;
    1959           0 :     return sig;
    1960           0 : }
    1961             : 
    1962             : Matrix<Float> &
    1963           0 : VisibilityIteratorReadImpl::sigmaMat (Matrix<Float> & sigmat) const
    1964             : {
    1965           0 :     sigmat.resize (nPol_p, curNumRow_p);
    1966           0 :     getCol (columns_p.sigma_p, sigmat);
    1967           0 :     return sigmat;
    1968             : }
    1969             : 
    1970             : Vector<Float> &
    1971         200 : VisibilityIteratorReadImpl::weight (Vector<Float> & wt) const
    1972             : {
    1973             :     // Take average of parallel hand polarizations for now.
    1974             :     // Later convert weight () to return full polarization dependence
    1975         200 :     Matrix<Float> polWeight;
    1976         200 :     getCol (columns_p.weight_p, polWeight);
    1977         200 :     wt.resize (polWeight.ncolumn ());
    1978         200 :     wt = polWeight.row (0);
    1979         200 :     wt += polWeight.row (nPol_p - 1);
    1980         200 :     wt /= 2.0f;
    1981         200 :     return wt;
    1982         200 : }
    1983             : 
    1984             : Matrix<Float> &
    1985           0 : VisibilityIteratorReadImpl::weightMat (Matrix<Float> & wtmat) const
    1986             : {
    1987           0 :     wtmat.resize (nPol_p, curNumRow_p);
    1988           0 :     getCol (columns_p.weight_p, wtmat);
    1989           0 :     return wtmat;
    1990             : }
    1991             : 
    1992             : 
    1993             : Bool
    1994         212 : VisibilityIteratorReadImpl::existsWeightSpectrum () const
    1995             : {
    1996         212 :     if (msIter_p.newMS ()) { // Cache to avoid testing unnecessarily.
    1997             :         try {
    1998         212 :             cache_p.msHasWtSp_p = columns_p.weightSpectrum_p.hasContent ();
    1999             :             // Comparing columns_p.weightSpectrum_p.shape (0) to
    2000             :             // IPosition (2, nPol_p, channelGroupSize ()) is too strict
    2001             :             // when channel averaging might have changed
    2002             :             // channelGroupSize () or weightSpectrum () out of sync.  Unfortunately the
    2003             :             // right answer might not get cached soon enough.
    2004             :             //
    2005             :             //       columns_p.weightSpectrum_p.shape (0).isEqual (IPosition (2, nPol_p,
    2006             :             //                                                    channelGroupSize ())));
    2007             :             // if (!msHasWtSp_p){
    2008             :             //   cerr << "columns_p.weightSpectrum_p.shape (0): " << columns_p.weightSpectrum_p.shape (0) << endl;
    2009             :             //   cerr << "(nPol_p, channelGroupSize ()): " << nPol_p
    2010             :             //        << ", " << channelGroupSize () << endl;
    2011             :             // }
    2012           0 :         } catch (AipsError x) {
    2013           0 :             cache_p.msHasWtSp_p = false;
    2014           0 :         }
    2015             :     }
    2016         212 :     return cache_p.msHasWtSp_p;
    2017             : }
    2018             : 
    2019             : Cube<Float> &
    2020         200 : VisibilityIteratorReadImpl::weightSpectrum (Cube<Float> & wtsp) const
    2021             : {
    2022         200 :     if (existsWeightSpectrum ()) {
    2023           0 :         if (useSlicer_p) {
    2024           0 :             getCol (columns_p.weightSpectrum_p, slicer_p, wtsp, true);
    2025             :         } else {
    2026           0 :             getCol (columns_p.weightSpectrum_p, wtsp, true);
    2027             :         }
    2028             :     } else {
    2029         200 :         wtsp.resize (0, 0, 0);
    2030             :     }
    2031         200 :     return wtsp;
    2032             : }
    2033             : 
    2034             : const VisImagingWeight &
    2035         200 : VisibilityIteratorReadImpl::getImagingWeightGenerator () const
    2036             : {
    2037         200 :     return imwgt_p;
    2038             : }
    2039             : 
    2040             : 
    2041             : //Matrix<Float> &
    2042             : //VisibilityIteratorReadImpl::imagingWeight (Matrix<Float> & wt) const
    2043             : //{
    2044             : //    if (imwgt_p.getType () == "none") {
    2045             : //        throw (AipsError ("Programmer Error... imaging weights not set"));
    2046             : //    }
    2047             : //    Vector<Float> weightvec;
    2048             : //    weight (weightvec);
    2049             : //    Matrix<Bool> flagmat;
    2050             : //    flag (flagmat);
    2051             : //    wt.resize (flagmat.shape ());
    2052             : //    if (imwgt_p.getType () == "uniform") {
    2053             : //        Vector<Double> fvec;
    2054             : //        frequency (fvec);
    2055             : //        Matrix<Double> uvwmat;
    2056             : //        uvwMat (uvwmat);
    2057             : //        imwgt_p.weightUniform (wt, flagmat, uvwmat, fvec, weightvec, msId (), fieldId ());
    2058             : //        if (imwgt_p.doFilter ()) {
    2059             : //            imwgt_p.filter (wt, flagmat, uvwmat, fvec, weightvec);
    2060             : //        }
    2061             : //    } else if (imwgt_p.getType () == "radial") {
    2062             : //        Vector<Double> fvec;
    2063             : //        frequency (fvec);
    2064             : //        Matrix<Double> uvwmat;
    2065             : //        uvwMat (uvwmat);
    2066             : //        imwgt_p.weightRadial (wt, flagmat, uvwmat, fvec, weightvec);
    2067             : //        if (imwgt_p.doFilter ()) {
    2068             : //            imwgt_p.filter (wt, flagmat, uvwmat, fvec, weightvec);
    2069             : //        }
    2070             : //    } else {
    2071             : //        imwgt_p.weightNatural (wt, flagmat, weightvec);
    2072             : //        if (imwgt_p.doFilter ()) {
    2073             : //            Matrix<Double> uvwmat;
    2074             : //            uvwMat (uvwmat);
    2075             : //            Vector<Double> fvec;
    2076             : //            frequency (fvec);
    2077             : //            imwgt_p.filter (wt, flagmat, uvwmat, fvec, weightvec);
    2078             : //
    2079             : //        }
    2080             : //    }
    2081             : //
    2082             : //    return wt;
    2083             : //}
    2084             : 
    2085             : Int
    2086           0 : VisibilityIteratorReadImpl::nSubInterval () const
    2087             : {
    2088             :     // Return the number of sub-intervals in the current chunk,
    2089             :     // i.e. the number of unique time stamps
    2090             :     //
    2091             :     // Find all unique times in time_p
    2092           0 :     Int retval = 0;
    2093           0 :     uInt nTimes = time_p.nelements ();
    2094           0 :     if (nTimes > 0) {
    2095             : 
    2096           0 :         Vector<Double> times (time_p); /* Do not change time_p, make a copy */
    2097             :         Bool deleteIt;
    2098           0 :         Double * tp = times.getStorage (deleteIt);
    2099             : 
    2100           0 :         std::sort (tp, tp + nTimes);
    2101             : 
    2102             :         /* Count unique times */
    2103           0 :         retval = 1;
    2104           0 :         for (unsigned i = 0; i < nTimes - 1; i++) {
    2105           0 :             if (tp[i] < tp[i + 1]) {
    2106           0 :                 retval += 1;
    2107             :             }
    2108             :         }
    2109           0 :     }
    2110           0 :     return retval;
    2111             : }
    2112             : 
    2113             : VisibilityIteratorReadImpl &
    2114           0 : VisibilityIteratorReadImpl::selectVelocity (Int /*nChan*/,
    2115             :         const MVRadialVelocity & /*vStart*/,
    2116             :         const MVRadialVelocity & /*vInc*/,
    2117             :         MRadialVelocity::Types /*rvType*/,
    2118             :         MDoppler::Types /*dType*/,
    2119             :         Bool /*precise*/)
    2120             : {
    2121           0 :     ThrowIf (true, "Method not implemented");
    2122             : 
    2123             : //    if (!initialized_p) {
    2124             : //        // initialize the base iterator only (avoid recursive call to originChunks)
    2125             : //        if (!msIterAtOrigin_p) {
    2126             : //            msIter_p.origin ();
    2127             : //            msIterAtOrigin_p = true;
    2128             : //            stateOk_p = false;
    2129             : //        }
    2130             : //    }
    2131             : //    velSelection_p = true;
    2132             : //    nVelChan_p = nChan;
    2133             : //    vstart_p = vStart;
    2134             : //    vinc_p = vInc;
    2135             : //    msd_p.setVelocityFrame (rvType);
    2136             : //    vDef_p = dType;
    2137             : //    cFromBETA_p.set (MDoppler (MVDoppler (Quantity (0., "m/s")),
    2138             : //                             MDoppler::BETA), vDef_p);
    2139             : //    vPrecise_p = precise;
    2140             : //    if (precise) {
    2141             : //        // set up conversion engine for full conversion
    2142             : //    }
    2143             : //    // have to reset the iterator so all caches get filled
    2144             : //    originChunks ();
    2145           0 :     return *this;
    2146             : }
    2147             : 
    2148             : 
    2149             : VisibilityIteratorReadImpl &
    2150           1 : VisibilityIteratorReadImpl::selectChannel (Int nGroup, Int start, Int width,
    2151             :         Int increment, Int spectralWindow)
    2152             : {
    2153             : 
    2154           1 :     if (!initialized_p) {
    2155             :         // initialize the base iterator only (avoid recursive call to originChunks)
    2156           0 :         if (!msIterAtOrigin_p) {
    2157           0 :             msIter_p.origin ();
    2158           0 :             msIterAtOrigin_p = true;
    2159           0 :             stateOk_p = false;
    2160             :         }
    2161             :     }
    2162           1 :     Int spw = spectralWindow;
    2163           1 :     if (spw < 0) {
    2164           0 :         spw = msIter_p.spectralWindowId ();
    2165             :     }
    2166           1 :     Int n = channels_p.nGroups_p.nelements ();
    2167           1 :     if (n == 0) {
    2168           0 :         msChannels_p.spw_p.resize (1, true, false);
    2169           0 :         msChannels_p.spw_p[0].resize (1);
    2170           0 :         msChannels_p.spw_p[0][0] = spw;
    2171           0 :         msChannels_p.nGroups_p.resize (1, true, false);
    2172           0 :         msChannels_p.nGroups_p[0].resize (1);
    2173           0 :         msChannels_p.nGroups_p[0][0] = nGroup;
    2174           0 :         msChannels_p.start_p.resize (1, true, false);
    2175           0 :         msChannels_p.start_p[0].resize (1);
    2176           0 :         msChannels_p.start_p[0][0] = start;
    2177           0 :         msChannels_p.width_p.resize (1, true, false);
    2178           0 :         msChannels_p.width_p[0].resize (1);
    2179           0 :         msChannels_p.width_p[0][0] = width;
    2180           0 :         msChannels_p.inc_p.resize (1, true, false);
    2181           0 :         msChannels_p.inc_p[0].resize (1);
    2182           0 :         msChannels_p.inc_p[0][0] = increment;
    2183           0 :         msCounter_p = 0;
    2184             : 
    2185             :     } else {
    2186           1 :         Bool hasSpw = false;
    2187           1 :         Int spwIndex = -1;
    2188           1 :         for (uInt k = 0; k < msChannels_p.spw_p[0].nelements (); ++k) {
    2189           1 :             if (spw == msChannels_p.spw_p[0][k]) {
    2190           1 :                 hasSpw = true;
    2191           1 :                 spwIndex = k;
    2192           1 :                 break;
    2193             :             }
    2194             :         }
    2195           1 :         if (!hasSpw) {
    2196           0 :             Int nspw = msChannels_p.spw_p[0].nelements () + 1;
    2197           0 :             msChannels_p.spw_p[0].resize (nspw, true);
    2198           0 :             msChannels_p.spw_p[0][nspw - 1] = spw;
    2199           0 :             msChannels_p.nGroups_p[0].resize (nspw, true);
    2200           0 :             msChannels_p.nGroups_p[0][nspw - 1] = nGroup;
    2201           0 :             msChannels_p.start_p[0].resize (nspw, true);
    2202           0 :             msChannels_p.start_p[0][nspw - 1] = start;
    2203           0 :             msChannels_p.width_p[0].resize (nspw, true);
    2204           0 :             msChannels_p.width_p[0][nspw - 1] = width;
    2205           0 :             msChannels_p.inc_p[0].resize (nspw, true);
    2206           0 :             msChannels_p.inc_p[0][nspw - 1] = increment;
    2207             :         } else {
    2208           1 :             msChannels_p.spw_p[0][spwIndex] = spw;
    2209           1 :             msChannels_p.nGroups_p[0][spwIndex] = nGroup;
    2210           1 :             msChannels_p.start_p[0][spwIndex] = start;
    2211           1 :             msChannels_p.width_p[0][spwIndex] = width;
    2212           1 :             msChannels_p.inc_p[0][spwIndex] = increment;
    2213             :         }
    2214             : 
    2215             : 
    2216             :     }
    2217           1 :     if (spw >= n) {
    2218             :         // we need to resize the blocks
    2219           0 :         Int newn = max (2, max (2 * n, spw + 1));
    2220           0 :         channels_p.nGroups_p.resize (newn);
    2221           0 :         channels_p.start_p.resize (newn);
    2222           0 :         channels_p.width_p.resize (newn);
    2223           0 :         channels_p.inc_p.resize (newn);
    2224           0 :         for (Int i = n; i < newn; i++) {
    2225           0 :             channels_p.nGroups_p[i] = 0;
    2226             :         }
    2227             :     }
    2228           1 :     channels_p.start_p[spw] = start;
    2229           1 :     channels_p.width_p[spw] = width;
    2230             : 
    2231           1 :     channels_p.inc_p[spw] = increment;
    2232           1 :     channels_p.nGroups_p[spw] = nGroup;
    2233             :     // have to reset the iterator so all caches get filled & slicer sizes
    2234             :     // get updated
    2235             :     //  originChunks ();
    2236             :     //
    2237             :     //    if (msIterAtOrigin_p){
    2238             :     //        if (!isInSelectedSPW (msIter_p.spectralWindowId ())){
    2239             :     //            while ((!isInSelectedSPW (msIter_p.spectralWindowId ()))
    2240             :     //                    && (msIter_p.more ()))
    2241             :     //                msIter_p++;
    2242             :     //            stateOk_p=false;
    2243             :     //            setState ();
    2244             :     //        }
    2245             :     //    }
    2246             : 
    2247             :     //leave the state where msiter is pointing
    2248           1 :     channelGroupSize_p = channels_p.width_p[msIter_p.spectralWindowId ()];
    2249           1 :     curNGroups_p = channels_p.nGroups_p[msIter_p.spectralWindowId ()];
    2250             : 
    2251           1 :     return *this;
    2252             : }
    2253             : 
    2254             : VisibilityIteratorReadImpl &
    2255           2 : VisibilityIteratorReadImpl::selectChannel (const Block<Vector<Int> > & blockNGroup,
    2256             :                                            const Block<Vector<Int> > & blockStart,
    2257             :                                            const Block<Vector<Int> > & blockWidth,
    2258             :                                            const Block<Vector<Int> > & blockIncr,
    2259             :                                            const Block<Vector<Int> > & blockSpw)
    2260             : {
    2261             :     /*
    2262             :     No longer needed
    2263             :     if (!isMultiMS_p){
    2264             :     //Programmer error ...so should not reach here
    2265             :     cout << "Cannot use this function if Visiter was not constructed with multi-ms"
    2266             :      << endl;
    2267             :     }
    2268             :      */
    2269             : 
    2270           2 :     msChannels_p.nGroups_p.resize (0, true, false);
    2271           2 :     msChannels_p.nGroups_p = blockNGroup;
    2272           2 :     msChannels_p.start_p.resize (0, true, false);
    2273           2 :     msChannels_p.start_p = blockStart;
    2274           2 :     msChannels_p.width_p.resize (0, true, false);
    2275           2 :     msChannels_p.width_p = blockWidth;
    2276           2 :     msChannels_p.inc_p.resize (0, true, false);
    2277           2 :     msChannels_p.inc_p = blockIncr;
    2278           2 :     msChannels_p.spw_p.resize (0, true, false);
    2279           2 :     msChannels_p.spw_p = blockSpw;
    2280             : 
    2281           2 :     if (!initialized_p) {
    2282             :         // initialize the base iterator only (avoid recursive call to originChunks)
    2283           2 :         if (!msIterAtOrigin_p) {
    2284           2 :             msIter_p.origin ();
    2285           2 :             msIterAtOrigin_p = true;
    2286           2 :             stateOk_p = false;
    2287             :         }
    2288             :     }
    2289             : 
    2290           2 :     channels_p.nGroups_p.resize (0);
    2291           2 :     msCounter_p = 0;
    2292             : 
    2293           2 :     doChannelSelection ();
    2294             :     // have to reset the iterator so all caches get filled & slicer sizes
    2295             :     // get updated
    2296             : 
    2297           2 :     if (msIterAtOrigin_p) {
    2298           2 :         if (!isInSelectedSPW (msIter_p.spectralWindowId ())) {
    2299           0 :             while ((!isInSelectedSPW (msIter_p.spectralWindowId ()))
    2300           0 :                     && (msIter_p.more ())) {
    2301           0 :                 msIter_p++;
    2302             :             }
    2303           0 :             stateOk_p = false;
    2304             :         }
    2305             : 
    2306             :     }
    2307             : 
    2308           2 :     originChunks ();
    2309           2 :     return *this;
    2310             : }
    2311             : 
    2312             : 
    2313             : void
    2314           0 : VisibilityIteratorReadImpl::getChannelSelection (Block< Vector<Int> > & blockNGroup,
    2315             :         Block< Vector<Int> > & blockStart,
    2316             :         Block< Vector<Int> > & blockWidth,
    2317             :         Block< Vector<Int> > & blockIncr,
    2318             :         Block< Vector<Int> > & blockSpw)
    2319             : {
    2320             : 
    2321           0 :     blockNGroup.resize (0, true, false);
    2322           0 :     blockNGroup = msChannels_p.nGroups_p;
    2323           0 :     blockStart.resize (0, true, false);
    2324           0 :     blockStart = msChannels_p.start_p;
    2325           0 :     blockWidth.resize (0, true, false);
    2326           0 :     blockWidth = msChannels_p.width_p;
    2327           0 :     blockIncr.resize (0, true, false);
    2328           0 :     blockIncr = msChannels_p.inc_p;
    2329           0 :     blockSpw.resize (0, true, false);
    2330           0 :     blockSpw = msChannels_p.spw_p;
    2331           0 : }
    2332             : void
    2333          14 : VisibilityIteratorReadImpl::doChannelSelection ()
    2334             : {
    2335          28 :     for (uInt k = 0; k < msChannels_p.spw_p[msCounter_p].nelements (); ++k) {
    2336          14 :         Int spw = msChannels_p.spw_p[msCounter_p][k];
    2337          14 :         if (spw < 0) {
    2338           0 :             spw = msIter_p.spectralWindowId ();
    2339             :         }
    2340          14 :         Int n = channels_p.nGroups_p.nelements ();
    2341          14 :         if (spw >= n) {
    2342             :             // we need to resize the blocks
    2343          14 :             Int newn = max (2, max (2 * n, spw + 1));
    2344          14 :             channels_p.nGroups_p.resize (newn, true, true);
    2345          14 :             channels_p.start_p.resize (newn, true, true);
    2346          14 :             channels_p.width_p.resize (newn, true, true);
    2347          14 :             channels_p.inc_p.resize (newn, true, true);
    2348          42 :             for (Int i = n; i < newn; i++) {
    2349          28 :                 channels_p.nGroups_p[i] = 0;
    2350             :             }
    2351             :         }
    2352             : 
    2353          14 :         channels_p.start_p[spw] = msChannels_p.start_p[msCounter_p][k];
    2354          14 :         channels_p.width_p[spw] = msChannels_p.width_p[msCounter_p][k];
    2355          14 :         channelGroupSize_p = msChannels_p.width_p[msCounter_p][k];
    2356          14 :         channels_p.inc_p[spw] = msChannels_p.inc_p[msCounter_p][k];
    2357          14 :         channels_p.nGroups_p[spw] = msChannels_p.nGroups_p[msCounter_p][k];
    2358          14 :         curNGroups_p = msChannels_p.nGroups_p[msCounter_p][k];
    2359             : 
    2360             :     }
    2361          14 :     Int spw = msIter_p.spectralWindowId ();
    2362          14 :     Int spIndex = -1;
    2363          14 :     for (uInt k = 0; k < msChannels_p.spw_p[msCounter_p].nelements (); ++k) {
    2364          14 :         if (spw == msChannels_p.spw_p[msCounter_p][k]) {
    2365          14 :             spIndex = k;
    2366          14 :             break;
    2367             :         }
    2368             :     }
    2369             : 
    2370             : 
    2371          14 :     if (spIndex < 0) {
    2372           0 :         spIndex = 0;
    2373             :     }
    2374             :     //leave this at the stage where msiter is pointing
    2375          14 :     channelGroupSize_p = msChannels_p.width_p[msCounter_p][spIndex];
    2376          14 :     curNGroups_p = msChannels_p.nGroups_p[msCounter_p][spIndex];
    2377             : 
    2378             : 
    2379             : 
    2380          14 : }
    2381             : 
    2382             : void
    2383           0 : VisibilityIteratorReadImpl::slicesToMatrices (Vector<Matrix<Int> > & matv,
    2384             :         const Vector<Vector<Slice> > & slicesv,
    2385             :         const Vector<Int> & widthsv) const
    2386             : {
    2387           0 :     uInt nspw = slicesv.nelements ();
    2388             : 
    2389           0 :     matv.resize (nspw);
    2390           0 :     uInt selspw = 0;
    2391           0 :     for (uInt spw = 0; spw < nspw; ++spw) {
    2392           0 :         uInt nSlices = slicesv[spw].nelements ();
    2393             : 
    2394             :         // Figure out how big to make matv[spw].
    2395           0 :         uInt totOutChan = 0;
    2396             : 
    2397           0 :         Int width = (nSlices > 0) ? widthsv[selspw] : 1;
    2398           0 :         if (width < 1) {
    2399           0 :             throw (AipsError ("Cannot channel average with width < 1"));
    2400             :         }
    2401             : 
    2402           0 :         for (uInt slicenum = 0; slicenum < nSlices; ++slicenum) {
    2403           0 :             const Slice & sl = slicesv[spw][slicenum];
    2404           0 :             Int firstchan = sl.start ();
    2405           0 :             Int lastchan = sl.all () ? firstchan + channels_p.width_p[spw] - 1 : sl.end ();
    2406           0 :             Int inc = sl.all () ? 1 : sl.inc ();
    2407             : 
    2408             :             // Even if negative increments are desirable, the for loop below has a <.
    2409           0 :             if (inc < 1) {
    2410           0 :                 throw (AipsError ("The channel increment must be >= 1"));
    2411             :             }
    2412             : 
    2413             :             // This formula is very dependent on integer division.  Don't rearrange it.
    2414           0 :             totOutChan += 1 + ((lastchan - firstchan) / inc) / (1 + (width - 1) / inc);
    2415             :         }
    2416           0 :         matv[spw].resize (totOutChan, 4);
    2417             : 
    2418             :         // Index of input channel in SELECTED list, i.e.
    2419             :         // mschan = vi.chanIds (chanids, spw)[selchanind].
    2420           0 :         uInt selchanind = 0;
    2421             : 
    2422             :         // Fill matv with channel boundaries.
    2423           0 :         uInt outChan = 0;
    2424           0 :         for (uInt slicenum = 0; slicenum < nSlices; ++slicenum) {
    2425           0 :             const Slice & sl = slicesv[spw][slicenum];
    2426           0 :             Int firstchan = sl.start ();
    2427           0 :             Int lastchan = sl.all () ? firstchan + channels_p.width_p[spw] - 1 : sl.end ();
    2428           0 :             Int inc = sl.all () ? 1 : sl.inc (); // Default to no skipping
    2429             : 
    2430             :             // Again, these depend on integer division.  Don't rearrange them.
    2431           0 :             Int selspan = 1 + (width - 1) / inc;
    2432           0 :             Int span = inc * selspan;
    2433             : 
    2434           0 :             for (Int mschan = firstchan; mschan <= lastchan; mschan += span) {
    2435             :                 // The start and end in MS channel #s.
    2436           0 :                 matv[spw](outChan, 0) = mschan;
    2437           0 :                 matv[spw](outChan, 1) = mschan + width - 1;
    2438             : 
    2439             :                 // The start and end in selected reckoning.
    2440           0 :                 matv[spw](outChan, 2) = selchanind;
    2441           0 :                 selchanind += selspan;
    2442           0 :                 matv[spw](outChan, 3) = selchanind - 1;
    2443           0 :                 ++outChan;
    2444             :             }
    2445             :         }
    2446           0 :         if (nSlices > 0) {  // spw was selected
    2447           0 :             ++selspw;
    2448             :         }
    2449             :     }
    2450           0 : }
    2451             : 
    2452             : 
    2453           0 : void VisibilityIteratorReadImpl::getFreqInSpwRange(Double& freqStart, Double& freqEnd, MFrequency::Types freqframe) const {
    2454           0 :   Int nMS = msIter_p.numMS ();
    2455           0 :   freqStart=C::dbl_max;
    2456           0 :   freqEnd = 0.0;
    2457             :             
    2458           0 :   for (Int msId=0; msId < nMS; ++msId){
    2459             : 
    2460           0 :     Vector<Int> spws =  msChannels_p.spw_p[msId];
    2461           0 :     Vector<Int> starts = msChannels_p.start_p[msId];
    2462           0 :     Vector<Int> nchan;
    2463             :     // careful here as we don't want to change width_p as it is multiplied by incr below
    2464           0 :     nchan= msChannels_p.width_p[msId];
    2465           0 :     Vector<Int> incr = msChannels_p.inc_p[msId];
    2466           0 :     nchan=nchan*incr;
    2467           0 :     Vector<uInt>  uniqIndx;
    2468           0 :     Vector<Int> fldId;
    2469           0 :     ScalarColumn<Int> (msIter_p.ms (msId), MS::columnName (MS::FIELD_ID)).getColumn (fldId);
    2470           0 :     uInt nFields = GenSort<Int>::sort (fldId, Sort::Ascending, Sort::QuickSort | Sort::NoDuplicates);
    2471           0 :     for (uInt indx=0; indx< nFields; ++indx){
    2472           0 :       Int fieldid=fldId(indx);
    2473             :       Double tmpFreqStart; 
    2474             :       Double tmpFreqEnd;
    2475           0 :       MSUtil::getFreqRangeInSpw(tmpFreqStart, tmpFreqEnd, spws, starts, nchan, msIter_p.ms(msId), freqframe, fieldid);
    2476           0 :       if(freqStart > tmpFreqStart) freqStart=tmpFreqStart;
    2477           0 :       if(freqEnd < tmpFreqEnd) freqEnd=tmpFreqEnd;
    2478             :     }
    2479           0 :   }
    2480             : 
    2481           0 : }
    2482             : 
    2483             : 
    2484             : 
    2485             : void
    2486           0 : VisibilityIteratorReadImpl::getSpwInFreqRange (Block<Vector<Int> > & spw,
    2487             :         Block<Vector<Int> > & start,
    2488             :         Block<Vector<Int> > & nchan,
    2489             :         Double freqStart,
    2490             :         Double freqEnd,
    2491             :         Double freqStep,
    2492             :         MFrequency::Types freqframe) const
    2493             : {
    2494             :     // This functionality was relocated from MSIter in order to support this operation
    2495             :     // within the VI to make the VisibilityIteratorReadImplAsync implementation feasible.
    2496             : 
    2497           0 :     Int nMS = msIter_p.numMS ();
    2498             : 
    2499           0 :     spw.resize (nMS, true, false);
    2500           0 :     start.resize (nMS, true, false);
    2501           0 :     nchan.resize (nMS, true, false);
    2502             : 
    2503           0 :     for (Int k = 0; k < nMS; ++k) {
    2504           0 :         Vector<Double> t;
    2505           0 :         ScalarColumn<Double> (msIter_p.ms (k), MS::columnName (MS::TIME)).getColumn (t);
    2506           0 :         Vector<Int> ddId;
    2507           0 :         Vector<Int> fldId;
    2508           0 :         ScalarColumn<Int> (msIter_p.ms (k), MS::columnName (MS::DATA_DESC_ID)).getColumn (ddId);
    2509           0 :         ScalarColumn<Int> (msIter_p.ms (k), MS::columnName (MS::FIELD_ID)).getColumn (fldId);
    2510           0 :         MSFieldColumns fieldCol (msIter_p.ms (k).field ());
    2511           0 :         MSDataDescColumns ddCol (msIter_p.ms (k).dataDescription ());
    2512           0 :         MSSpWindowColumns spwCol (msIter_p.ms (k).spectralWindow ());
    2513           0 :         ROScalarMeasColumn<MEpoch> timeCol (msIter_p.ms (k), MS::columnName (MS::TIME));
    2514           0 :         Vector<uInt>  uniqIndx;
    2515           0 :         uInt nTimes = GenSortIndirect<Double>::sort (uniqIndx, t, Sort::Ascending, Sort::QuickSort | Sort::NoDuplicates);
    2516             :         //now need to do the conversion to data frame from requested frame
    2517             :         //Get the epoch mesasures of the first row
    2518           0 :         MEpoch ep;
    2519           0 :         timeCol.get (0, ep);
    2520           0 :         MPosition obsPos = msIter_p.telescopePosition ();
    2521           0 :         Int oldDD = ddId[0];
    2522           0 :         Int oldFLD = fldId[0];
    2523             :         //For now we will assume that the field is not moving very far from polynome 0
    2524           0 :         MDirection dir = fieldCol.phaseDirMeas (fldId[0]);
    2525           0 :         MFrequency::Types obsMFreqType = (MFrequency::Types) (spwCol.measFreqRef ()(ddCol.spectralWindowId ()(ddId[0])));
    2526             :         //cout << "nTimes " << nTimes << endl;
    2527             :         //cout << " obsframe " << obsMFreqType << " reqFrame " << freqframe << endl;
    2528           0 :         MeasFrame frame (ep, obsPos, dir);
    2529             :         MFrequency::Convert toObs (freqframe,
    2530           0 :                                   MFrequency::Ref (obsMFreqType, frame));
    2531             : 
    2532           0 :         Double freqEndMax = freqEnd;
    2533           0 :         Double freqStartMin = freqStart;
    2534           0 :         if (freqframe != obsMFreqType) {
    2535           0 :             freqEndMax = 0.0;
    2536           0 :             freqStartMin = C::dbl_max;
    2537             :         }
    2538             : 
    2539           0 :         for (uInt j = 0; j < nTimes; ++j) {
    2540           0 :             timeCol.get (uniqIndx[j], ep);
    2541           0 :             if (oldDD != ddId[uniqIndx[j]]) {
    2542           0 :                 oldDD = ddId[uniqIndx[j]];
    2543           0 :                 if (spwCol.measFreqRef ()(ddCol.spectralWindowId ()(ddId[uniqIndx[j]])) != obsMFreqType) {
    2544           0 :                     obsMFreqType = (MFrequency::Types) (spwCol.measFreqRef ()(ddCol.spectralWindowId ()(ddId[uniqIndx[j]])));
    2545           0 :                     toObs.setOut (MFrequency::Ref (obsMFreqType, frame));
    2546             :                 }
    2547             :             }
    2548           0 :             if (obsMFreqType != freqframe) {
    2549           0 :                 frame.resetEpoch (ep);
    2550           0 :                 if (oldFLD != fldId[uniqIndx[j]]) {
    2551           0 :                     oldFLD = fldId[uniqIndx[j]];
    2552           0 :                     frame.resetDirection (fieldCol.phaseDirMeas (fldId[uniqIndx[j]]));
    2553             :                 }
    2554           0 :                 Double freqTmp = toObs (Quantity (freqStart, "Hz")).get ("Hz").getValue ();
    2555           0 :                 freqStartMin = (freqStartMin > freqTmp) ? freqTmp : freqStartMin;
    2556           0 :                 freqTmp = toObs (Quantity (freqEnd, "Hz")).get ("Hz").getValue ();
    2557           0 :                 freqEndMax = (freqEndMax < freqTmp) ? freqTmp : freqEndMax;
    2558             :             }
    2559             :         }
    2560             : 
    2561             :         //cout << "freqStartMin " << freqStartMin << " freqEndMax " << freqEndMax << endl;
    2562           0 :         MSSpwIndex spwIn (msIter_p.ms (k).spectralWindow ());
    2563             : 
    2564           0 :         spwIn.matchFrequencyRange (freqStartMin - 0.5 * freqStep, freqEndMax + 0.5 * freqStep, spw[k], start[k], nchan[k]);
    2565           0 :     }
    2566           0 : }
    2567             : 
    2568             : vector<MeasurementSet>
    2569           0 : VisibilityIteratorReadImpl::getMeasurementSets () const
    2570             : {
    2571           0 :     return measurementSets_p;
    2572             : }
    2573             : 
    2574             : 
    2575             : void
    2576           1 : VisibilityIteratorReadImpl::allSelectedSpectralWindows (Vector<Int> & spws, Vector<Int> & nvischan)
    2577             : {
    2578             : 
    2579           1 :     spws.resize ();
    2580           1 :     spws = msChannels_p.spw_p[msId ()];
    2581           1 :     nvischan.resize ();
    2582           1 :     nvischan.resize (max (spws) + 1);
    2583           1 :     nvischan.set (-1);
    2584           2 :     for (uInt k = 0; k < spws.nelements (); ++k) {
    2585           1 :         nvischan[spws[k]] = channels_p.width_p[spws[k]];
    2586             :     }
    2587           1 : }
    2588             : 
    2589             : Vector<Double> &
    2590           0 : VisibilityIteratorReadImpl::lsrFrequency (Vector<Double> & freq) const
    2591             : {
    2592           0 :     if (velocity_p.velSelection_p) {
    2593           0 :         freq.resize (velocity_p.nVelChan_p);
    2594           0 :         freq = velocity_p.lsrFreq_p;
    2595             :     } else {
    2596             :         // if there is no vel selection, we just return the observing freqs
    2597           0 :         frequency (freq);
    2598             :     }
    2599           0 :     return freq;
    2600             : }
    2601             : 
    2602             : 
    2603             : void
    2604           1 : VisibilityIteratorReadImpl::lsrFrequency (const Int & spw, Vector<Double> & freq,
    2605             :                                           Bool & convert, const Bool ignoreconv)
    2606             : {
    2607             :     // This method is not good for conversion between frames which are extremely
    2608             :     // time dependent over the course of the observation e.g topo to lsr unless
    2609             :     // the epoch is in the actual buffer
    2610             : 
    2611           1 :     if (velocity_p.velSelection_p) {
    2612           0 :         getTopoFreqs ();
    2613           0 :         lsrFrequency (freq);
    2614           0 :         return;
    2615             :     }
    2616             : 
    2617           1 :     if (! cache_p.freqCacheOK_p) {
    2618           0 :         frequency (freq);
    2619             :     }
    2620             : 
    2621             :     //MFrequency::Types obsMFreqType=(MFrequency::Types)(msIter_p.msColumns ().spectralWindow ().measFreqRef ()(spw));
    2622             : 
    2623             :     //chanFreq=msIter_p.msColumns ().spectralWindow ().chanFreq ()(spw);
    2624             : 
    2625           1 :     const ArrayColumn <Double> & chanFreqs = msIter_p.msColumns ().spectralWindow ().chanFreq ();
    2626           1 :     const ScalarColumn<Int> & obsMFreqTypes = msIter_p.msColumns ().spectralWindow ().measFreqRef ();
    2627           1 :     MEpoch ep;
    2628           1 :     ROScalarMeasColumn<MEpoch>(msIter_p.table (), MS::columnName (MS::TIME)).get (curStartRow_p, ep); // Setting epoch to iteration's first one
    2629           1 :     MPosition obsPos = msIter_p.telescopePosition ();
    2630           1 :     MDirection dir = msIter_p.phaseCenter ();
    2631             : 
    2632           1 :     lsrFrequency (spw, freq, convert, channels_p.start_p, channels_p.width_p, channels_p.inc_p,
    2633           1 :                   channels_p.nGroups_p, chanFreqs, obsMFreqTypes, ep, obsPos, dir, ignoreconv);
    2634             : 
    2635           1 : }
    2636             : 
    2637             : void
    2638           1 : VisibilityIteratorReadImpl::lsrFrequency (const Int & spw,
    2639             :                                           Vector<Double> & freq,
    2640             :                                           Bool & convert,
    2641             :                                           const Block<Int> & chanStart,
    2642             :                                           const Block<Int> & chanWidth,
    2643             :                                           const Block<Int> & chanInc,
    2644             :                                           const Block<Int> & numChanGroup,
    2645             :                                           const ArrayColumn <Double> & chanFreqs,
    2646             :                                           const ScalarColumn<Int> & obsMFreqTypes,
    2647             :                                           const MEpoch & ep,
    2648             :                                           const MPosition & obsPos,
    2649             :                                           const MDirection & dir, const Bool ignoreconv)
    2650             : {
    2651             : 
    2652           1 :     Vector<Double> chanFreq (0);
    2653           1 :     chanFreq = chanFreqs (spw);
    2654             : 
    2655             :     //chanFreq=msIter_p.msColumns ().spectralWindow ().chanFreq ()(spw);
    2656             :     //      Int start=channels_p.start_p[spw]-msIter_p.startChan ();
    2657             :     //Assuming that the spectral windows selected is not a reference ms from
    2658             :     //visset ...as this will have a start chan offseted may be.
    2659             : 
    2660           1 :     Int start = chanStart[spw];
    2661           1 :     freq.resize (chanWidth[spw]);
    2662           1 :     MFrequency::Types obsMFreqType = (MFrequency::Types) (obsMFreqTypes (spw));
    2663           1 :     MeasFrame frame (ep, obsPos, dir);
    2664             :     MFrequency::Convert tolsr (obsMFreqType,
    2665           1 :                                MFrequency::Ref (MFrequency::LSRK, frame));
    2666             : 
    2667             :     //    if (obsMFreqType != MFrequency::LSRK){
    2668             :     //        convert=true;
    2669             :     //    }
    2670             : 
    2671           1 :     convert = obsMFreqType != MFrequency::LSRK; // make this parameter write-only
    2672             :     // user requested no conversion
    2673           1 :     if(ignoreconv) convert=false;
    2674             : 
    2675         101 :     for (Int i = 0; i < chanWidth[spw]; i++) {
    2676         100 :         Int inc = chanInc[spw] <= 0 ? 1 : chanInc[spw] ;
    2677         100 :         if (convert) {
    2678           0 :             freq[i] = tolsr (chanFreq (start +
    2679           0 :                                        (numChanGroup[spw] - 1) * chanWidth[spw] + i * inc)).
    2680           0 :                                        getValue ().getValue ();
    2681             :         } else {
    2682         100 :             freq[i] = chanFreq (start +
    2683         100 :                                 (numChanGroup[spw] - 1) * chanWidth[spw] + i * inc);
    2684             :         }
    2685             :     }
    2686           1 : }
    2687             : 
    2688             : void
    2689           0 : VisibilityIteratorReadImpl::getLsrInfo (Block<Int> & channelGroupNumber,
    2690             :                                         Block<Int> & channelIncrement,
    2691             :                                         Block<Int> & channelStart,
    2692             :                                         Block<Int> & channelWidth,
    2693             :                                         MPosition & observatoryPositon,
    2694             :                                         MDirection & phaseCenter,
    2695             :                                         Bool & velocitySelection) const
    2696             : {
    2697           0 :     channelStart = channels_p.start_p;
    2698           0 :     channelWidth = channels_p.width_p;
    2699           0 :     channelIncrement = channels_p.inc_p;
    2700           0 :     channelGroupNumber = channels_p.nGroups_p;
    2701           0 :     observatoryPositon = msIter_p.telescopePosition ();
    2702           0 :     phaseCenter = msIter_p.phaseCenter ();
    2703           0 :     velocitySelection = velocity_p.velSelection_p;
    2704           0 : }
    2705             : 
    2706             : 
    2707             : void
    2708           2 : VisibilityIteratorReadImpl::attachVisBuffer (VisBuffer & vb)
    2709             : {
    2710           2 :     vbStack_p.push (& vb);
    2711           2 :     vb.invalidate ();
    2712           2 : }
    2713             : 
    2714             : VisBuffer *
    2715           0 : VisibilityIteratorReadImpl::getVisBuffer ()
    2716             : {
    2717           0 :     VisBuffer * result = NULL;
    2718             : 
    2719           0 :     if (! vbStack_p.empty ()) {
    2720           0 :         result = vbStack_p.top ();
    2721             :     }
    2722             : 
    2723           0 :     return result;
    2724             : }
    2725             : 
    2726             : void
    2727           1 : VisibilityIteratorReadImpl::detachVisBuffer (VisBuffer & vb)
    2728             : {
    2729           1 :     if (!vbStack_p.empty ()) {
    2730           1 :         if (vbStack_p.top () == & vb) {
    2731           1 :             vbStack_p.pop ();
    2732           1 :             if (!vbStack_p.empty ()) {
    2733           0 :                 vbStack_p.top ()->invalidate ();
    2734             :             }
    2735             :         } else {
    2736           0 :             throw (AipsError ("ROVisIter::detachVisBuffer - attempt to detach "
    2737           0 :                             "buffer that is not the last one attached"));
    2738             :         }
    2739             :     }
    2740           1 : }
    2741             : 
    2742             : Int
    2743           0 : VisibilityIteratorReadImpl::numberAnt ()
    2744             : {
    2745           0 :     return msColumns ().antenna ().nrow (); // for single (sub)array only..
    2746             : }
    2747             : 
    2748             : Int
    2749           0 : VisibilityIteratorReadImpl::numberSpw ()
    2750             : {
    2751           0 :     return msColumns ().spectralWindow ().nrow ();
    2752             : }
    2753             : 
    2754             : Int
    2755           0 : VisibilityIteratorReadImpl::numberDDId ()
    2756             : {
    2757           0 :     return msColumns ().dataDescription ().nrow ();
    2758             : }
    2759             : 
    2760             : Int
    2761           0 : VisibilityIteratorReadImpl::numberPol ()
    2762             : {
    2763           0 :     return msColumns ().polarization ().nrow ();
    2764             : }
    2765             : 
    2766             : Int
    2767           0 : VisibilityIteratorReadImpl::numberCoh ()
    2768             : {
    2769           0 :     Int numcoh = 0;
    2770           0 :     for (uInt k = 0; k < uInt (msIter_p.numMS ()) ; ++k) {
    2771           0 :         numcoh += msIter_p.ms (k).nrow ();
    2772             :     }
    2773           0 :     return numcoh;
    2774             : 
    2775             : }
    2776             : 
    2777             : template<class T>
    2778             : void
    2779         801 : VisibilityIteratorReadImpl::getColScalar (const ScalarColumn<T> &column, Vector<T> &array, Bool resize) const
    2780             : {
    2781         801 :     column.getColumnCells (selRows_p, array, resize);
    2782         801 :     return;
    2783             : }
    2784             : 
    2785             : void
    2786         200 : VisibilityIteratorReadImpl::getCol (const ScalarColumn<Bool> &column, Vector<Bool> &array, Bool resize) const
    2787             : {
    2788         200 :     getColScalar<Bool>(column, array, resize);
    2789         200 : }
    2790             : 
    2791             : void
    2792         400 : VisibilityIteratorReadImpl::getCol (const ScalarColumn<Int> &column, Vector<Int> &array, Bool resize) const
    2793             : {
    2794         400 :     getColScalar<Int>(column, array, resize);
    2795         400 : }
    2796             : 
    2797             : void
    2798         201 : VisibilityIteratorReadImpl::getCol (const ScalarColumn<Double> &column, Vector<Double> &array, Bool resize) const
    2799             : {
    2800         201 :     getColScalar<Double>(column, array, resize);
    2801         201 : }
    2802             : 
    2803             : void
    2804         460 : VisibilityIteratorReadImpl::getCol (const ArrayColumn<Bool> &column, Array<Bool> &array, Bool resize) const
    2805             : {
    2806         460 :     column.getColumnCells (selRows_p, array, resize);
    2807         460 : }
    2808             : 
    2809         200 : void VisibilityIteratorReadImpl::getCol (const ArrayColumn<Float> &column, Array<Float> &array, Bool resize) const
    2810             : {
    2811         200 :     column.getColumnCells (selRows_p, array, resize);
    2812         200 : }
    2813             : 
    2814             : template<class T>
    2815             : void
    2816         200 : VisibilityIteratorReadImpl::getColArray (const ArrayColumn<T> &column, Array<T> &array, Bool resize) const
    2817             : {
    2818         200 :     column.getColumnCells (selRows_p, array, resize);
    2819         200 :     return;
    2820             : }
    2821             : 
    2822             : void
    2823           0 : VisibilityIteratorReadImpl::getCol (const ArrayColumn<Double> &column, Array<Double> &array, Bool resize) const
    2824             : {
    2825           0 :     column.getColumnCells (selRows_p, array, resize);
    2826           0 : }
    2827             : 
    2828             : void
    2829         266 : VisibilityIteratorReadImpl::getCol (const ArrayColumn<Complex> &column, Array<Complex> &array, Bool resize) const
    2830             : {
    2831         266 :     column.getColumnCells (selRows_p, array, resize);
    2832         266 : }
    2833             : 
    2834             : void
    2835           0 : VisibilityIteratorReadImpl::getCol (const ArrayColumn<Bool> &column, const Slicer & slicer, Array<Bool> &array, Bool resize) const
    2836             : {
    2837           0 :     column.getColumnCells (selRows_p, slicer, array, resize);
    2838           0 : }
    2839             : 
    2840             : void
    2841           0 : VisibilityIteratorReadImpl::getCol (const ArrayColumn<Float> &column, const Slicer & slicer, Array<Float> &array, Bool resize) const
    2842             : {
    2843           0 :     column.getColumnCells (selRows_p, slicer, array, resize);
    2844           0 : }
    2845             : 
    2846             : void
    2847           0 : VisibilityIteratorReadImpl::getCol (const ArrayColumn<Complex> &column, const Slicer & slicer, Array<Complex> &array, Bool resize) const
    2848             : {
    2849           0 :     column.getColumnCells (selRows_p, slicer, array, resize);
    2850           0 : }
    2851             : 
    2852             : const Table
    2853          35 : VisibilityIteratorReadImpl::attachTable () const
    2854             : {
    2855          35 :     return msIter_p.table ();
    2856             : }
    2857             : 
    2858             : void
    2859           0 : VisibilityIteratorReadImpl::slurp () const
    2860             : {
    2861             :     /* Set the table data manager (ISM and SSM) cache size to the full column size, for
    2862             :        the columns ANTENNA1, ANTENNA2, FEED1, FEED2, TIME, INTERVAL, FLAG_ROW, SCAN_NUMBER and UVW
    2863             :      */
    2864           0 :     Record dmInfo (msIter_p.ms ().dataManagerInfo ());
    2865             : 
    2866             :     //  cout << "nfields = " << dmInfo.nfields () << endl;
    2867             :     //  cout << "dminfo = " << dmInfo.description () << endl;
    2868           0 :     RecordDesc desc = dmInfo.description ();
    2869           0 :     for (unsigned i = 0; i < dmInfo.nfields (); i++) {
    2870             :         //      cout << "field " << i << " isSubRecord = " << desc.isSubRecord (i) << endl;
    2871             :         //      cout << "field " << i << " isArray = " << desc.isArray (i) << endl;
    2872           0 :         if (desc.isSubRecord (i)) {
    2873             : 
    2874           0 :             Record sub = dmInfo.subRecord (i);
    2875             : 
    2876             :             //          cout << "sub = " << sub << endl;
    2877           0 :             if (sub.fieldNumber ("NAME") >= 0 &&
    2878           0 :                     sub.fieldNumber ("TYPE") >= 0 &&
    2879           0 :                     sub.fieldNumber ("COLUMNS") >= 0 &&
    2880           0 :                     sub.type (sub.fieldNumber ("NAME")) == TpString &&
    2881           0 :                     sub.type (sub.fieldNumber ("TYPE")) == TpString &&
    2882           0 :                     sub.type (sub.fieldNumber ("COLUMNS")) == TpArrayString) {
    2883             : 
    2884           0 :                 Array<String> columns;
    2885           0 :                 dmInfo.subRecord (i).get ("COLUMNS", columns);
    2886             : 
    2887           0 :                 bool match = false;
    2888           0 :                 for (unsigned j = 0; j < columns.nelements (); j++) {
    2889           0 :                     String column = columns (IPosition (1, j));
    2890           0 :                     match |= (column == MS::columnName (MS::ANTENNA1) ||
    2891           0 :                               column == MS::columnName (MS::ANTENNA2) ||
    2892           0 :                               column == MS::columnName (MS::FEED1) ||
    2893           0 :                               column == MS::columnName (MS::FEED2) ||
    2894           0 :                               column == MS::columnName (MS::TIME) ||
    2895           0 :                               column == MS::columnName (MS::INTERVAL) ||
    2896           0 :                               column == MS::columnName (MS::FLAG_ROW) ||
    2897           0 :                               column == MS::columnName (MS::SCAN_NUMBER) ||
    2898           0 :                               column == MS::columnName (MS::UVW));
    2899           0 :                 }
    2900             :                 //              cout << "columns = " << columns << endl;
    2901             : 
    2902           0 :                 if (match) {
    2903             : 
    2904           0 :                     String dm_name;
    2905           0 :                     dmInfo.subRecord (i).get ("NAME", dm_name);
    2906             :                     // cout << "dm_name = " << dm_name << endl;
    2907             : 
    2908           0 :                     String dm_type;
    2909           0 :                     dmInfo.subRecord (i).get ("TYPE", dm_type);
    2910             :                     // cout << "dm_type = " << dm_type << endl;
    2911             : 
    2912           0 :                     Bool can_exceed_nr_buckets = false;
    2913           0 :                     uInt num_buckets = msIter_p.ms ().nrow ();
    2914             :                     // One bucket is at least one row, so this is enough
    2915             : 
    2916           0 :                     if (dm_type == "IncrementalStMan") {
    2917           0 :                         ROIncrementalStManAccessor acc (msIter_p.ms (), dm_name);
    2918           0 :                         acc.setCacheSize (num_buckets, can_exceed_nr_buckets);
    2919           0 :                     } else if (dm_type == "StandardStMan") {
    2920           0 :                         ROStandardStManAccessor acc (msIter_p.ms (), dm_name);
    2921           0 :                         acc.setCacheSize (num_buckets, can_exceed_nr_buckets);
    2922           0 :                     }
    2923             :                     /* These are the only storage managers which use the BucketCache
    2924             :                      (and therefore are slow for random access and small cache sizes)
    2925             :                      */
    2926           0 :                 } else {
    2927           0 :                     String dm_name;
    2928           0 :                     dmInfo.subRecord (i).get ("NAME", dm_name);
    2929             :                     //cout << "IGNORING...." << dm_name << endl;
    2930           0 :                 }
    2931           0 :             } else {
    2932           0 :                 cerr << "Data manager info has unexpected shape! " << sub << endl;
    2933             :             }
    2934           0 :         }
    2935             :     }
    2936           0 :     return;
    2937           0 : }
    2938             : 
    2939           2 : VisibilityIteratorWriteImpl::VisibilityIteratorWriteImpl (VisibilityIterator * vi)
    2940           2 : : vi_p (vi)
    2941             : {
    2942           2 :         useCustomTileShape_p = useCustomTileShape();
    2943           2 : }
    2944             : 
    2945           0 : VisibilityIteratorWriteImpl::VisibilityIteratorWriteImpl (const VisibilityIteratorWriteImpl & other)
    2946             : {
    2947           0 :     operator=(other);
    2948           0 :     useCustomTileShape_p = useCustomTileShape();
    2949           0 : }
    2950             : 
    2951           2 : VisibilityIteratorWriteImpl::~VisibilityIteratorWriteImpl ()
    2952             : {
    2953           2 : }
    2954             : 
    2955             : VisibilityIteratorWriteImpl *
    2956           0 : VisibilityIteratorWriteImpl::clone (VisibilityIterator * vi) const
    2957             : {
    2958             :     // Return a clone of this object but ensure it's attached to the proper
    2959             :     // VI container object.
    2960             : 
    2961           0 :     VisibilityIteratorWriteImpl * viwi = new VisibilityIteratorWriteImpl (* this);
    2962             : 
    2963           0 :     viwi->vi_p = vi;
    2964             : 
    2965           0 :     return viwi;
    2966             : }
    2967             : 
    2968             : void
    2969          31 : VisibilityIteratorWriteImpl::attachColumns (const Table & t)
    2970             : {
    2971          31 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    2972             : 
    2973          31 :     readImpl->attachColumns (t); // Let the read impl handle it's tables
    2974             : 
    2975          31 :     const ColumnDescSet & cds = t.tableDesc ().columnDescSet ();
    2976             : 
    2977          31 :     if (cds.isDefined (MS::columnName (MS::DATA))) {
    2978          31 :         columns_p.vis_p.attach (t, MS::columnName (MS::DATA));
    2979             :     }
    2980             : 
    2981          31 :     if (cds.isDefined (MS::columnName (MS::FLOAT_DATA))) {
    2982           0 :         readImpl->floatDataFound_p = true;
    2983           0 :         columns_p.floatVis_p.attach (t, MS::columnName (MS::FLOAT_DATA));
    2984             :     } else {
    2985          31 :         readImpl->floatDataFound_p = false;
    2986             :     }
    2987             : 
    2988          31 :     if (cds.isDefined ("MODEL_DATA")) {
    2989          31 :         columns_p.modelVis_p.attach (t, "MODEL_DATA");
    2990             :     }
    2991             : 
    2992          31 :     if (cds.isDefined ("CORRECTED_DATA")) {
    2993          31 :         columns_p.corrVis_p.attach (t, "CORRECTED_DATA");
    2994             :     }
    2995             : 
    2996          31 :     columns_p.weight_p.attach (t, MS::columnName (MS::WEIGHT));
    2997             : 
    2998          31 :     if (cds.isDefined ("WEIGHT_SPECTRUM")) {
    2999          27 :         columns_p.weightSpectrum_p.attach (t, "WEIGHT_SPECTRUM");
    3000             :     }
    3001             : 
    3002          31 :     columns_p.sigma_p.attach (t, MS::columnName (MS::SIGMA));
    3003             : 
    3004          31 :     columns_p.flag_p.attach (t, MS::columnName (MS::FLAG));
    3005             : 
    3006          31 :     columns_p.flagRow_p.attach (t, MS::columnName (MS::FLAG_ROW));
    3007             : 
    3008          31 :     if (cds.isDefined ("FLAG_CATEGORY")) {
    3009          31 :         columns_p.flagCategory_p.attach (t, MS::columnName (MS::FLAG_CATEGORY));
    3010             :     }
    3011          31 : }
    3012             : 
    3013             : VisibilityIteratorReadImpl *
    3014         307 : VisibilityIteratorWriteImpl::getReadImpl ()
    3015             : {
    3016         307 :     return vi_p->getReadImpl();
    3017             : }
    3018             : 
    3019             : void
    3020           0 : VisibilityIteratorWriteImpl::setFlag (const Matrix<Bool> & flag)
    3021             : {
    3022             :     // use same value for all polarizations
    3023             : 
    3024           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3025             : 
    3026           0 :     readImpl->cache_p.flagCube_p.resize (readImpl->nPol_p, readImpl->channelGroupSize_p,
    3027           0 :                                          readImpl->curNumRow_p);
    3028             : 
    3029             :     Bool deleteIt;
    3030           0 :     Bool * p = readImpl->cache_p.flagCube_p.getStorage (deleteIt);
    3031           0 :     const Bool * pflag = flag.getStorage (deleteIt);
    3032           0 :     if (Int (flag.nrow ()) != readImpl->channelGroupSize_p) {
    3033           0 :         throw (AipsError ("VisIter::setFlag (flag) - inconsistent number of channels"));
    3034             :     }
    3035             : 
    3036           0 :     for (uInt row = 0; row < readImpl->curNumRow_p; row++) {
    3037           0 :         for (Int chn = 0; chn < readImpl->channelGroupSize_p; chn++) {
    3038           0 :             for (Int pol = 0; pol < readImpl->nPol_p; pol++) {
    3039           0 :                 *p++ = *pflag;
    3040             :             }
    3041           0 :             pflag++;
    3042             :         }
    3043             :     }
    3044             : 
    3045           0 :     if (readImpl->useSlicer_p) {
    3046           0 :         putCol (columns_p.flag_p, readImpl->slicer_p, readImpl->cache_p.flagCube_p);
    3047             :     } else {
    3048           0 :         putCol (columns_p.flag_p, readImpl->cache_p.flagCube_p);
    3049             :     }
    3050           0 : }
    3051             : 
    3052             : void
    3053           0 : VisibilityIteratorWriteImpl::setFlag (const Cube<Bool> & flags)
    3054             : {
    3055           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3056             : 
    3057           0 :     if (readImpl->useSlicer_p) {
    3058           0 :         putCol (columns_p.flag_p, readImpl->slicer_p, flags);
    3059             :     } else {
    3060           0 :         putCol (columns_p.flag_p, flags);
    3061             :     }
    3062           0 : }
    3063             : 
    3064             : void
    3065           0 : VisibilityIteratorWriteImpl::setFlagCategory(const Array<Bool>& flagCategory)
    3066             : {
    3067           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3068             : 
    3069           0 :     if (readImpl->useSlicer_p){
    3070           0 :         putCol(columns_p.flagCategory_p, readImpl->slicer_p, flagCategory);
    3071             :     }
    3072             :     else{
    3073           0 :         putCol(columns_p.flagCategory_p, flagCategory);
    3074             :     }
    3075           0 : }
    3076             : 
    3077             : 
    3078             : void
    3079           0 : VisibilityIteratorWriteImpl::setFlagRow (const Vector<Bool> & rowflags)
    3080             : {
    3081           0 :     putCol (columns_p.flagRow_p, rowflags);
    3082           0 : }
    3083             : 
    3084             : void
    3085           0 : VisibilityIteratorWriteImpl::setVis (const Matrix<CStokesVector> & vis,
    3086             :         DataColumn whichOne)
    3087             : {
    3088             :     // two problems: 1. channel selection -> we can only write to reference
    3089             :     // MS with 'processed' channels
    3090             :     //               2. polarization: there could be 1, 2 or 4 in the
    3091             :     // original data, predict () always gives us 4. We save what was there
    3092             :     // originally.
    3093             : 
    3094             :     //  if (!preselected_p) {
    3095             :     //    throw (AipsError ("VisIter::setVis (vis) - cannot change original data"));
    3096             :     //  }
    3097             : 
    3098           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3099             : 
    3100           0 :     if (Int (vis.nrow ()) != readImpl->channelGroupSize_p) {
    3101           0 :         throw (AipsError ("VisIter::setVis (vis) - inconsistent number of channels"));
    3102             :     }
    3103             :     // we need to reform the vis matrix to a cube before we can use
    3104             :     // putColumn to a Matrix column
    3105           0 :     readImpl->cache_p.visCube_p.resize (readImpl->nPol_p, readImpl->channelGroupSize_p, readImpl->curNumRow_p);
    3106             :     Bool deleteIt;
    3107           0 :     Complex * p = readImpl->cache_p.visCube_p.getStorage (deleteIt);
    3108           0 :     for (uInt row = 0; row < readImpl->curNumRow_p; row++) {
    3109           0 :         for (Int chn = 0; chn < readImpl->channelGroupSize_p; chn++) {
    3110           0 :             const CStokesVector & v = vis (chn, row);
    3111           0 :             switch (readImpl->nPol_p) {
    3112           0 :             case 4:
    3113           0 :                 *p++ = v (0);
    3114           0 :                 *p++ = v (1);
    3115           0 :                 *p++ = v (2);
    3116           0 :                 *p++ = v (3);
    3117           0 :                 break;
    3118           0 :             case 2:
    3119           0 :                 *p++ = v (0);
    3120           0 :                 *p++ = v (3);
    3121           0 :                 break;
    3122           0 :             case 1:
    3123           0 :                 *p++ = (v (0) + v (3)) / 2;
    3124           0 :                 break;
    3125             :             }
    3126             :         }
    3127             :     }
    3128           0 :     if (readImpl->useSlicer_p) {
    3129           0 :         putDataColumn (whichOne, readImpl->slicer_p, readImpl->cache_p.visCube_p);
    3130             :     } else {
    3131           0 :         putDataColumn (whichOne, readImpl->cache_p.visCube_p);
    3132             :     }
    3133           0 : }
    3134             : 
    3135             : void
    3136          60 : VisibilityIteratorWriteImpl::setVisAndFlag (const Cube<Complex> & vis,
    3137             :                                             const Cube<Bool> & flag,
    3138             :                                             DataColumn whichOne)
    3139             : {
    3140          60 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3141             : 
    3142          60 :     if (readImpl->useSlicer_p) {
    3143           0 :         putDataColumn (whichOne, readImpl->slicer_p, vis);
    3144             :     } else {
    3145          60 :         putDataColumn (whichOne, vis);
    3146             :     }
    3147          60 :     if (readImpl->useSlicer_p) {
    3148           0 :         putCol (columns_p.flag_p, readImpl->slicer_p, flag);
    3149             :     } else {
    3150          60 :         putCol (columns_p.flag_p, flag);
    3151             :     }
    3152             : 
    3153          60 : }
    3154             : 
    3155             : void
    3156          12 : VisibilityIteratorWriteImpl::setVis (const Cube<Complex> & vis, DataColumn whichOne)
    3157             : {
    3158          12 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3159             : 
    3160          12 :     if (readImpl->useSlicer_p) {
    3161           0 :         putDataColumn (whichOne, readImpl->slicer_p, vis);
    3162             :     } else {
    3163          12 :         putDataColumn (whichOne, vis);
    3164             :     }
    3165          12 : }
    3166             : 
    3167             : void
    3168           0 : VisibilityIteratorWriteImpl::setWeight (const Vector<Float> & weight)
    3169             : {
    3170           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3171             : 
    3172             :     // No polarization dependence for now
    3173           0 :     Matrix<Float> polWeight;
    3174           0 :     readImpl->getCol (readImpl->columns_p.weight_p, polWeight);
    3175           0 :     for (Int i = 0; i < readImpl->nPol_p; i++) {
    3176           0 :         Vector<Float> r = polWeight.row (i);
    3177           0 :         r = weight;
    3178           0 :     }
    3179           0 :     putCol (columns_p.weight_p, polWeight);
    3180           0 : }
    3181             : 
    3182             : void
    3183           0 : VisibilityIteratorWriteImpl::setWeightMat (const Matrix<Float> & weightMat)
    3184             : {
    3185           0 :     putCol (columns_p.weight_p, weightMat);
    3186           0 : }
    3187             : 
    3188             : void
    3189           0 : VisibilityIteratorWriteImpl::setWeightSpectrum (const Cube<Float> & weightSpectrum)
    3190             : {
    3191           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3192             : 
    3193           0 :     if (! readImpl->columns_p.weightSpectrum_p.isNull ()) {
    3194           0 :         putCol (columns_p.weightSpectrum_p, weightSpectrum);
    3195             :     }
    3196           0 : }
    3197             : 
    3198             : void
    3199           0 : VisibilityIteratorWriteImpl::setSigma (const Vector<Float> & sigma)
    3200             : {
    3201           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3202             : 
    3203           0 :     Matrix<Float> sigmat;
    3204           0 :     readImpl->getCol (readImpl->columns_p.sigma_p, sigmat);
    3205           0 :     for (Int i = 0; i < readImpl->nPol_p; i++) {
    3206           0 :         Vector<Float> r = sigmat.row (i);
    3207           0 :         r = sigma;
    3208           0 :     }
    3209           0 :     putCol (columns_p.sigma_p, sigmat);
    3210           0 : }
    3211             : 
    3212             : void
    3213           0 : VisibilityIteratorWriteImpl::setSigmaMat (const Matrix<Float> & sigMat)
    3214             : {
    3215           0 :     putCol (columns_p.sigma_p, sigMat);
    3216           0 : }
    3217             : 
    3218             : 
    3219             : void
    3220           0 : VisibilityIteratorWriteImpl::putDataColumn (DataColumn whichOne,
    3221             :                                            const Slicer & slicer,
    3222             :                                            const Cube<Complex> & data)
    3223             : {
    3224             :     // Set the visibility (observed, model or corrected);
    3225             :     // deal with DATA and FLOAT_DATA seamlessly for observed data.
    3226             : 
    3227           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3228             : 
    3229           0 :     switch (whichOne) {
    3230             : 
    3231           0 :     case ROVisibilityIterator::Observed:
    3232           0 :         if (readImpl->floatDataFound_p) {
    3233           0 :             Cube<Float> dataFloat = real (data);
    3234           0 :             putCol (columns_p.floatVis_p, slicer, dataFloat);
    3235           0 :         } else {
    3236           0 :             putCol (columns_p.vis_p, slicer, data);
    3237             :         }
    3238           0 :         break;
    3239             : 
    3240           0 :     case ROVisibilityIterator::Corrected:
    3241           0 :         putCol (columns_p.corrVis_p, slicer, data);
    3242           0 :         break;
    3243             : 
    3244           0 :     case ROVisibilityIterator::Model:
    3245           0 :         putCol (columns_p.modelVis_p, slicer, data);
    3246           0 :         break;
    3247             : 
    3248           0 :     default:
    3249           0 :         Assert (false);
    3250             :     }
    3251           0 : }
    3252             : 
    3253             : void
    3254          72 : VisibilityIteratorWriteImpl::putDataColumn (DataColumn whichOne,
    3255             :         const Cube<Complex> & data)
    3256             : {
    3257             :     // Set the visibility (observed, model or corrected);
    3258             :     // deal with DATA and FLOAT_DATA seamlessly for observed data.
    3259             : 
    3260          72 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3261             : 
    3262          72 :     switch (whichOne) {
    3263             : 
    3264           0 :     case ROVisibilityIterator::Observed:
    3265           0 :         if (readImpl->floatDataFound_p) {
    3266           0 :             Cube<Float> dataFloat = real (data);
    3267           0 :             if (useCustomTileShape_p) setTileShape(readImpl->selRows_p,columns_p.floatVis_p,dataFloat.shape());
    3268           0 :             putCol (columns_p.floatVis_p, dataFloat);
    3269           0 :         } else {
    3270           0 :                 if (useCustomTileShape_p) setTileShape(readImpl->selRows_p,columns_p.vis_p,data.shape());
    3271           0 :             putCol (columns_p.vis_p, data);
    3272             :         }
    3273           0 :         break;
    3274             : 
    3275          66 :     case ROVisibilityIterator::Corrected:
    3276          66 :         if (useCustomTileShape_p) setTileShape(readImpl->selRows_p,columns_p.corrVis_p,data.shape());
    3277          66 :         putCol (columns_p.corrVis_p, data);
    3278          66 :         break;
    3279             : 
    3280           6 :     case ROVisibilityIterator::Model:
    3281           6 :         if (useCustomTileShape_p) setTileShape(readImpl->selRows_p,columns_p.modelVis_p,data.shape());
    3282           6 :         putCol (columns_p.modelVis_p, data);
    3283           6 :         break;
    3284             : 
    3285           0 :     default:
    3286           0 :         Assert (false);
    3287             :     }
    3288          72 : }
    3289             : 
    3290             : void
    3291           0 : VisibilityIteratorWriteImpl::putColScalar (ScalarColumn<Bool> &column, const Vector<Bool> &array)
    3292             : {
    3293           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3294             : 
    3295           0 :     column.putColumnCells (readImpl->selRows_p, array);
    3296           0 :     return;
    3297             : }
    3298             : 
    3299             : void
    3300           0 : VisibilityIteratorWriteImpl::putCol (ScalarColumn<Bool> &column, const Vector<Bool> &array)
    3301             : {
    3302           0 :     putColScalar (column, array);
    3303           0 : }
    3304             : 
    3305             : void
    3306          60 : VisibilityIteratorWriteImpl::putCol (ArrayColumn<Bool> &column, const Array<Bool> &array)
    3307             : {
    3308          60 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3309             : 
    3310          60 :     column.putColumnCells (readImpl->selRows_p, array);
    3311          60 : }
    3312             : 
    3313             : void
    3314           0 : VisibilityIteratorWriteImpl::putCol (ArrayColumn<Float> &column, const Array<Float> &array)
    3315             : {
    3316           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3317             : 
    3318           0 :     column.putColumnCells (readImpl->selRows_p, array);
    3319           0 : }
    3320             : 
    3321             : void
    3322          72 : VisibilityIteratorWriteImpl::putCol (ArrayColumn<Complex> &column, const Array<Complex> &array)
    3323             : {
    3324          72 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3325             : 
    3326          72 :     column.putColumnCells (readImpl->selRows_p, array);
    3327          72 : }
    3328             : 
    3329             : void
    3330           0 : VisibilityIteratorWriteImpl::putCol (ArrayColumn<Bool> &column,
    3331             :                                     const Slicer & slicer,
    3332             :                                     const Array<Bool> &array)
    3333             : {
    3334           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3335             : 
    3336           0 :     column.putColumnCells (readImpl->selRows_p, slicer, array);
    3337           0 : }
    3338             : 
    3339             : void
    3340           0 : VisibilityIteratorWriteImpl::putCol (ArrayColumn<Float> &column,
    3341             :                                     const Slicer & slicer,
    3342             :                                     const Array<Float> &array)
    3343             : {
    3344           0 :     VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3345             : 
    3346           0 :     column.putColumnCells (readImpl->selRows_p, slicer, array);
    3347           0 : }
    3348             : 
    3349             : void
    3350           0 : VisibilityIteratorWriteImpl::putCol (ArrayColumn<Complex> &column,
    3351             :                                     const Slicer & slicer,
    3352             :                                     const Array<Complex> &array)
    3353             : {
    3354           0 :      VisibilityIteratorReadImpl * readImpl = getReadImpl();
    3355             : 
    3356           0 :    column.putColumnCells (readImpl->selRows_p, slicer, array);
    3357           0 : }
    3358             : 
    3359           0 : template <class T> void VisibilityIteratorWriteImpl::setTileShape(        RefRows &rowRef,
    3360             :                                                                                                                                         ArrayColumn<T> &outputDataCol,
    3361             :                                                                                                                                         const IPosition &arrayShape)
    3362             : {
    3363           0 :         size_t nCorr = arrayShape(0);
    3364           0 :         size_t nChan = arrayShape(1);
    3365           0 :         ssize_t nRows = 1048576 / (sizeof(T)*nCorr*nChan);
    3366           0 :         IPosition outputPlaneShape(2,nCorr,nChan);
    3367           0 :         IPosition tileShape(3,nCorr,nChan,nRows);
    3368           0 :         outputDataCol.setShape(rowRef.firstRow(),outputPlaneShape,tileShape);
    3369             : 
    3370           0 :         return;
    3371           0 : }
    3372             : 
    3373           2 : Bool VisibilityIteratorWriteImpl::useCustomTileShape()
    3374             : {
    3375           2 :         Bool ret = false;
    3376           2 :         String rank = EnvironmentVariable::get("OMPI_COMM_WORLD_RANK");
    3377           2 :         if (!rank.empty())
    3378             :         {
    3379           0 :                 ret = true;
    3380             :         }
    3381             : 
    3382           2 :         return ret;
    3383           2 : }
    3384             : 
    3385             : void
    3386           0 : VisibilityIteratorWriteImpl::putModel(const RecordInterface& rec, Bool iscomponentlist, Bool incremental)
    3387             : {
    3388             : 
    3389             :   /*
    3390             :   Vector<Int> fields = getReadImpl()->msColumns().fieldId().getColumn();
    3391             :   const Int option = Sort::HeapSort | Sort::NoDuplicates;
    3392             :   const Sort::Order order = Sort::Ascending;
    3393             : 
    3394             :   Int nfields = GenSort<Int>::sort (fields, order, option);
    3395             : 
    3396             :   // Make sure  we have the right size
    3397             : 
    3398             :   fields.resize(nfields, true);
    3399             :   */
    3400           0 :   Matrix<Int>  combiIndex;
    3401           0 :   MSUtil::getIndexCombination(getReadImpl()->msColumns(), combiIndex);
    3402           0 :   Int msid = getReadImpl()->msId();
    3403             : 
    3404           0 :   Vector<Int> spws =  getReadImpl()->msChannels_p.spw_p[msid];
    3405           0 :   Vector<Int> starts = getReadImpl()->msChannels_p.start_p[msid];
    3406           0 :   Vector<Int> nchan = getReadImpl()->msChannels_p.width_p[msid];
    3407           0 :   Vector<Int> incr = getReadImpl()->msChannels_p.inc_p[msid];
    3408           0 :   Matrix<Int> chansel(spws.nelements(),4);
    3409           0 :   chansel.column(0)=spws;
    3410           0 :   chansel.column(1)=starts;
    3411           0 :   chansel.column(2)=nchan;
    3412           0 :   chansel.column(3)=incr;
    3413             : 
    3414           0 :   CountedPtr<VisModelDataI> visModelData = VisModelDataI::create();
    3415             : 
    3416             :   //visModelData->putModelI (getReadImpl()->ms (), rec, fields, spws, starts, nchan, incr,
    3417             :   //                           iscomponentlist, incremental);
    3418             : 
    3419             :   //version 2.0 to keep track of scan and state_id selection 
    3420           0 :   visModelData->putModelI (getReadImpl()->ms (), rec, combiIndex, chansel, iscomponentlist, incremental);
    3421             :   
    3422           0 : }
    3423             : 
    3424             : 
    3425             : void
    3426           0 : VisibilityIteratorWriteImpl::writeBack (VisBuffer * vb)
    3427             : {
    3428           0 :     if (backWriters_p.empty ()) {
    3429           0 :         initializeBackWriters ();
    3430             :     }
    3431             : 
    3432           0 :     VbDirtyComponents dirtyComponents = vb->dirtyComponentsGet ();
    3433             : 
    3434           0 :     for (VbDirtyComponents::const_iterator dirtyComponent = dirtyComponents.begin ();
    3435           0 :          dirtyComponent != dirtyComponents.end ();
    3436           0 :          dirtyComponent ++) {
    3437             : 
    3438           0 :         ThrowIf (backWriters_p.find (* dirtyComponent) == backWriters_p.end (),
    3439             :                  String::format ("No writer defined for VisBuffer component %d", * dirtyComponent));
    3440           0 :         BackWriter * backWriter = backWriters_p [ * dirtyComponent];
    3441             : 
    3442             :         try {
    3443           0 :             (* backWriter) (this, vb);
    3444           0 :         } catch (AipsError & e) {
    3445           0 :             Rethrow (e, String::format ("Error while writing back VisBuffer component %d", * dirtyComponent));
    3446           0 :         }
    3447             :     }
    3448           0 : }
    3449             : 
    3450             : void
    3451           0 : VisibilityIteratorWriteImpl::initializeBackWriters ()
    3452             : {
    3453           0 :     backWriters_p [VisBufferComponents::Flag] =
    3454           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setFlag, & VisBuffer::flag);
    3455           0 :     backWriters_p [VisBufferComponents::FlagCube] =
    3456           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setFlag, & VisBuffer::flagCube);
    3457           0 :     backWriters_p [VisBufferComponents::FlagRow] =
    3458           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setFlagRow, & VisBuffer::flagRow);
    3459           0 :     backWriters_p [VisBufferComponents::FlagCategory] =
    3460           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setFlagCategory, & VisBuffer::flagCategory);
    3461           0 :     backWriters_p [VisBufferComponents::Sigma] =
    3462           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setSigma, & VisBuffer::sigma);
    3463           0 :     backWriters_p [VisBufferComponents::SigmaMat] =
    3464           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setSigmaMat, & VisBuffer::sigmaMat);
    3465           0 :     backWriters_p [VisBufferComponents::Weight] =
    3466           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setWeight, & VisBuffer::weight);
    3467           0 :     backWriters_p [VisBufferComponents::WeightMat] =
    3468           0 :         makeBackWriter (& VisibilityIteratorWriteImpl::setWeightMat, & VisBuffer::weightMat);
    3469             : 
    3470             :     // Now do the visibilities.  These are slightly different since the setter requires an
    3471             :     // enum value.
    3472             : 
    3473           0 :     backWriters_p [VisBufferComponents::Observed] =
    3474           0 :         makeBackWriter2 (& VisibilityIteratorWriteImpl::setVis, & VisBuffer::visibility,
    3475             :                          ROVisibilityIterator::Observed);
    3476           0 :     backWriters_p [VisBufferComponents::Corrected] =
    3477           0 :         makeBackWriter2 (& VisibilityIteratorWriteImpl::setVis, & VisBuffer::correctedVisibility,
    3478             :                          ROVisibilityIterator::Corrected);
    3479           0 :     backWriters_p [VisBufferComponents::Model] =
    3480           0 :         makeBackWriter2 (& VisibilityIteratorWriteImpl::setVis, & VisBuffer::modelVisibility,
    3481             :                          ROVisibilityIterator::Model);
    3482             : 
    3483           0 :     backWriters_p [VisBufferComponents::ObservedCube] =
    3484           0 :         makeBackWriter2 (& VisibilityIteratorWriteImpl::setVis, & VisBuffer::visCube,
    3485             :                          ROVisibilityIterator::Observed);
    3486           0 :     backWriters_p [VisBufferComponents::CorrectedCube] =
    3487           0 :         makeBackWriter2 (& VisibilityIteratorWriteImpl::setVis, & VisBuffer::correctedVisCube,
    3488             :                          ROVisibilityIterator::Corrected);
    3489           0 :     backWriters_p [VisBufferComponents::ModelCube] =
    3490           0 :         makeBackWriter2 (& VisibilityIteratorWriteImpl::setVis, & VisBuffer::modelVisCube,
    3491             :                          ROVisibilityIterator::Model);
    3492             : 
    3493           0 : }
    3494             : 
    3495             : VisibilityIteratorWriteImpl::Columns &
    3496           0 : VisibilityIteratorWriteImpl::Columns::operator= (const VisibilityIteratorWriteImpl::Columns & other)
    3497             : {
    3498           0 :     flag_p.reference (other.flag_p);
    3499           0 :     flagCategory_p.reference (other.flagCategory_p);
    3500           0 :     flagRow_p.reference (other.flagRow_p);
    3501           0 :     vis_p.reference (other.vis_p);
    3502           0 :     floatVis_p.reference (other.floatVis_p);
    3503           0 :     modelVis_p.reference (other.modelVis_p);
    3504           0 :     corrVis_p.reference (other.corrVis_p);
    3505           0 :     weight_p.reference (other.weight_p);
    3506           0 :     weightSpectrum_p.reference (other.weightSpectrum_p);
    3507           0 :     sigma_p.reference (other.sigma_p);
    3508             : 
    3509           0 :     return * this;
    3510             : }
    3511             : 
    3512             : 
    3513             : } //# NAMESPACE CASA - END
    3514             : 
    3515             : 
    3516             : 

Generated by: LCOV version 1.16