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

          Line data    Source code
       1             : #include <synthesis/Utilities/FixVis.h>
       2             : #include <msvis/MSVis/MSUVWGenerator.h>
       3             : #include <msvis/MSVis/SubMS.h>
       4             : #include <casacore/measures/Measures/MeasTable.h>
       5             : #include <casacore/measures/Measures/UVWMachine.h>
       6             : #include <casacore/casa/Logging/LogIO.h>
       7             : #include <casacore/casa/Exceptions/Error.h>
       8             : #include <casacore/casa/Quanta/MVAngle.h>
       9             : #include <casacore/coordinates/Coordinates/Projection.h>
      10             : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
      11             : #include <casacore/coordinates/Coordinates/ObsInfo.h>
      12             : #include <casacore/images/Images/PagedImage.h>           // Used to pass coords
      13             : #include <casacore/images/Images/ImageInfo.h>            // to FTMachine.
      14             : #include <casacore/ms/MeasurementSets/MSColumns.h>
      15             : #include <casacore/ms/MeasurementSets/MSDopplerUtil.h>
      16             : #include <casacore/ms/MSSel/MSSelection.h>
      17             : #include <casacore/ms/MSSel/MSSelectionTools.h>
      18             : #include <msvis/MSVis/VisibilityIterator.h>
      19             : #include <msvis/MSVis/VisBuffer.h>
      20             : #include <casacore/casa/BasicSL/String.h> // for parseColumnNames()
      21             : 
      22             : #include <iostream>
      23             : 
      24             : using namespace casacore;
      25             : namespace casa {
      26             : 
      27           0 : FixVis::FixVis(MeasurementSet& ms, const String& dataColName) :
      28             :   FTMachine(),
      29             :   ms_p(ms),
      30             :   msc_p(NULL),
      31             :   nsel_p(0),
      32             :   nAllFields_p(1),
      33             :   npix_p(2),
      34           0 :   cimageShape_p(4, npix_p, npix_p, 1, 1), // Can we get away with
      35           0 :   tileShape_p(4, npix_p, npix_p, 1, 1),   // (1, 1, 1, 1)?  Does it matter?
      36           0 :   tiledShape_p(cimageShape_p, tileShape_p),
      37             :   antennaSel_p(false),
      38           0 :   freqFrameValid_p(false)
      39             :   //  obsString_p("")
      40             : {
      41           0 :   logSink() << LogOrigin("FixVis", "") << LogIO::NORMAL3;
      42             : 
      43           0 :   antennaId_p.resize();
      44           0 :   antennaSelStr_p.resize();
      45           0 :   distances_p.resize();
      46           0 :   dataCols_p = SubMS::parseColumnNames(dataColName, ms);
      47           0 :   nDataCols_p = dataCols_p.nelements();
      48             : 
      49           0 :   nchan_p = 1; // imageNchan_p;
      50             : 
      51           0 :   spectralwindowids_p.resize(ms_p.spectralWindow().nrow());
      52           0 :   indgen(spectralwindowids_p);
      53             : 
      54           0 :   lockCounter_p = 0;
      55           0 : }
      56             :   
      57             : // Destructor
      58           0 : FixVis::~FixVis()
      59             : {
      60           0 :   if(!ms_p.isNull())
      61           0 :     ms_p.flush();
      62             : 
      63           0 :   delete msc_p;
      64           0 : }
      65             : 
      66             : // Interpret field indices (MSSelection)
      67           0 : Vector<Int> FixVis::getFieldIdx(const String& fields)
      68             : {
      69           0 :   MSSelection mssel;
      70             : 
      71           0 :   mssel.setFieldExpr(fields);
      72           0 :   return mssel.getFieldList(&ms_p);
      73             : }
      74             : 
      75           0 : uInt FixVis::setFields(const Vector<Int>& fieldIds)
      76             : {
      77           0 :   logSink() << LogOrigin("FixVis", "setFields");
      78           0 :   logSink() << LogIO::NORMAL << "Selecting fields ";
      79             : 
      80           0 :   nsel_p = fieldIds.nelements();
      81           0 :   nAllFields_p = ms_p.field().nrow();
      82           0 :   FieldIds_p.resize(nAllFields_p);
      83             : 
      84           0 :   for(Int i = 0; i < static_cast<Int>(nAllFields_p); ++i){
      85           0 :     FieldIds_p(i) = -1;
      86           0 :     for(uInt j = 0; j < nsel_p; ++j){
      87           0 :       if(fieldIds[j] == i){
      88           0 :         FieldIds_p(i) = i;
      89           0 :         logSink() << i << " " << LogIO::NORMAL;
      90           0 :         break;
      91             :       }
      92             :     }
      93             :   }
      94           0 :   logSink() << LogIO::POST;
      95             : 
      96           0 :   return nsel_p;
      97             : }
      98             : 
      99           0 : void FixVis::setPhaseDirs(const Vector<MDirection>& phaseDirs)
     100             : {
     101           0 :   phaseDirs_p = phaseDirs;
     102             : 
     103             :   // Do a consistency check between fieldIds and FieldIds_p.
     104           0 :   logSink() << LogOrigin("FixVis", "setPhaseDirs");
     105           0 :   uInt n2change = phaseDirs.nelements();
     106           0 :   if(n2change != nsel_p){
     107             :     logSink() << LogIO::SEVERE
     108             :               << "Mismatch between the number of new directions and the fields to change"
     109           0 :               << LogIO::POST;
     110             :   }
     111           0 : }
     112             : 
     113             : 
     114           0 : void FixVis::convertFieldDirs(const MDirection::Types outType)
     115             : {
     116           0 :   logSink() << LogOrigin("FixVis", "convertFieldDirs");
     117             : 
     118             :   // Note that the each direction column in the FIELD table only allows one
     119             :   // reference frame for the entire column, but polynomials can be assigned on
     120             :   // a row-wise basis for objects moving in that frame.
     121             : 
     122             :   Muvw::Types uvwtype;
     123           0 :   Muvw::getType(uvwtype, MDirection::showType(outType));
     124             : 
     125           0 :   ready_msc_p();
     126             :   
     127           0 :   msc_p->uvw().rwKeywordSet().asrwRecord("MEASINFO").define("Ref", MDirection::showType(outType));
     128             : 
     129           0 :   MSFieldColumns& msfcs = msc_p->field();
     130             : 
     131           0 :   MDirection pd0(msfcs.phaseDirMeas(0));
     132             :   logSink() << LogIO::DEBUG1
     133           0 :             << "PHASE_DIR[0] before = " << pd0.tellMe() << " ";
     134             :   {
     135           0 :     ostringstream os;
     136           0 :     os << *(pd0.getData()) << endl;
     137           0 :     logSink() << os.str() << LogIO::POST;
     138             :   }
     139             :   
     140             :   // There is no physical or known programming need to change the delay and
     141             :   // reference direction frames as well, but for aesthetic reasons we keep them
     142             :   // all in the same frame if they start in the same frame.
     143             :   //ArrayMeasColumn<MDirection> msDelayDirCol;
     144             :   //msDelayDirCol.reference(msfcs.delayDirMeasCol());
     145             :   //ArrayMeasColumn<MDirection> msReferenceDirCol;
     146             :   //msReferenceDirCol.reference(msfcs.referenceDirMeasCol());
     147           0 :   Bool doAll3 = (msfcs.phaseDirMeasCol().getMeasRef().getType() ==
     148           0 :                  msfcs.delayDirMeasCol().getMeasRef().getType() &&
     149           0 :                  msfcs.phaseDirMeasCol().getMeasRef().getType() ==
     150           0 :                  msfcs.referenceDirMeasCol().getMeasRef().getType());
     151             :   
     152             :   // Setup conversion machines.
     153             :   // Set the frame - choose the first antenna. For e.g. VLBI, we
     154             :   // will need to reset the frame per antenna
     155           0 :   mLocation_p = msc_p->antenna().positionMeas()(0);
     156             : 
     157             :   // Expect problems if a moving object is involved!
     158           0 :   mFrame_p = MeasFrame(msfcs.timeMeas()(0), mLocation_p);
     159             : 
     160             :   //MDirection::Ref startref(msfcs.phaseDirMeasCol().getMeasRef());
     161             :   // If the either of the start or destination frames refers to a finite
     162             :   // distance, then the conversion has to be done in two steps:
     163             :   // MDirection::Convert start2app(msfcs.phaseDirMeasCol()(0), MDirection::APP);
     164             :   // 
     165             :   // Otherwise the conversion can be done directly.
     166           0 :   Bool haveMovingFrame = (MDirection::castType(msfcs.phaseDirMeasCol().getMeasRef().getType()) > MDirection::N_Types ||
     167           0 :                           outType > MDirection::N_Types);
     168             : 
     169             :   const MDirection::Ref newFrame(haveMovingFrame ? MDirection::APP : outType,
     170           0 :                                  mFrame_p);
     171             : 
     172           0 :   convertFieldCols(msfcs, newFrame, doAll3);
     173             :   
     174           0 :   if(haveMovingFrame){
     175             :     // Since ArrayMeasCol most likely uses one frame for the whole column, do
     176             :     // the second half of the conversion with a second pass through the column
     177             :     // instead of on a row-by-row basis.
     178             :     logSink() << LogIO::WARN
     179             :               << "Switching to or from accelerating frames is not well tested."
     180           0 :               << LogIO::POST;
     181             : 
     182             :     // Using msfcs.phaseDirMeasCol()(0)[0] to initialize converter will only
     183             :     // work if msfcs.phaseDirMeasCol()'s type has been set to APP.
     184           0 :     const MDirection::Ref newerFrame(outType, mFrame_p);
     185             : 
     186           0 :     convertFieldCols(msfcs, newerFrame, doAll3);
     187             :   }
     188             : 
     189           0 :   pd0 = msfcs.phaseDirMeas(0);
     190             :   logSink() << LogIO::DEBUG1
     191           0 :             << "PHASE_DIR[0] after =  " << pd0.tellMe() << " ";
     192             :   {
     193           0 :     ostringstream os;
     194           0 :     os << *(pd0.getData()) << endl;
     195           0 :     logSink() << os.str() << LogIO::POST;
     196             :   }
     197           0 : }
     198             : 
     199             : 
     200           0 : void FixVis::convertFieldCols(MSFieldColumns& msfcs,
     201             :                               const MDirection::Ref& newFrame,
     202             :                               const Bool doAll3)
     203             : {
     204           0 :   logSink() << LogOrigin("FixVis", "convertFieldCols");
     205             :   // Unfortunately ArrayMeasColumn::doConvert() is private, which moots the
     206             :   // point of making a conversion machine here.
     207             : //   Vector<MDirection> dummyV;
     208             : //   dummyV.assign(pdc(0));
     209             : //   MDirection::Convert *converter = new MDirection::Convert(dummyV[0],
     210             : //                                                            newFrame);
     211             : //   if(!converter)
     212             : //     logSink() << "Cannot make direction conversion machine"
     213             : //               << LogIO::SEVERE;
     214             : 
     215           0 :   uInt nrows = msfcs.nrow();
     216             : 
     217             :   // Convert each phase tracking center.  This will make them numerically
     218             :   // correct in the new frame, but the column will still be labelled with the
     219             :   // old frame.
     220             :   
     221             :   uInt nOrders;
     222           0 :   Vector<MDirection> mdarr;              // direction for each order
     223           0 :   Array<Double>     darr;               // longitude and latitude for each order
     224           0 :   Vector<Double> dirV;
     225           0 :   for(uInt i = 0; i < nrows; ++i){
     226           0 :     nOrders = msfcs.numPoly()(i) + 1;
     227             :     logSink() << LogIO::DEBUG1 << "numPoly(" << i << ") = " << nOrders - 1
     228           0 :               << LogIO::POST;
     229             : 
     230             :     //pdc.put(i, pdc.doConvert(i, *converter));
     231           0 :     mdarr = msfcs.phaseDirMeasCol().convert(i, newFrame);
     232           0 :     darr.resize(IPosition(2, 2, nOrders));
     233           0 :     for(uInt orderNumber = 0; orderNumber < nOrders; ++orderNumber){
     234           0 :       dirV = mdarr[orderNumber].getAngle().getValue();
     235           0 :       darr(IPosition(2, 0, orderNumber)) = dirV[0];
     236           0 :       darr(IPosition(2, 1, orderNumber)) = dirV[1];
     237             :     }
     238           0 :     msfcs.phaseDir().put(i, darr);
     239             :     
     240             :     //msfcs.phaseDirMeasCol().put(i, mdarr);
     241             :     
     242           0 :     if(doAll3){
     243             :       //ddc.put(i, ddc.doConvert(i, *converter));
     244           0 :       mdarr = msfcs.delayDirMeasCol().convert(i, newFrame);
     245           0 :       for(uInt orderNumber = 0; orderNumber < nOrders; ++orderNumber){
     246           0 :         dirV = mdarr[orderNumber].getAngle().getValue();
     247           0 :         darr(IPosition(2, 0, orderNumber)) = dirV[0];
     248           0 :         darr(IPosition(2, 1, orderNumber)) = dirV[1];
     249             :       }
     250           0 :       msfcs.delayDir().put(i, darr);
     251             :       //rdc.put(i, rdc.doConvert(i, *converter));
     252             :       //msfcs.referenceDirMeasCol().put(i,
     253             :       //         msfcs.referenceDirMeasCol().convert(i, newFrame));
     254           0 :       mdarr = msfcs.referenceDirMeasCol().convert(i, newFrame);
     255           0 :       for(uInt orderNumber = 0; orderNumber < nOrders; ++orderNumber){
     256           0 :         dirV = mdarr(IPosition(1, orderNumber)).getAngle().getValue();
     257           0 :         darr(IPosition(2, 0, orderNumber)) = dirV[0];
     258           0 :         darr(IPosition(2, 1, orderNumber)) = dirV[1];
     259             :       }
     260           0 :       msfcs.referenceDir().put(i, darr);      
     261             :     }
     262             :   }
     263             :   
     264             :   // Update the reference frame label(s).
     265           0 :   msfcs.phaseDirMeasCol().setDescRefCode(newFrame.getType(), false);
     266           0 :   if(doAll3){
     267           0 :     msfcs.delayDirMeasCol().setDescRefCode(newFrame.getType(), false);
     268           0 :     msfcs.referenceDirMeasCol().setDescRefCode(newFrame.getType(), false);
     269             :   }
     270             : 
     271             :   //delete converter;
     272           0 : }
     273             : 
     274             : 
     275           0 : void FixVis::setDistances(const Vector<Double>& distances)
     276             : {
     277           0 :   logSink() << LogOrigin("FixVis", "setDistances");
     278           0 :   if(distances.nelements() != nsel_p)
     279             :     logSink() << LogIO::SEVERE
     280             :               << "Mismatch between the # of specified distances and selected fields."
     281           0 :               << LogIO::POST;
     282           0 :   distances_p = distances;
     283           0 : }
     284             : 
     285             : // Calculate the (u, v, w)s and store them in ms_p.
     286           0 : Bool FixVis::calc_uvw(const String& refcode, const Bool reuse)
     287             : {
     288           0 :   Bool retval = false;
     289             :   
     290           0 :   logSink() << LogOrigin("FixVis", "calc_uvw");
     291             : 
     292           0 :   if(!ready_msc_p())
     293           0 :     return false;
     294             :   
     295           0 :   if(nsel_p > 0){
     296             : 
     297             :     // Get the PHASE_DIR reference frame type for the input ms.
     298           0 :     MSFieldColumns& msfcs(msc_p->field());
     299           0 :     MDirection startDir = msfcs.phaseDirMeas(0);
     300           0 :     MDirection::Types startDirType = MDirection::castType(msfcs.phaseDirMeasCol().getMeasRef().getType());
     301             :     MDirection::Types wantedDirType;
     302           0 :     MDirection::getType(wantedDirType, refcode);
     303             : 
     304           0 :     if(startDirType != wantedDirType){
     305           0 :       if(nsel_p < nAllFields_p){
     306             :         logSink() << LogIO::SEVERE
     307             :                   << "The reference frame must either be changed for all fields or not at all."
     308           0 :                   << LogIO::POST;
     309           0 :         return false;
     310             :       }
     311             :       else
     312           0 :         convertFieldDirs(wantedDirType);
     313             :     }
     314           0 :     else if(reuse){
     315             :       logSink() << LogIO::NORMAL
     316             :                 << "The UVWs are already in the desired frame - leaving them as is."
     317           0 :                 << LogIO::POST;
     318           0 :       return true;
     319             :     }
     320             :     
     321             :     try{
     322           0 :       if(reuse){
     323           0 :         const MDirection::Ref outref(wantedDirType);
     324             :         
     325           0 :         rotateUVW(startDir, outref);
     326             :       }
     327             :       else{
     328             :         Muvw::Types uvwtype;
     329             :         MBaseline::Types bltype;
     330             :     
     331             :         try{
     332           0 :           MBaseline::getType(bltype, refcode);
     333           0 :           Muvw::getType(uvwtype, refcode);
     334             :         }
     335           0 :         catch(AipsError x){
     336             :           logSink() << LogIO::SEVERE
     337             :                     << "refcode \"" << refcode << "\" is not valid for baselines."
     338           0 :                     << LogIO::POST;
     339           0 :           return false;
     340             :         }
     341             :              
     342           0 :         MSUVWGenerator uvwgen(*msc_p, bltype, uvwtype);
     343           0 :         retval = uvwgen.make_uvws(FieldIds_p);
     344             :       }
     345             :       
     346             :     }
     347           0 :     catch(AipsError x){
     348           0 :       logSink() << LogIO::SEVERE << "Error " << x.getMesg() << LogIO::POST;
     349             :     }
     350             : 
     351             :   }
     352             :   else{
     353             :     logSink() << LogIO::SEVERE
     354             :               << "There is a problem with the selected field IDs and phase tracking centers."
     355           0 :               << LogIO::POST;
     356             :   }
     357           0 :   return retval;
     358             : }
     359             : 
     360             : // Convert the UVW column to a new reference frame by rotating the old
     361             : // baselines instead of calculating fresh ones.
     362             : //
     363             : // oldref must be supplied instead of extracted from msc_p->uvw(), because
     364             : // the latter might be wrong (use the field direction).
     365           0 : void FixVis::rotateUVW(const MDirection &indir, const MDirection::Ref& newref)
     366             : {
     367           0 :   ArrayColumn<Double>& UVWcol = msc_p->uvw();
     368             : 
     369             :   // Setup a machine for converting a UVW vector from the old frame to
     370             :   // uvwtype's frame
     371           0 :   UVWMachine uvm(newref, indir);
     372           0 :   RotMatrix rm(uvm.rotationUVW());
     373             : 
     374           0 :   uInt nRows = UVWcol.nrow();
     375           0 :   for(uInt row = 0; row < nRows; ++row){
     376           0 :     UVWcol.put(row, (rm * MVuvw(UVWcol(row))).getVector());
     377             :   }
     378           0 :   return;
     379             : }
     380             : 
     381             : // Don't just calculate the (u, v, w)s, do everything and store them in ms_p.
     382           0 : Bool FixVis::fixvis(const String& refcode)
     383             : {
     384           0 :   logSink() << LogOrigin("FixVis", "fixvis");
     385             : 
     386           0 :   Bool retval = false;
     387             : 
     388           0 :   if(!ready_msc_p())
     389           0 :     return false;
     390             : 
     391           0 :   if(nsel_p > 0){
     392           0 :     if(phaseDirs_p.nelements() == static_cast<uInt>(nsel_p)){ 
     393             : 
     394           0 :       String telescop = msc_p->observation().telescopeName()(0);
     395           0 :       MPosition obsPosition;
     396           0 :       if(!(MeasTable::Observatory(obsPosition, telescop))){
     397             :         logSink() << LogIO::WARN << "Did not get the position of " << telescop 
     398           0 :                   << " from data repository" << LogIO::POST;
     399             :         logSink() << LogIO::WARN << "Please contact CASA to add it to the repository."
     400           0 :                   << LogIO::POST;
     401           0 :         logSink() << LogIO::WARN << "Frequency conversion will not work " << LogIO::POST;
     402           0 :         freqFrameValid_p = false;
     403             :       }
     404             :       else{
     405           0 :         mLocation_p = obsPosition;
     406           0 :         freqFrameValid_p = true;
     407             :       }
     408             : 
     409           0 :       MSFieldColumns& msfcs = msc_p->field();
     410             : 
     411           0 :       mFrame_p = MeasFrame(msfcs.timeMeas()(0), mLocation_p);
     412             : 
     413           0 :       msc_p->uvw().rwKeywordSet().asrwRecord("MEASINFO").define("Ref", refcode);
     414             : 
     415             :       //**** Adjust the phase tracking centers and distances. ****
     416             :       // Loop through each selected field.
     417             :       Int selectedField;
     418           0 :       Int selFldCounter=0;
     419           0 :       for(uInt fldCounter = 0; fldCounter < nAllFields_p; ++fldCounter){
     420           0 :         selectedField = FieldIds_p[fldCounter];
     421           0 :         if(selectedField<0){
     422           0 :           continue;
     423             :         }
     424           0 :         setImageField(selectedField);
     425           0 :         if(makeSelection(selectedField)){
     426           0 :           logSink() << LogIO::NORMAL << "Processing field " << selectedField << LogIO::POST;
     427           0 :           processSelected(selFldCounter);
     428           0 :           selFldCounter++;
     429             : 
     430             :           // Update FIELD (and/or optional tables SOURCE, OBSERVATION, but not
     431             :           // POINTING?) to new PTC.
     432             : 
     433           0 :           retval = true;
     434             :         }
     435             :         else{
     436             :           logSink() << LogIO::SEVERE
     437             :                     << "Field " << selectedField << " could not be selected for phase tracking center or"
     438             :                     << " distance adjustment."
     439           0 :                     << LogIO::POST;
     440             :         }
     441             :       }
     442             :     }
     443           0 :     else if(phaseDirs_p.nelements() > 0){
     444             :       logSink() << LogIO::SEVERE
     445             :                 << "There is a problem with the selected field IDs and phase tracking centers.\n"
     446             :                 << "No adjustments of phase tracking centers or distances will be done."
     447           0 :                 << LogIO::POST;
     448             :     }
     449             :   }
     450             :   else{
     451           0 :     logSink() << LogIO::SEVERE << "No fields are selected." << LogIO::POST;
     452             :   }  
     453           0 :   return retval;
     454             : }
     455             : 
     456             : 
     457           0 : Bool FixVis::setImageField(const Int fieldid,
     458             :                            const Bool dotrackDir //, const MDirection& trackDir
     459             :                            )
     460             : {
     461           0 :   logSink() << LogOrigin("FixVis", "setImageField()");
     462             : 
     463             :   try{
     464             : 
     465           0 :     doTrackSource_p = dotrackDir;
     466             : 
     467           0 :     fieldid_p = fieldid;
     468             : 
     469           0 :     return true;
     470             :   }
     471             :   catch(AipsError x){
     472             :     this->unlock();
     473             :     logSink() << LogIO::SEVERE << "Caught exception: " << x.getMesg()
     474             :        << LogIO::POST;
     475             :     return false;
     476             :   } 
     477             :   return true;
     478             : }
     479             : 
     480           0 : Bool FixVis::lock()
     481             : {
     482           0 :   Bool ok = true;
     483             : 
     484           0 :   if(lockCounter_p == 0)
     485           0 :     ok = ms_p.lock();
     486           0 :   ++lockCounter_p;
     487             : 
     488           0 :   return ok;
     489             : }
     490             : 
     491           0 : void FixVis::unlock()
     492             : {
     493           0 :   if(lockCounter_p == 1)
     494           0 :     ms_p.unlock();
     495             : 
     496           0 :   if(lockCounter_p > 0)
     497           0 :     --lockCounter_p;
     498           0 : }
     499             : 
     500             : 
     501           0 : Bool FixVis::makeSelection(const Int selectedField)
     502             : {
     503           0 :   logSink() << LogOrigin("FixVis", "makeSelection()");
     504             :     
     505             :   //Vis/MSIter will check if SORTED_TABLE exists and resort if necessary.
     506           0 :   MSSelection thisSelection;
     507           0 :   if(selectedField >= 0 && nAllFields_p > 1){
     508           0 :     Vector<Int> wrapper;
     509           0 :     wrapper.resize(1);
     510           0 :     wrapper[0] = selectedField;
     511           0 :     thisSelection.setFieldExpr(MSSelection::indexExprStr(wrapper));
     512             :   }
     513           0 :   else if(antennaSel_p){
     514           0 :     if(antennaId_p.nelements() > 0)
     515           0 :       thisSelection.setAntennaExpr(MSSelection::indexExprStr(antennaId_p));
     516           0 :     if(antennaSelStr_p[0] != "")
     517           0 :       thisSelection.setAntennaExpr(MSSelection::nameExprStr(antennaSelStr_p));
     518             :   }
     519             :   //  if(obsString_p != "")
     520             :   //  thisSelection.setObservationExpr(obsString_p);
     521             :     
     522           0 :   TableExprNode exprNode = thisSelection.toTableExprNode(&ms_p);    
     523             :     
     524             :   // Now remake the selected ms
     525           0 :   if(!(exprNode.isNull())){
     526           0 :     mssel_p = MeasurementSet(ms_p(exprNode));
     527             :   }
     528           0 :   else if(selectedField < 0 || nsel_p == nAllFields_p){
     529             :     // Null take all the ms ...setdata() blank means that
     530           0 :     mssel_p = MeasurementSet(ms_p);
     531             :   }
     532             :   else{
     533             :     logSink() << LogIO::SEVERE
     534             :               << "Error selecting field " << selectedField << ".  "
     535             :               << "Are you trying to adjust antenna positions at the same time?"
     536           0 :               << LogIO::POST;
     537           0 :     return false;
     538             :   }
     539             : 
     540             :   //mssel_p.rename(ms_p.tableName()+"/SELECTED_TABLE", Table::Scratch);
     541           0 :   if(mssel_p.nrow() == 0)
     542           0 :     return false;
     543             : 
     544           0 :   if(mssel_p.nrow() < ms_p.nrow())
     545             :     logSink() << LogIO::NORMAL
     546             :               << mssel_p.nrow() << " rows selected out of " << ms_p.nrow() << "." 
     547           0 :               << LogIO::POST;
     548             : 
     549           0 :   delete msc_p;
     550           0 :   msc_p = NULL;
     551           0 :   return ready_msc_p();
     552             : }
     553             : 
     554           0 : Bool FixVis::ready_msc_p()
     555             : {
     556           0 :   Bool retval = false;
     557             : 
     558           0 :   if(!msc_p){
     559             :     try{
     560           0 :       msc_p = new MSColumns(mssel_p.isNull() ? ms_p : mssel_p);
     561           0 :       retval = true; // Assume msc_p is OK.
     562             :     }
     563           0 :     catch(AipsError& e){
     564             :       logSink() << LogIO::SEVERE
     565             :                 << "Error getting the columns from the MS."
     566           0 :                 << LogIO::POST;
     567             :     }
     568           0 :     catch(std::bad_alloc& e){
     569             :       logSink() << LogIO::SEVERE
     570             :                 << "Error allocating memory for the MS columns."
     571           0 :                 << LogIO::POST;
     572             :     }
     573             :     // Just let any other exceptions, of the unexpected kind,
     574             :     // propagate up where they can be seen.
     575             :   }
     576             :   else
     577           0 :     retval = true; // Assume msc_p is OK.
     578             : 
     579           0 :   return retval;
     580             : }
     581             : 
     582             : 
     583           0 : void FixVis::processSelected(uInt numInSel)
     584             : {
     585           0 :   logSink() << LogOrigin("FixVis", "processSelected()");
     586             : 
     587           0 :   mImage_p = phaseDirs_p[numInSel];
     588             : 
     589           0 :   ArrayColumn<Double>& UVWcol = msc_p->uvw();
     590             : 
     591           0 :   Block<Int> sort(0);
     592           0 :   sort.resize(4);
     593           0 :   sort[0] = MS::ARRAY_ID;                   // use default sort order
     594           0 :   sort[1] = MS::FIELD_ID;
     595           0 :   sort[2] = MS::DATA_DESC_ID;
     596           0 :   sort[3] = MS::TIME;
     597             : 
     598           0 :   VisibilityIterator vi(mssel_p, sort); 
     599             :           
     600             :   // Loop over all visibilities in the selected field.
     601           0 :   VisBuffer vb(vi);
     602             :   
     603           0 :   vi.origin();
     604             : 
     605           0 :   for(vi.originChunks(); vi.moreChunks(); vi.nextChunk()){
     606           0 :     for(vi.origin(); vi.more(); ++vi){
     607             : 
     608           0 :       uInt numRows = vb.nRow();
     609             : 
     610           0 :       Matrix<Double> uvw(3, numRows);
     611           0 :       uvw=0.0;
     612           0 :       Vector<Double> dphase(numRows);
     613           0 :       dphase=0.0;
     614             : 
     615           0 :       for(uInt i = 0; i < numRows; ++i){
     616           0 :         for (Int idim=0;idim<3;idim++){
     617           0 :           uvw(idim,i)=vb.uvw()(i)(idim);
     618             :         }
     619             :       }
     620             : 
     621             :       // the following call requires the member variables
     622             :       //   lastFieldId_p
     623             :       //   lastMSId_p
     624             :       //   tangentSpecified_p
     625             :       //   MeasFrame mFrame_p == output ref frame for the UVW coordinates
     626             :       //   MDirection mImage_p == output phase center
     627             :       //      (input phase center is taken from the visbuffer, i.e. from the FIELD table)
     628             :       
     629           0 :       FTMachine::rotateUVW(uvw, dphase, vb);
     630             : 
     631             :       // Immediately returns if not needed.
     632           0 :       refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
     633             : 
     634             :       // update vis buffer cache
     635           0 :       for(uInt datacol = 0; datacol < nDataCols_p; datacol++){
     636           0 :         if(dataCols_p[datacol] == MS::DATA){
     637           0 :           vb.visCube(); // return value not needed
     638             :         }
     639           0 :         else if(dataCols_p[datacol] == MS::CORRECTED_DATA){
     640           0 :           vb.correctedVisCube();
     641             :         }
     642           0 :         else if(dataCols_p[datacol] == MS::MODEL_DATA){
     643           0 :           vb.modelVisCube();
     644             :         }
     645             :       }
     646             : 
     647             :       // apply phase center shift to vis buffer
     648           0 :       vb.phaseCenterShift(dphase);
     649             : 
     650             :       // write changed UVWs
     651           0 :       auto origRows = vb.rowIds();
     652           0 :       for(uInt row = 0; row < numRows; row++){
     653           0 :         UVWcol.put(origRows(row), uvw.column(row));
     654             :       }
     655             : 
     656             :       // write changed visibilities
     657           0 :       for(uInt datacol = 0; datacol < nDataCols_p; datacol++){
     658           0 :         if(dataCols_p[datacol] == MS::DATA){
     659           0 :           vi.setVis(vb.visCube(),VisibilityIterator::Observed);
     660             :         }
     661           0 :         else if(dataCols_p[datacol] == MS::CORRECTED_DATA){
     662           0 :           vi.setVis(vb.correctedVisCube(),VisibilityIterator::Corrected);
     663             :         }
     664           0 :         else if(dataCols_p[datacol] == MS::MODEL_DATA){
     665           0 :           vi.setVis(vb.modelVisCube(),VisibilityIterator::Model);
     666             :         }
     667             :       }
     668             : 
     669             : 
     670             :     }
     671             :     
     672             :   }
     673             : 
     674           0 : }
     675             :   
     676             : 
     677           0 : void FixVis::ok() {
     678             :   //  AlwaysAssert(image, AipsError);
     679           0 : }
     680             : 
     681           0 : void FixVis::init()
     682             : {
     683           0 :   logSink() << LogOrigin("FixVis", "init")  << LogIO::NORMAL;
     684             : 
     685             :   //ok();
     686             : 
     687             :   //npol  = image->shape()(2);
     688             :   //nchan = image->shape()(3);
     689           0 : }
     690             : 
     691             : // Initialize FTMachine.
     692           0 : void FixVis::initializeToVis(ImageInterface<Complex>& iimage,
     693             :                              const VisBuffer&)
     694             : {
     695           0 :   image = &iimage;
     696             : 
     697           0 :   ok();
     698           0 :   init();
     699             : 
     700             :   // Initialize the maps for polarization and channel. These maps
     701             :   // translate visibility indices into image indices
     702             :   //RR initMaps(vb);
     703           0 : }
     704             : 
     705           0 : void FixVis::finalizeToVis()
     706             : {
     707           0 : }
     708             : 
     709             : // Initialize the FFT to the Sky. Here we have to setup and initialize the
     710             : // grid. 
     711           0 : void FixVis::initializeToSky(ImageInterface<Complex>& iimage,
     712             :                              Matrix<Float>&, //weight,
     713             :                              const VisBuffer&)
     714             : {
     715             :   // image always points to the image
     716           0 :   image = &iimage;
     717             : 
     718           0 :   init();
     719             : 
     720             :   // Initialize the maps for polarization and channel. These maps
     721             :   // translate visibility indices into image indices
     722             :   //RR initMaps(vb);
     723           0 : }
     724             : 
     725             : }  // End of casa namespace.
     726             : 

Generated by: LCOV version 1.16