LCOV - code coverage report
Current view: top level - msvis/MSVis - VisSetUtil.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 18 409 4.4 %
Date: 2024-10-10 15:00:01 Functions: 2 12 16.7 %

          Line data    Source code
       1             : //# VisSetUtil.cc: VisSet Utilities
       2             : //# Copyright (C) 1996,1997,1998,1999,2001,2002
       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 adressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //#
      27             : //# $Id$
      28             : 
      29             : #include <casacore/casa/aips.h>
      30             : 
      31             : #include <casacore/casa/Arrays/Matrix.h>
      32             : #include <casacore/casa/Arrays/MatrixMath.h>
      33             : #include <casacore/casa/Arrays/ArrayMath.h>
      34             : #include <casacore/casa/Arrays/Cube.h>
      35             : #include <casacore/casa/BasicMath/Math.h>
      36             : #include <casacore/casa/BasicSL/Complex.h>
      37             : #include <casacore/casa/BasicSL/Constants.h>
      38             : #include <casacore/casa/Utilities/Assert.h>
      39             : 
      40             : #include <casacore/tables/Tables/ArrColDesc.h>
      41             : #include <casacore/tables/Tables/ScaColDesc.h>
      42             : #include <casacore/tables/Tables/TableCopy.h>
      43             : #include <casacore/tables/DataMan/TiledDataStMan.h>
      44             : #include <casacore/tables/DataMan/TiledShapeStMan.h>
      45             : #include <casacore/tables/DataMan/StandardStMan.h>
      46             : #include <casacore/tables/DataMan/TiledDataStManAccessor.h>
      47             : #include <casacore/tables/DataMan/CompressComplex.h>
      48             : #include <casacore/tables/DataMan/CompressFloat.h>
      49             : 
      50             : 
      51             : #include <casacore/ms/MeasurementSets/MSColumns.h>
      52             : #include <msvis/MSVis/VisModelDataI.h>
      53             : 
      54             : #include <msvis/MSVis/VisSet.h>
      55             : #include <msvis/MSVis/VisBuffer.h>
      56             : #include <msvis/MSVis/VisSetUtil.h>
      57             : 
      58             : #include <casacore/casa/Quanta/UnitMap.h>
      59             : #include <casacore/casa/Quanta/UnitVal.h>
      60             : #include <casacore/measures/Measures/Stokes.h>
      61             : #include <casacore/casa/Quanta/MVAngle.h>
      62             : 
      63             : #include <casacore/casa/Logging/LogIO.h>
      64             : 
      65             : #include <iostream>
      66             : 
      67             : using std::vector;
      68             : using std::pair;
      69             : 
      70             : using namespace casacore;
      71             : namespace casa { //# NAMESPACE CASA - BEGIN
      72             : 
      73             : // <summary> 
      74             : // </summary>
      75             : 
      76             : // <reviewed reviewer="" date="" tests="tMEGI" demos="">
      77             : 
      78             : // <prerequisite>
      79             : // </prerequisite>
      80             : //
      81             : // <etymology>
      82             : // </etymology>
      83             : //
      84             : // <synopsis> 
      85             : // </synopsis> 
      86             : //
      87             : // <example>
      88             : // <srcblock>
      89             : // </srcblock>
      90             : // </example>
      91             : //
      92             : // <motivation>
      93             : // </motivation>
      94             : //
      95             : // <todo asof="">
      96             : // </todo>
      97             : // Calculate sensitivity
      98           0 : void VisSetUtil::Sensitivity(VisSet &vs, Matrix<Double>& mssFreqSel,
      99             :                              Matrix<Int>& mssChanSel,
     100             :                              Quantity& pointsourcesens,
     101             :                              Double& relativesens,
     102             :                              Double& sumwt,
     103             :                              Double& effectiveBandwidth,
     104             :                              Double& effectiveIntegration,
     105             :                              Int& nBaselines,
     106             :                              Vector<Vector<Int> >& nData,
     107             :                              Vector<Vector<Double> >& sumwtChan,
     108             :                              Vector<Vector<Double> >& sumwtsqChan,
     109             :                              Vector<Vector<Double> >& sumInverseVarianceChan)
     110             : {
     111           0 :     ROVisIter& vi(vs.iter());
     112           0 :     VisSetUtil::Sensitivity(vi, mssFreqSel, mssChanSel, pointsourcesens, relativesens,
     113             :                             sumwt, effectiveBandwidth, effectiveIntegration, nBaselines,
     114             :                             nData, sumwtChan, sumwtsqChan, sumInverseVarianceChan);
     115             : 
     116           0 : }
     117           0 : void VisSetUtil::Sensitivity(ROVisIter &vi, Matrix<Double>& /*mssFreqSel*/,
     118             :                              Matrix<Int>& mssChanSel,
     119             :                              Quantity& pointsourcesens,
     120             :                              Double& relativesens,
     121             :                              Double& sumwt,
     122             :                              Double& effectiveBandwidth,
     123             :                              Double& effectiveIntegration,
     124             :                              Int& nBaselines,
     125             :                              Vector<Vector<Int> >& nData,
     126             :                              Vector<Vector<Double> >& sumwtChan,
     127             :                              Vector<Vector<Double> >& sumwtsqChan,
     128             :                              Vector<Vector<Double> >& sumInverseVarianceChan)
     129             : {
     130           0 :     LogIO os(LogOrigin("VisSetUtil", "Sensitivity()", WHERE));
     131             : 
     132           0 :     sumwt=0.0;
     133           0 :     Vector<Double> timeInterval, chanWidth;
     134           0 :     Double sumwtsq=0.0;
     135           0 :     Double sumInverseVariance=0.0;
     136             :     //  Vector<Vector<Double> > sumwtChan, sumwtsqChan, sumInverseVarianceChan;
     137           0 :     VisBuffer vb(vi);
     138           0 :     Int nd=0,totalRows=0,spw=0;
     139           0 :     nBaselines=0;
     140           0 :     effectiveBandwidth=effectiveIntegration=0.0;
     141           0 :     Vector<Double> bwList;
     142           0 :     bwList.resize(mssChanSel.shape()(0)); bwList=0.0;
     143             : 
     144           0 :     sumwtChan.resize(mssChanSel.shape()(0));
     145           0 :     sumwtsqChan.resize(mssChanSel.shape()(0));
     146           0 :     sumInverseVarianceChan.resize(mssChanSel.shape()(0));
     147           0 :     nData.resize(mssChanSel.shape()(0));
     148           0 :     for (spw=0; spw<mssChanSel.shape()(0); spw++)
     149             :     {
     150           0 :         Int nc=mssChanSel(spw,2)-mssChanSel(spw,1)+1;
     151           0 :         for (int c=0; c<nc; c++)
     152             :         {
     153           0 :             sumwtChan(spw).resize(nc); sumwtChan(spw)=0.0;
     154           0 :             sumwtsqChan(spw).resize(nc); sumwtsqChan(spw) = 0.0;
     155           0 :             sumInverseVarianceChan(spw).resize(nc); sumInverseVarianceChan(spw)=0.0;
     156           0 :             nData(spw).resize(nc); nData(spw)=0;
     157             :         }
     158             :     }
     159             :     // sumwtChan=0.0;
     160             :     // sumwtsqChan=0.0;
     161             :     // sumInverseVarianceChan=0.0;
     162             : 
     163             :     // Now iterate through the data
     164           0 :     Int nant=vi.msColumns().antenna().nrow();
     165           0 :     Matrix<Int> baselines(nant,nant); baselines=0;
     166           0 :     Vector<Int> a1,a2;
     167           0 :     Vector<Double> t0, spwIntegTime;
     168           0 :     t0.resize(mssChanSel.shape()(0));
     169           0 :     spwIntegTime.resize(mssChanSel.shape()(0));
     170           0 :     t0 = spwIntegTime = 0.0;
     171             : 
     172           0 :     for (vi.originChunks();vi.moreChunks();vi.nextChunk())
     173             :     {
     174           0 :         for (vi.origin();vi.more();vi++)
     175             :         {
     176           0 :             Int nRow=vb.nRow();
     177           0 :             vb.nChannel();
     178             :             Int spwIndex;
     179           0 :             spw=vb.spectralWindow();
     180           0 :             spwIndex=-1;
     181           0 :             for (Int i=0;i<mssChanSel.shape()(0); i++)
     182           0 :                 if (mssChanSel(i,0) == spw) {spwIndex=i; break;}
     183           0 :             if (spwIndex == -1)
     184             :                 os << "Internal error:  Could not locate the SPW index in the list of selected SPWs."
     185           0 :                 << LogIO::EXCEPTION;
     186             : 
     187           0 :             timeInterval.assign(vb.timeInterval());
     188           0 :             Vector<Bool> rowFlags=vb.flagRow();
     189           0 :             Matrix<Bool> flag = vb.flag();
     190             :             //    cerr << "SPW shape = " << vb.msColumns().spectralWindow().chanWidth().shape(spw) << " ";
     191           0 :             chanWidth.assign(vb.msColumns().spectralWindow().chanWidth().get(spw));
     192           0 :             a1.assign(vb.antenna1()); a2.assign(vb.antenna2());
     193             : 
     194           0 :             for (Int row=0; row<nRow; row++)
     195             :             {
     196             :                 // TBD: Should probably use weight() here, which updates with calibration
     197           0 :                 if (!rowFlags(row))
     198             :                 {
     199             :                     //            Double variance=square(vb.sigma()(row));
     200           0 :                     Double variance=1.0/(vb.weight()(row));
     201           0 :                     if (abs(vb.time()(row) - t0(spwIndex)) > timeInterval(row))
     202             :                     {
     203           0 :                         t0(spwIndex)=vb.time()(row);
     204           0 :                         spwIntegTime(spwIndex) += timeInterval(row);
     205             :                     }
     206           0 :                     totalRows++;
     207           0 :                     baselines(a1(row), a2(row))++;
     208           0 :                     for (Int chn=mssChanSel(spwIndex,1); chn<mssChanSel(spwIndex,2); chn+=mssChanSel(spwIndex,3))
     209             :                     {
     210           0 :                         if(!flag(chn,row)&&(variance>0.0))
     211             :                         {
     212           0 :                             sumwt+=vb.imagingWeight()(chn,row)*variance;
     213           0 :                             sumwtsq+=square(vb.imagingWeight()(chn,row)*variance);
     214             :                             //                    sumwtsq+=square(vb.imagingWeight()(chn,row));
     215           0 :                             sumInverseVariance+=1.0/variance;
     216             : 
     217           0 :                             sumwtChan(spwIndex)(chn) += vb.imagingWeight()(chn,row);
     218             :                             //sumwtsqChan(spwIndex)(chn)+=square(vb.imagingWeight()(chn,row))*variance;
     219           0 :                             sumwtsqChan(spwIndex)(chn)+=square(vb.imagingWeight()(chn,row));
     220             : 
     221           0 :                             bwList(spwIndex) += abs(chanWidth(chn));
     222           0 :                             (nData(spwIndex)(chn))++;
     223           0 :                             nd++;
     224             :                         }
     225             :                     }
     226             :                 }
     227             :             }
     228           0 :         }
     229             :     }
     230             : 
     231           0 :     if (totalRows == 0)
     232           0 :         os << "Cannot calculate sensitivty:  No unflagged rows found" << LogIO::EXCEPTION;
     233             : 
     234           0 :     for (uInt spwndx=0; spwndx<bwList.nelements(); spwndx++)
     235             :     {
     236             :         // cerr << spwndx << " " << bwList(spwndx) << " " << nData(spwndx) << endl;
     237             :         // cerr << spwndx << " " << spwIntegTime(spwndx) << " " << endl;
     238           0 :         spw=mssChanSel(spwndx,0); // Get the SPW ID;
     239           0 :         chanWidth.assign(vi.msColumns().spectralWindow().chanWidth().get(spw)); // Extract the list of chan widths
     240             : 
     241           0 :         Int nchan=nData(spwndx).nelements();
     242             :         // If a channel from the current SPW was used, uses its width
     243             :         // for effective bandwidth calculation.
     244           0 :         for (Int j=0; j<nchan; j++)
     245           0 :             if (nData(spwndx)(j) > 0)
     246           0 :                 effectiveBandwidth += abs(chanWidth(j));
     247           0 :         effectiveIntegration += spwIntegTime(spwndx)/bwList.nelements();
     248             :     }
     249             : 
     250           0 :     for (Int i=0; i<nant; i++)
     251           0 :         for (Int j=0; j<nant; j++)
     252           0 :             if (baselines(i,j) > 0)
     253           0 :                 nBaselines++;
     254             : 
     255             : 
     256           0 :     if(sumwt==0.0) {
     257             :         os << "Cannot calculate sensitivity: sum of weights is zero" << endl
     258           0 :                 << "Perhaps you need to weight the data" << LogIO::EXCEPTION;
     259             :     }
     260           0 :     if(sumInverseVariance==0.0) {
     261             :         os << "Cannot calculate sensitivity: sum of inverse variances is zero" << endl
     262           0 :                 << "Perhaps you need to weight the data" << LogIO::EXCEPTION;
     263             :     }
     264             : 
     265             :     // Double naturalsens=1.0/sqrt(sumInverseVariance);
     266             :     // pointsourcesens=Quantity(sqrt(sumwtsq)/sumwt, "Jy");
     267             :     // relativesens=sqrt(sumwtsq)/sumwt/naturalsens;
     268             : 
     269             :     //  cerr << "sumwt, sumwtsq, nd: " << sumwt << " " << sumwtsq << " " << nd << endl;
     270           0 :     relativesens=sqrt(nd*sumwtsq)/sumwt;
     271             :     //Double naturalsens=1.0/sqrt(sumInverseVariance);
     272           0 :     Double KB=1.3806488e-23;
     273           0 :     pointsourcesens=Quantity((10e26*2*KB*relativesens/sqrt(nBaselines*effectiveIntegration*effectiveBandwidth)), "Jy m^2/K");
     274             : 
     275             :     //  cerr << "Pt src. = " << pointsourcesens << " " << integTime << " " << bandWidth/totalRows << endl;
     276             :     //  cerr << baselines << endl;
     277           0 : }
     278           0 : void VisSetUtil::HanningSmooth(VisSet &vs, const String& dataCol, const Bool& doFlagAndWeight)
     279             : {
     280           0 :     VisIter& vi(vs.iter());
     281           0 :     VisSetUtil::HanningSmooth(vi, dataCol, doFlagAndWeight);
     282           0 : }
     283           0 : void VisSetUtil::HanningSmooth(VisIter &vi, const String& dataCol, const Bool& doFlagAndWeight)
     284             : {
     285             :     using casacore::operator*;
     286             : 
     287           0 :     LogIO os(LogOrigin("VisSetUtil", "HanningSmooth()"));
     288             : 
     289           0 :     VisBuffer vb(vi);
     290             :     Int row, chn, pol;
     291             : 
     292           0 :     for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
     293           0 :         if (vi.existsWeightSpectrum()) {
     294           0 :             for (vi.origin();vi.more();vi++) {
     295             : 
     296           0 :                 Cube<Complex>& vc = ( dataCol=="data" ? vb.visCube() : vb.correctedVisCube());
     297             : 
     298           0 :                 Cube<Bool>& fc= vb.flagCube();
     299           0 :                 Cube<Float>& wc= vb.weightSpectrum();
     300             : 
     301           0 :                 Int nRow=vb.nRow();
     302           0 :                 Int nChan=vb.nChannel();
     303           0 :                 if (nChan < 3) break;
     304           0 :                 Int nPol=vi.visibilityShape()(0);
     305           0 :                 Cube<Complex> smoothedData(nPol,nChan,nRow);
     306           0 :                 Cube<Bool> newFlag(nPol,nChan,nRow);
     307           0 :                 Cube<Float> newWeight(nPol,nChan,nRow);
     308           0 :                 for (row=0; row<nRow; row++) {
     309           0 :                     for (pol=0; pol<nPol; pol++) {
     310             :                         ///Handle first channel and flag it
     311           0 :                         smoothedData(pol,0,row) = vc(pol,0,row)*0.5 + vc(pol,1,row)*0.5;
     312           0 :                         newWeight(pol,0,row) = 0.0;
     313           0 :                         newFlag(pol,0,row) = true;
     314           0 :                         for (chn=1; chn<nChan-1; chn++) {
     315           0 :                             smoothedData(pol,chn,row) =
     316           0 :                                     vc(pol,chn-1,row)*0.25 + vc(pol,chn,row)*0.50 +
     317           0 :                                     vc(pol,chn+1,row)*0.25;
     318           0 :                             if (wc(pol,chn-1,row) != 0 && wc(pol,chn,row) != 0
     319           0 :                                     && wc(pol,chn+1,row) != 0) {
     320           0 :                                 newWeight(pol,chn,row) = 1.0 /
     321           0 :                                         (1.0/(wc(pol,chn-1,row)*16.0) + 1.0/(wc(pol,chn,row)*4.0)
     322           0 :                                                 + 1.0/(wc(pol,chn+1,row)*16.0));
     323             :                             } else {
     324           0 :                                 newWeight(pol,chn,row) = 0.0;
     325             :                             }
     326           0 :                             newFlag(pol,chn,row) =
     327           0 :                                     fc(pol,chn-1,row)||fc(pol,chn,row)||fc(pol,chn+1,row);
     328             :                         }
     329             :                         //Handle last channel and flag it
     330           0 :                         smoothedData(pol,nChan-1,row) =
     331           0 :                                 vc(pol,nChan-2,row)*0.5+vc(pol,nChan-1,row)*0.5;
     332           0 :                         newWeight(pol,nChan-1,row) = 0.0;
     333           0 :                         newFlag(pol,nChan-1,row) = true;  // flag last channel
     334             :                     }
     335             :                 }
     336             : 
     337           0 :                 if(dataCol=="data"){
     338           0 :                     if(doFlagAndWeight){
     339           0 :                         vi.setVisAndFlag(smoothedData,newFlag,VisibilityIterator::Observed);
     340           0 :                         vi.setWeightSpectrum(newWeight);
     341             :                     }
     342             :                     else{
     343           0 :                         vi.setVis(smoothedData,VisibilityIterator::Observed);
     344             :                     }
     345             :                 }
     346             :                 else{
     347           0 :                     if(doFlagAndWeight){
     348           0 :                         vi.setVisAndFlag(smoothedData,newFlag,VisibilityIterator::Corrected);
     349           0 :                         vi.setWeightSpectrum(newWeight);
     350             :                     }
     351             :                     else{
     352           0 :                         vi.setVis(smoothedData,VisibilityIterator::Corrected);
     353             :                     }
     354             :                 }
     355             : 
     356           0 :             }
     357             :         } else {
     358           0 :             for (vi.origin();vi.more();vi++) {
     359             : 
     360           0 :                 Cube<Complex>& vc = (dataCol=="data" ? vb.visCube() : vb.correctedVisCube());
     361             : 
     362           0 :                 Cube<Bool>& fc= vb.flagCube();
     363           0 :                 Matrix<Float>& wm = vb.weightMat();
     364             : 
     365           0 :                 Int nRow=vb.nRow();
     366           0 :                 Int nChan=vb.nChannel();
     367           0 :                 if (nChan < 3) break;
     368           0 :                 Int nPol=vi.visibilityShape()(0);
     369           0 :                 Cube<Complex> smoothedData(nPol,nChan,nRow);
     370           0 :                 Cube<Bool> newFlag(nPol,nChan,nRow);
     371           0 :                 Matrix<Float> newWeight(nPol, nRow);
     372           0 :                 for (row=0; row<nRow; row++) {
     373           0 :                     for (pol=0; pol<nPol; pol++) {
     374             :                         ///Handle first channel and flag it
     375           0 :                         smoothedData(pol,0,row) = vc(pol,0,row)*0.5 + vc(pol,1,row)*0.5;
     376           0 :                         newFlag(pol,0,row) = true;
     377             :                         ///Handle chan-independent weights
     378           0 :                         newWeight(pol, row) = 8.0*wm(pol, row)/3.0;
     379           0 :                         for (chn=1; chn<nChan-1; chn++) {
     380           0 :                             smoothedData(pol,chn,row) =
     381           0 :                                     vc(pol,chn-1,row)*0.25 + vc(pol,chn,row)*0.50 +
     382           0 :                                     vc(pol,chn+1,row)*0.25;
     383           0 :                             newFlag(pol,chn,row) =
     384           0 :                                     fc(pol,chn-1,row)||fc(pol,chn,row)||fc(pol,chn+1,row);
     385             :                         }
     386             :                         //Handle last channel and flag it
     387           0 :                         smoothedData(pol,nChan-1,row) =
     388           0 :                                 vc(pol,nChan-2,row)*0.5+vc(pol,nChan-1,row)*0.5;
     389           0 :                         newFlag(pol,nChan-1,row) = true;  // flag last channel
     390             :                     }
     391             :                 }
     392             : 
     393           0 :                 if(dataCol=="data"){
     394           0 :                     if(doFlagAndWeight){
     395           0 :                         vi.setVisAndFlag(smoothedData,newFlag,VisibilityIterator::Observed);
     396           0 :                         vi.setWeightMat(newWeight);
     397             :                     }
     398             :                     else{
     399           0 :                         vi.setVis(smoothedData,VisibilityIterator::Observed);
     400             :                     }
     401             :                 }
     402             :                 else{
     403           0 :                     if(doFlagAndWeight){
     404           0 :                         vi.setVisAndFlag(smoothedData,newFlag,VisibilityIterator::Corrected);
     405           0 :                         vi.setWeightMat(newWeight);
     406             :                     }
     407             :                     else{
     408           0 :                         vi.setVis(smoothedData,VisibilityIterator::Corrected);
     409             :                     }
     410             :                 }
     411           0 :             }
     412             :         }
     413             :     }
     414           0 : }
     415             : 
     416             : 
     417           0 : void VisSetUtil::addScrCols(MeasurementSet& ms, Bool addModel, Bool addCorr, 
     418             :                             Bool alsoinit, Bool compress) {
     419             : 
     420             :     // Add but DO NOT INITIALIZE calibration set (comprising a set of CORRECTED_DATA
     421             :     // and MODEL_DATA columns) to the MeasurementSet.
     422             : 
     423             :     // Sense if anything is to be done
     424           0 :     addModel=addModel && !(ms.tableDesc().isColumn("MODEL_DATA"));
     425           0 :     addCorr=addCorr && !(ms.tableDesc().isColumn("CORRECTED_DATA"));
     426             : 
     427             :     // Escape (silently) without doing anything if nothing
     428             :     // to be done
     429           0 :     if (!addModel && !addCorr)
     430           0 :         return;
     431             :     else {
     432             :         // Remove SORTED_TABLE and continue
     433             :         // This is needed because old SORTED_TABLE won't see
     434             :         //   the added column(s)
     435           0 :         if (ms.keywordSet().isDefined("SORT_COLUMNS"))
     436           0 :             ms.rwKeywordSet().removeField("SORT_COLUMNS");
     437           0 :         if (ms.keywordSet().isDefined("SORTED_TABLE"))
     438           0 :             ms.rwKeywordSet().removeField("SORTED_TABLE");
     439             :     }
     440             : 
     441             :     // If we are adding the MODEL_DATA column, make it
     442             :     //  the exclusive origin for model visibilities by
     443             :     //  deleting any OTF model keywords
     444           0 :     if (addModel)
     445           0 :         VisSetUtil::remOTFModel(ms);
     446             : 
     447             : 
     448             :     // Form log message
     449           0 :     String addMessage("Adding ");
     450           0 :     if (addModel) {
     451           0 :         addMessage+="MODEL_DATA ";
     452           0 :         if (addCorr) addMessage+="and ";
     453             :     }
     454           0 :     if (addCorr) addMessage+="CORRECTED_DATA ";
     455           0 :     addMessage+="column(s).";
     456           0 :     LogSink logSink;
     457           0 :     LogMessage message(addMessage,LogOrigin("VisSetUtil","addScrCols"));
     458           0 :     logSink.post(message);
     459             : 
     460             :     {
     461             :         // Define a column accessor to the observed data
     462             :         TableColumn* data;
     463           0 :         const bool data_is_float = ms.tableDesc().isColumn(MS::columnName(MS::FLOAT_DATA));
     464           0 :         if (data_is_float) {
     465           0 :             data = new ArrayColumn<Float> (ms, MS::columnName(MS::FLOAT_DATA));
     466             :         } else {
     467           0 :             data = new ArrayColumn<Complex> (ms, MS::columnName(MS::DATA));
     468             :         };
     469             : 
     470             :         // Check if the data column is tiled and, if so, the
     471             :         // smallest tile shape used.
     472           0 :         TableDesc td = ms.actualTableDesc();
     473           0 :         const ColumnDesc& cdesc = td[data->columnDesc().name()];
     474           0 :         String dataManType = cdesc.dataManagerType();
     475           0 :         String dataManGroup = cdesc.dataManagerGroup();
     476             : 
     477           0 :         IPosition dataTileShape;
     478           0 :         Bool tiled = (dataManType.contains("Tiled"));
     479           0 :         Bool simpleTiling = false;
     480             : 
     481           0 :         if (!tiled || !simpleTiling) {
     482             :             // Untiled, or tiled at a higher than expected dimensionality
     483             :             // Use a canonical tile shape of 1 MB size
     484             : 
     485           0 :             MSSpWindowColumns msspwcol(ms.spectralWindow());
     486           0 :             Int maxNchan = max (msspwcol.numChan().getColumn());
     487           0 :             Int tileSize = maxNchan/10 + 1;
     488           0 :             Int nCorr = data->shape(0)(0);
     489           0 :             dataTileShape = IPosition(3, nCorr, tileSize, 131072/nCorr/tileSize + 1);
     490           0 :         };
     491             : 
     492           0 :         delete data;
     493             : 
     494           0 :         if(addModel){
     495             :             // Add the MODEL_DATA column
     496           0 :             TableDesc tdModel, tdModelComp, tdModelScale;
     497           0 :             CompressComplex* ccModel=NULL;
     498           0 :             String colModel=MS::columnName(MS::MODEL_DATA);
     499             : 
     500           0 :             tdModel.addColumn(ArrayColumnDesc<Complex>(colModel,"model data", 2));
     501           0 :             td.addColumn(ArrayColumnDesc<Complex>(colModel,"model data", 2));
     502           0 :             IPosition modelTileShape = dataTileShape;
     503           0 :             if (compress) {
     504           0 :                 tdModelComp.addColumn(ArrayColumnDesc<Int>(colModel+"_COMPRESSED",
     505             :                                                            "model data compressed",2));
     506           0 :                 tdModelScale.addColumn(ScalarColumnDesc<Float>(colModel+"_SCALE"));
     507           0 :                 tdModelScale.addColumn(ScalarColumnDesc<Float>(colModel+"_OFFSET"));
     508           0 :                 ccModel = new CompressComplex(colModel, colModel+"_COMPRESSED",
     509           0 :                                               colModel+"_SCALE", colModel+"_OFFSET", true);
     510             : 
     511           0 :                 StandardStMan modelScaleStMan("ModelScaleOffset");
     512           0 :                 ms.addColumn(tdModelScale, modelScaleStMan);
     513             : 
     514             : 
     515           0 :                 TiledShapeStMan modelCompStMan("ModelCompTiled", modelTileShape);
     516           0 :                 ms.addColumn(tdModelComp, modelCompStMan);
     517           0 :                 ms.addColumn(tdModel, *ccModel);
     518             : 
     519           0 :             } else {
     520             : 
     521             :                 // Make a clone of the appropriate data column.  The clone can differ by
     522             :                 // by having a different element datatype.
     523             : 
     524             :                 try {
     525           0 :                     String dataColumnName = data_is_float ? MS::columnName (MS::FLOAT_DATA)
     526           0 :                     :  MS::columnName (MS::DATA);
     527             : 
     528           0 :                     TableCopy::cloneColumnTyped<Complex> (ms, dataColumnName, ms, MS::columnName(MS::MODEL_DATA),
     529             :                                                           "TiledModel");
     530             : 
     531             :                     // Now fill the model column with complex zeroes.  Using the function below
     532             :                     // to do the filling preserves the tiling of the hypercubes making up
     533             :                     // the column.  The later call to initScrCols will set these appropriately
     534             :                     // since depending on the way the correlations are represented, only one
     535             :                     // of the correlations will be set to one.  Unfortunately, this results in
     536             :                     // two writes of the scratch column where one would do.
     537             : 
     538           0 :                     TableCopy::fillColumnData (ms, MS::columnName (MS::MODEL_DATA),
     539           0 :                                                Complex (0.0, 0.0),
     540             :                                                ms, dataColumnName,
     541             :                                                true); // last arg preserves tile shape
     542           0 :                 } catch (AipsError & e){
     543             : 
     544             :                     // Column cloning failed (presumably).  Try it the old way.
     545             : 
     546           0 :                     MeasurementSet::addColumnToDesc(tdModel, MeasurementSet::MODEL_DATA, 2);
     547           0 :                     TiledShapeStMan modelStMan("ModelTiled", modelTileShape);
     548           0 :                     ms.addColumn(tdModel, modelStMan);
     549           0 :                 }
     550             :             }
     551             : 
     552           0 :             if (ccModel) delete ccModel;
     553           0 :         }
     554           0 :         if (addCorr) {
     555             :             // Add the CORRECTED_DATA column
     556           0 :             TableDesc tdCorr, tdCorrComp, tdCorrScale;
     557           0 :             CompressComplex* ccCorr=NULL;
     558           0 :             String colCorr=MS::columnName(MS::CORRECTED_DATA);
     559             : 
     560           0 :             tdCorr.addColumn(ArrayColumnDesc<Complex>(colCorr,"corrected data", 2));
     561           0 :             IPosition corrTileShape = dataTileShape;
     562           0 :             if (compress) {
     563           0 :                 tdCorrComp.addColumn(ArrayColumnDesc<Int>(colCorr+"_COMPRESSED",
     564             :                                                           "corrected data compressed",2));
     565           0 :                 tdCorrScale.addColumn(ScalarColumnDesc<Float>(colCorr+"_SCALE"));
     566           0 :                 tdCorrScale.addColumn(ScalarColumnDesc<Float>(colCorr+"_OFFSET"));
     567           0 :                 ccCorr = new CompressComplex(colCorr, colCorr+"_COMPRESSED",
     568           0 :                                              colCorr+"_SCALE", colCorr+"_OFFSET", true);
     569             : 
     570           0 :                 StandardStMan corrScaleStMan("CorrScaleOffset");
     571           0 :                 ms.addColumn(tdCorrScale, corrScaleStMan);
     572             : 
     573           0 :                 TiledShapeStMan corrCompStMan("CorrectedCompTiled", corrTileShape);
     574           0 :                 ms.addColumn(tdCorrComp, corrCompStMan);
     575           0 :                 ms.addColumn(tdCorr, *ccCorr);
     576             : 
     577           0 :             } else {
     578             : 
     579             :                 try {
     580             : 
     581             :                     // Make a clone of the appropriate data column, except the new column
     582             :                     // will have datatype complex.
     583             : 
     584           0 :                     String dataColumnName = data_is_float ? MS::columnName (MS::FLOAT_DATA)
     585           0 :                     :  MS::columnName (MS::DATA);
     586             : 
     587           0 :                     TableCopy::cloneColumnTyped<Complex> (ms, dataColumnName,
     588             :                                                           ms, colCorr,
     589             :                                                           "TiledCorrected");
     590             : 
     591             :                     // Copy the appropriate data column into the new one, preserving the tiling
     592             :                     // of the column's hypercubes.
     593             : 
     594           0 :                     TableCopy::copyColumnData (ms, dataColumnName,
     595             :                                                ms, colCorr,
     596             :                                                true); // last arg preserves tile shape
     597             : 
     598           0 :                     addCorr = false; // We've already done the copying
     599             : 
     600           0 :                 } catch (AipsError & e){
     601             : 
     602             :                     // Table clone failed (presumably): try it the old way
     603             : 
     604           0 :                     TiledShapeStMan corrStMan("CorrectedTiled", corrTileShape);
     605           0 :                     ms.addColumn(tdCorr, corrStMan);
     606           0 :                 }
     607             :                 // Copy the column keywords
     608           0 :                 String dataColumnName = data_is_float ? MS::columnName (MS::FLOAT_DATA)
     609           0 :                 :  MS::columnName (MS::DATA);
     610           0 :                 const TableRecord& dataColKeyWord = ms.tableDesc().columnDesc(dataColumnName).keywordSet();
     611           0 :                 if (dataColKeyWord.nfields() > 0) {
     612           0 :                     LogMessage message("Start copying column keyword(s) of "+colCorr+" from "+dataColumnName,LogOrigin("VisSetUtil","addScrCols"));
     613           0 :                     logSink.post(message);
     614           0 :                     ArrayColumn<Complex> corrCol(ms, colCorr);
     615           0 :                     TableRecord &corrColKeyWord = corrCol.rwKeywordSet();
     616           0 :                         if (corrColKeyWord.nfields()==0) {
     617           0 :                         corrColKeyWord.assign(dataColKeyWord);
     618             :                         } else {
     619           0 :                                 corrColKeyWord.merge(dataColKeyWord, RecordInterface::OverwriteDuplicates);
     620             :                         }
     621           0 :                 }
     622           0 :             }
     623             : 
     624           0 :             if (ccCorr) delete ccCorr;
     625           0 :         }
     626           0 :         ms.flush();
     627             : 
     628           0 :     }
     629             : 
     630           0 :     if (alsoinit)
     631             :         // Initialize only what we added
     632           0 :         VisSetUtil::initScrCols(ms,addModel,addCorr);
     633             : 
     634           0 :     return;
     635             : 
     636             : 
     637           0 : }
     638             : 
     639           1 : void VisSetUtil::remScrCols(MeasurementSet& ms, Bool remModel, Bool remCorr) {
     640             : 
     641           1 :     Vector<String> colNames(2);
     642           1 :     colNames(0)=MS::columnName(MS::MODEL_DATA);
     643           1 :     colNames(1)=MS::columnName(MS::CORRECTED_DATA);
     644             : 
     645           1 :     Vector<Bool> doCol(2);
     646           1 :     doCol(0)=remModel;
     647           1 :     doCol(1)=remCorr;
     648             : 
     649             : 
     650           3 :     for (uInt j=0; j<colNames.nelements(); j++) {
     651           2 :         if (doCol(j)) {
     652           2 :             if (ms.tableDesc().isColumn(colNames(j))) {
     653           0 :                 ms.removeColumn(colNames(j));
     654             :             };
     655           2 :             if (ms.tableDesc().isColumn(colNames(j)+"_COMPRESSED")) {
     656           0 :                 ms.removeColumn(colNames(j)+"_COMPRESSED");
     657             :             };
     658           2 :             if (ms.tableDesc().isColumn(colNames(j)+"_SCALE")) {
     659           0 :                 ms.removeColumn(colNames(j)+"_SCALE");
     660             :             };
     661           2 :             if (ms.tableDesc().isColumn(colNames(j)+"_OFFSET")) {
     662           0 :                 ms.removeColumn(colNames(j)+"_OFFSET");
     663             :             };
     664             :         };
     665             :     };
     666             : 
     667             : 
     668           1 : }
     669             : 
     670           0 : void VisSetUtil::remOTFModel(MeasurementSet& ms) {
     671             : 
     672           0 :     CountedPtr<VisModelDataI> visModelData = VisModelDataI::create();
     673           0 :     visModelData->clearModelI(ms);
     674           0 : }
     675             : 
     676           0 : void VisSetUtil::initScrCols(MeasurementSet& ms, Bool initModel, Bool initCorr) {
     677             : 
     678             :     // Sense if anything is to be done (relevant scr cols must be present)
     679           0 :     initModel=initModel && ms.tableDesc().isColumn("MODEL_DATA");
     680           0 :     initCorr=initCorr && ms.tableDesc().isColumn("CORRECTED_DATA");
     681             : 
     682             :     // Do nothing?
     683           0 :     if (!initModel && !initCorr)
     684           0 :         return;
     685             : 
     686             :     /* Reconsider this trap?
     687             :   // Trap missing columns:
     688             :   if (initModel && !ms.tableDesc().isColumn("MODEL_DATA"))
     689             :     throw(AipsError("Cannot initialize MODEL_DATA if column is absent."));
     690             :   if (initCorr && !ms.tableDesc().isColumn("CORRECTED_DATA"))
     691             :     throw(AipsError("Cannot initialize CORRECTED_DATA if column is absent."));
     692             :      */
     693             : 
     694             :     // Create ordinary (un-row-selected) VisibilityIterator from the MS
     695           0 :     VisibilityIterator vi(ms,Block<Int>(),0.0);
     696             : 
     697             :     // Pass to VisibilityIterator-oriented method
     698           0 :     VisSetUtil::initScrCols(vi,initModel,initCorr);
     699           0 : }
     700             : 
     701             : 
     702           0 : void VisSetUtil::initScrCols(VisibilityIterator& vi, Bool initModel, Bool initCorr) {
     703             : 
     704             :     // Sense if anything is to be done (relevant scr cols must be present)
     705           0 :     initModel=initModel && vi.ms().tableDesc().isColumn("MODEL_DATA");
     706           0 :     initCorr=initCorr && vi.ms().tableDesc().isColumn("CORRECTED_DATA");
     707             : 
     708             :     // Do nothing?
     709           0 :     if (!initModel && !initCorr)
     710           0 :         return;
     711             : 
     712             :     /*  Reconsider this trap?
     713             :   // Trap missing columns:
     714             :   if (initModel && !vi.ms().tableDesc().isColumn("MODEL_DATA"))
     715             :     throw(AipsError("Cannot initialize MODEL_DATA if column is absent."));
     716             :   if (initCorr && !vi.ms().tableDesc().isColumn("CORRECTED_DATA"))
     717             :     throw(AipsError("Cannot initialize CORRECTED_DATA if column is absent."));
     718             :      */
     719             : 
     720             :     // Form log message
     721           0 :     String initMessage("Initializing ");
     722           0 :     if (initModel) {
     723           0 :         initMessage+="MODEL_DATA to (unity)";
     724           0 :         if (initCorr) initMessage+=" and ";
     725             :     }
     726           0 :     if (initCorr) initMessage+="CORRECTED_DATA (to DATA)";
     727           0 :     initMessage+=".";
     728           0 :     LogSink logSink;
     729           0 :     LogMessage message(initMessage,LogOrigin("VisSetUtil","initScrCols"));
     730           0 :     logSink.post(message);
     731             : 
     732           0 :     Vector<Int> lastCorrType;
     733           0 :     Vector<Bool> zero;
     734           0 :     Int nRows(0);
     735           0 :     vi.setRowBlocking(10000);
     736           0 :     for (vi.originChunks(); vi.moreChunks(); vi.nextChunk()) {
     737             : 
     738           0 :         Vector<Int> corrType; vi.corrType(corrType);
     739           0 :         uInt nCorr = corrType.nelements();
     740           0 :         if (initModel) {
     741             :             // figure out which correlations to set to 1. and 0. for the model.
     742           0 :             if (nCorr != lastCorrType.nelements() ||
     743           0 :                     !allEQ(corrType, lastCorrType)) {
     744             : 
     745           0 :                 lastCorrType.resize(nCorr);
     746           0 :                 lastCorrType=corrType;
     747           0 :                 zero.resize(nCorr);
     748             : 
     749           0 :                 for (uInt i=0; i<nCorr; i++)
     750             :                 {
     751           0 :                     zero[i]=(corrType[i]==Stokes::RL || corrType[i]==Stokes::LR ||
     752           0 :                             corrType[i]==Stokes::XY || corrType[i]==Stokes::YX);
     753             :                 }
     754             :             }
     755             :         }
     756           0 :         for (vi.origin(); vi.more(); vi++) {
     757           0 :             nRows+=vi.nRow();
     758             : 
     759           0 :             Cube<Complex> data;
     760           0 :             vi.visibility(data, VisibilityIterator::Observed);
     761           0 :             if (initCorr) {
     762             :                 // Read DATA and set CORRECTED_DATA
     763           0 :                 vi.setVis(data,VisibilityIterator::Corrected);
     764             :             }
     765           0 :             if (initModel) {
     766             :                 // Set MODEL_DATA
     767           0 :                 data.set(1.0);
     768           0 :                 if (ntrue(zero)>0) {
     769           0 :                     for (uInt i=0; i < nCorr; i++) {
     770           0 :                         if (zero[i]) data(Slice(i), Slice(), Slice()) = Complex(0.0,0.0);
     771             :                     }
     772             :                 }
     773           0 :                 vi.setVis(data,VisibilityIterator::Model);
     774             :             }
     775           0 :         }
     776           0 :     }
     777           0 :     vi.ms().relinquishAutoLocks();
     778             : 
     779           0 :     vi.originChunks();
     780           0 :     vi.setRowBlocking(0);
     781             : 
     782           0 :     ostringstream os;
     783           0 :     os << "Initialized " << nRows << " rows.";
     784           0 :     message.message(os.str());
     785           0 :     logSink.post(message);
     786             : 
     787           0 : }  
     788             : 
     789           1 : void VisSetUtil::removeCalSet(MeasurementSet& ms, Bool removeModel) {
     790             :     // Remove an existing calibration set (comprising a set of CORRECTED_DATA
     791             :     // and MODEL_DATA columns) from the MeasurementSet.
     792             : 
     793             :     //Remove model in header
     794           1 :     if(removeModel)
     795           0 :         VisSetUtil::remOTFModel(ms);
     796             : 
     797           1 :     VisSetUtil::remScrCols(ms,true,true);
     798             : 
     799           1 : }
     800             : 
     801             : 
     802           0 : void VisSetUtil::UVSub(VisSet &vs, Bool reverse)
     803             : {
     804           0 :     VisIter& vi(vs.iter());
     805           0 :     VisSetUtil::UVSub(vi, reverse);
     806           0 : }
     807           0 : void VisSetUtil::UVSub(VisIter &vi, Bool reverse)
     808             : {
     809           0 :     LogIO os(LogOrigin("VisSetUtil", "UVSub()"));
     810             : 
     811             : 
     812           0 :     VisBuffer vb(vi);
     813             : 
     814             :     Int row, chn, pol;
     815             : 
     816           0 :     for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
     817           0 :         for (vi.origin();vi.more();vi++) {
     818             : 
     819           0 :             Cube<Complex>& vc= vb.correctedVisCube();
     820           0 :             Cube<Complex>& mc= vb.modelVisCube();
     821             : 
     822           0 :             Int nRow=vb.nRow();
     823           0 :             Int nChan=vb.nChannel();
     824           0 :             Int nPol=vi.visibilityShape()(0);
     825           0 :             Cube<Complex> residualData(nPol,nChan,nRow);
     826           0 :             if (reverse) {
     827           0 :                 for (row=0; row<nRow; row++) {
     828           0 :                     for (pol=0; pol<nPol; pol++) {
     829           0 :                         for (chn=0; chn<nChan; chn++) {
     830           0 :                             residualData(pol,chn,row) = vc(pol,chn,row)+mc(pol,chn ,row);
     831             :                         }
     832             :                     }
     833             :                 }
     834             :             } else {
     835           0 :                 for (row=0; row<nRow; row++) {
     836           0 :                     for (pol=0; pol<nPol; pol++) {
     837           0 :                         for (chn=0; chn<nChan; chn++) {
     838           0 :                             residualData(pol,chn,row) = vc(pol,chn,row)-mc(pol,chn ,row);
     839             :                         }
     840             :                     }
     841             :                 }
     842             :             }
     843           0 :             vi.setVis(residualData,VisibilityIterator::Corrected);
     844           0 :         }
     845             :     }
     846           0 : }
     847             : 
     848             : } //# NAMESPACE CASA - END
     849             : 

Generated by: LCOV version 1.16