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

          Line data    Source code
       1             : //# ImagerMultiMS.cc: Implementation of ImagerMultiMS.h
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This program is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU General Public License as published by the Free
       7             : //# Software Foundation; either version 2 of the License, or (at your option)
       8             : //# any later version.
       9             : //#
      10             : //# This program 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 General Public License for
      13             : //# more details.
      14             : //#
      15             : //# You should have received a copy of the GNU General Public License along
      16             : //# with this program; if not, write to the Free Software Foundation, Inc.,
      17             : //# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: aips2-request@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$
      27             : 
      28             : #include <cassert>
      29             : 
      30             : #include <synthesis/MeasurementEquations/ImagerMultiMS.h>
      31             : #include <synthesis/TransformMachines/VisModelData.h>
      32             : #include <casacore/casa/BasicSL/String.h>
      33             : #include <casacore/casa/Utilities/Assert.h>
      34             : #include <casacore/casa/Logging.h>
      35             : #include <casacore/casa/Logging/LogIO.h>
      36             : #include <casacore/casa/Logging/LogMessage.h>
      37             : 
      38             : #include <casacore/casa/Exceptions/Error.h>
      39             : #include <iostream>
      40             : #include <casacore/ms/MSSel/MSSelection.h>
      41             : #include <casacore/ms/MSSel/MSDataDescIndex.h>
      42             : #include <casacore/ms/MeasurementSets/MSHistoryHandler.h>
      43             : #include <casacore/ms/MeasurementSets/MeasurementSet.h>
      44             : #include <casacore/ms/MeasurementSets/MSDataDescColumns.h>
      45             : #include <casacore/ms/MeasurementSets/MSColumns.h>
      46             : #include <msvis/MSVis/SimpleSubMS.h>
      47             : #include <msvis/MSVis/SubMS.h>
      48             : #include <msvis/MSVis/VisSetUtil.h>
      49             : #include <msvis/MSVis/VisibilityIterator.h>
      50             : #include <casacore/casa/Arrays/Matrix.h>
      51             : #include <casacore/casa/Arrays/ArrayMath.h>
      52             : 
      53             : #include <casacore/tables/TaQL/ExprNode.h>
      54             : #include <casacore/tables/TaQL/TableParse.h>
      55             : #include <casacore/tables/Tables/SetupNewTab.h>
      56             : 
      57             : #include <casacore/lattices/LEL/LatticeExpr.h> 
      58             : 
      59             : #include <casacore/casa/OS/File.h>
      60             : #include <casacore/casa/OS/HostInfo.h>
      61             : #include <casacore/casa/Containers/Record.h>
      62             : 
      63             : #include <sstream>
      64             : 
      65             : using namespace casacore;
      66             : namespace casa { //# NAMESPACE CASA - BEGIN
      67             : 
      68           0 :   ImagerMultiMS::ImagerMultiMS() 
      69             :     : Imager(), blockNChan_p(0), blockStart_p(0), blockStep_p(0), blockSpw_p(0),
      70           0 :       blockMSSel_p(0), dataSet_p(false)
      71             :   {
      72             :     
      73           0 :     lockCounter_p=0;
      74           0 :     ms_p=0;
      75           0 :     mssel_p=0;
      76           0 :     se_p=0;
      77           0 :     vs_p=0;
      78           0 :     ft_p=0;
      79           0 :     cft_p=0;
      80           0 :     rvi_p=wvi_p=0;
      81           0 :     numMS_p=0;
      82             :     
      83           0 :   }
      84             : 
      85           0 :   Bool ImagerMultiMS::setDataToMemory(const String& msname, 
      86             :                                       const String& /*mode*/, 
      87             :                                    const Vector<Int>& nchan, 
      88             :                                    const Vector<Int>& start,
      89             :                                    const Vector<Int>& step,
      90             :                                       const Vector<Int>& /*spectralwindowids*/,
      91             :                                    const Vector<Int>& /*fieldids*/,
      92             :                                    const String& msSelect,
      93             :                                    const String& timerng,
      94             :                                    const String& fieldnames,
      95             :                                       const Vector<Int>& /*antIndex*/,
      96             :                                    const String& antnames,
      97             :                                    const String& spwstring,
      98             :                                    const String& uvdist,
      99             :                                       const String& scan,
     100             :                                       const String& intent,
     101             :                                       const String& obs){
     102           0 :     useModelCol_p=false;
     103           0 :     LogIO os(LogOrigin("imager", "setDataToMemory()"), logSink_p);
     104           0 :     if(!Table::isReadable(msname)){
     105             :       os << LogIO::SEVERE << "MeasurementSet " 
     106             :          << msname << " does not exist  " 
     107           0 :          << LogIO::POST;
     108           0 :       return false;
     109             :     }
     110           0 :     if(intent != ""){
     111             :        os << LogIO::WARN << "does not support INTENT selection here " 
     112           0 :          << LogIO::POST;
     113             :     }
     114           0 :     MeasurementSet thisms(msname, TableLock(TableLock::AutoNoReadLocking), 
     115           0 :                               Table::Old);
     116           0 :     SimpleSubMS splitter(thisms);
     117             :     //SubMS splitter(thisms);
     118           0 :     splitter.setmsselect(spwstring, fieldnames, antnames, scan, obs, uvdist,
     119             :                          msSelect, nchan, start, step, "");
     120           0 :     splitter.selectCorrelations("");
     121           0 :     splitter.selectTime(-1.0, timerng);
     122           0 :     MS::PredefinedColumns whichCol=MS::DATA;
     123           0 :     if(thisms.tableDesc().isColumn("CORRECTED_DATA"))
     124           0 :       whichCol=MS::CORRECTED_DATA;
     125           0 :     CountedPtr<MeasurementSet> subMS(splitter.makeMemSubMS(whichCol), true);
     126             :     //CountedPtr<MeasurementSet> subMS(splitter.makeScratchSubMS(Vector<MS::PredefinedColumns>(1,whichCol), true), true);
     127           0 :     return setDataOnThisMS(*subMS);
     128             : 
     129             :   }
     130             : 
     131             : 
     132           0 :   Bool ImagerMultiMS::setDataPerMS(const String& msname, const String& mode, 
     133             :                                    const Vector<Int>& nchan, 
     134             :                                    const Vector<Int>& start,
     135             :                                    const Vector<Int>& step,
     136             :                                    const Vector<Int>& spectralwindowids,
     137             :                                    const Vector<Int>& fieldids,
     138             :                                    const String& msSelect,
     139             :                                    const String& timerng,
     140             :                                    const String& fieldnames,
     141             :                                    const Vector<Int>& antIndex,
     142             :                                    const String& antnames,
     143             :                                    const String& spwstring,
     144             :                                    const String& uvdist,
     145             :                                    const String& scan,
     146             :                                    const String& intent,
     147             :                                    const String& obs,
     148             :                                    const Bool useModel, 
     149             :                                    const Bool readonly){
     150           0 :     useModelCol_p=useModel;
     151             :     //    Bool rd=readonly;
     152           0 :     LogIO os(LogOrigin("imager", "setDataPerMS()"), logSink_p);
     153             :     //    if(useModel) 
     154             :     //      rd=true;
     155           0 :     if(!Table::isReadable(msname)){
     156             :       os << LogIO::SEVERE << "MeasurementSet " 
     157             :          << msname << " does not exist  " 
     158           0 :          << LogIO::POST;
     159           0 :       return false;
     160             :     }
     161             :     else{
     162           0 :       MeasurementSet thisms;
     163           0 :       if(!readonly)
     164           0 :         thisms=MeasurementSet(msname, TableLock(TableLock::AutoNoReadLocking), 
     165           0 :                               Table::Update);
     166             :       else
     167           0 :        thisms=MeasurementSet(msname, TableLock(TableLock::AutoNoReadLocking), 
     168           0 :                               Table::Old);
     169             :       //thisms=MeasurementSet(msname, TableLock(), 
     170             :       //                              Table::Old);
     171             :       
     172           0 :       thisms.setMemoryResidentSubtables (MrsEligibility::defaultEligible());
     173             : 
     174           0 :       return setDataOnThisMS(thisms, mode, nchan, start, step, spectralwindowids, fieldids, msSelect, timerng, 
     175           0 :                              fieldnames, antIndex, antnames, spwstring, uvdist, scan, intent, obs);  
     176             :       
     177             :     }
     178             :     
     179             :   }
     180             : 
     181             : 
     182             : 
     183           0 :   Bool ImagerMultiMS::setDataOnThisMS(MeasurementSet& thisms, const String& mode, 
     184             :                                    const Vector<Int>& nchan, 
     185             :                                    const Vector<Int>& start,
     186             :                                    const Vector<Int>& step,
     187             :                                    const Vector<Int>& spectralwindowids,
     188             :                                    const Vector<Int>& fieldids,
     189             :                                    const String& msSelect,
     190             :                                    const String& timerng,
     191             :                                    const String& fieldnames,
     192             :                                    const Vector<Int>& antIndex,
     193             :                                    const String& antnames,
     194             :                                    const String& spwstring,
     195             :                                    const String& uvdist,
     196             :                                       const String& scan,
     197             :                                       const String& intent,
     198             :                                       const String& obs){
     199           0 :     LogIO os(LogOrigin("imager", "setDataOnThisMS()"), logSink_p);  
     200             : 
     201             : 
     202           0 :     dataMode_p=mode;
     203           0 :     dataNchan_p.resize();
     204           0 :     dataStart_p.resize();
     205           0 :     dataStep_p.resize();
     206           0 :     dataNchan_p=nchan;
     207           0 :     dataStart_p=start;
     208           0 :     dataStep_p=step;
     209           0 :     dataspectralwindowids_p.resize(spectralwindowids.nelements());
     210           0 :     dataspectralwindowids_p=spectralwindowids;
     211           0 :     datafieldids_p.resize(fieldids.nelements());
     212           0 :     datafieldids_p=fieldids;
     213             :     
     214             : 
     215             : 
     216             :     //make ms
     217             :     // auto lock for now
     218             :     // make ms and visset
     219           0 :     ++numMS_p;
     220           0 :     blockMSSel_p.resize(numMS_p);
     221           0 :     blockNChan_p.resize(numMS_p);
     222           0 :     blockStart_p.resize(numMS_p);
     223           0 :     blockStep_p.resize(numMS_p);
     224           0 :     blockSpw_p.resize(numMS_p);
     225             :     //Using autolocking here 
     226             :     //Will need to rethink this when in parallel mode with multi-cpu access
     227           0 :     blockMSSel_p[numMS_p-1]=thisms;
     228             :     //breaking reference
     229           0 :     if(ms_p.null())
     230           0 :       ms_p=new MeasurementSet();
     231             :     else
     232           0 :       (*ms_p)=MeasurementSet();
     233           0 :     (*ms_p)=thisms;
     234             :     
     235             :     
     236             :     try{
     237           0 :       openSubTables();
     238             :       
     239             :       //if spectralwindowids=-1 take all
     240           0 :       if(mode=="none" && 
     241           0 :          (spectralwindowids.nelements()==1 && spectralwindowids[0]<0)){
     242           0 :         Int nspw=thisms.spectralWindow().nrow();
     243           0 :         dataspectralwindowids_p.resize(nspw);
     244           0 :         indgen(dataspectralwindowids_p);
     245             :         
     246             :       }
     247             :       
     248             :       // If a selection has been made then close the current MS
     249             :       // and attach to a new selected MS. We do this on the original
     250             :       // MS.
     251             :       //I don't think i need this if statement
     252             :       //   if(datafieldids_p.nelements()>0||datadescids_p.nelements()>0) {
     253           0 :       os << "Performing selection on MeasurementSet : " << thisms.tableName() << LogIO::POST;
     254             :       //if(vs_p) delete vs_p; vs_p=0;
     255             :       //if(mssel_p) delete mssel_p; 
     256           0 :       mssel_p=0;
     257             :       
     258             :       // check that sorted table exists (it should), if not, make it now.
     259             :       //this->makeVisSet(thisms);
     260             :       
     261             :       //if you want to use scratch col...make sure they are there
     262           0 :       if(useModelCol_p){
     263           0 :         VisSetUtil::addScrCols(thisms, true, false, true, false);
     264           0 :         VisModelData::clearModel(thisms);
     265             :       }
     266             :       //MeasurementSet sorted=thisms.keywordSet().asTable("SORTED_TABLE");
     267             :       
     268             :       
     269             :       //Some MSSelection 
     270           0 :       MSSelection thisSelection;
     271           0 :       if(datafieldids_p.nelements() > 0){
     272           0 :         thisSelection.setFieldExpr(MSSelection::indexExprStr(datafieldids_p));
     273           0 :         os << "Selecting on field ids : " << datafieldids_p << LogIO::POST;
     274             :       }
     275           0 :       if(fieldnames != ""){
     276           0 :         thisSelection.setFieldExpr(fieldnames);
     277           0 :         os << "Selecting on fields : " << fieldnames << LogIO::POST;
     278             :       }
     279           0 :       if(dataspectralwindowids_p.nelements() > 0){
     280           0 :         thisSelection.setSpwExpr(MSSelection::indexExprStr(dataspectralwindowids_p));
     281           0 :         os << "Selecting on spectral windows" << LogIO::POST;
     282             :       }
     283           0 :       else if(spwstring != ""){
     284           0 :         thisSelection.setSpwExpr(spwstring);
     285           0 :         os << "Selecting on spectral windows expression :"<< spwstring  << LogIO::POST;
     286             :       }
     287           0 :       if(antIndex.nelements() >0){
     288           0 :         thisSelection.setAntennaExpr( MSSelection::indexExprStr(antIndex) );
     289           0 :         os << "Selecting on antenna ids : " << antIndex << LogIO::POST;     
     290             :       }
     291           0 :       if(antnames != ""){
     292           0 :         Vector<String> antNames(1, antnames);
     293             :         // thisSelection.setAntennaExpr(MSSelection::nameExprStr( antNames));
     294           0 :         thisSelection.setAntennaExpr(antnames);
     295           0 :         os << "Selecting on antenna names : " << antnames << LogIO::POST;
     296             :         
     297             :       }            
     298           0 :       if(timerng != ""){
     299           0 :         thisSelection.setTimeExpr(timerng);
     300           0 :         os << "Selecting on time range : " << timerng << LogIO::POST;       
     301             :       }
     302           0 :       if(uvdist != ""){
     303           0 :         thisSelection.setUvDistExpr(uvdist);
     304           0 :         os << "Selecting on uvdist : " << uvdist << LogIO::POST;    
     305             :       }
     306           0 :       if(scan != ""){
     307           0 :         thisSelection.setScanExpr(scan);
     308           0 :         os << "Selecting on scan : " << scan << LogIO::POST;        
     309             :       }
     310           0 :       if(intent != ""){
     311           0 :         thisSelection.setStateExpr(intent);
     312           0 :         os << "Selecting on State(scan intent) Expr " << intent << LogIO::POST;     
     313             :       }
     314           0 :       if(obs != ""){
     315           0 :         thisSelection.setObservationExpr(obs);
     316           0 :         os << "Selecting on Observation Expr : " << obs << LogIO::POST;     
     317             :       }
     318           0 :       if(msSelect != ""){
     319           0 :         thisSelection.setTaQLExpr(msSelect);
     320           0 :         os << "Selecting via TaQL : " << msSelect << LogIO::POST;   
     321             :       }
     322             :       //***************
     323             :       
     324           0 :       TableExprNode exprNode=thisSelection.toTableExprNode(&thisms);
     325             :       //if(exprNode.isNull())
     326             :       //        throw(AipsError("Selection failed...review ms and selection parameters"));
     327           0 :       datafieldids_p.resize();
     328           0 :       datafieldids_p=thisSelection.getFieldList();
     329           0 :       if(datafieldids_p.nelements()==0){
     330           0 :         Int nf=ms_p->field().nrow();
     331           0 :         datafieldids_p.resize(nf);
     332           0 :         indgen(datafieldids_p);
     333             :       }
     334           0 :       if((numMS_p > 1) || datafieldids_p.nelements() > 1)
     335           0 :         multiFields_p= true;
     336             :       //Now lets see what was selected as spw and match it with datadesc
     337             :       //dataspectralwindowids_p.resize();
     338             :       //dataspectralwindowids_p=thisSelection.getSpwList();
     339           0 :       Matrix<Int> chansels=thisSelection.getChanList(NULL, 1, true);
     340           0 :       mssFreqSel_p.resize();
     341           0 :       mssFreqSel_p=thisSelection.getChanFreqList(NULL, true);
     342             :      
     343           0 :       uInt nms = numMS_p;
     344           0 :       uInt nrow = chansels.nrow(); 
     345           0 :       dataspectralwindowids_p.resize();
     346           0 :       const MSSpWindowColumns spwc(thisms.spectralWindow());
     347           0 :       uInt nspw = spwc.nrow();
     348           0 :       const ScalarColumn<Int> spwNchans(spwc.numChan());
     349           0 :       Vector<Int> nchanvec = spwNchans.getColumn();
     350             :       //cerr<<"SetDataOnThisMS::numMS_p="<<numMS_p<<" nchanvec="<<nchanvec<<endl;
     351           0 :       Int maxnchan = 0;
     352             :       
     353           0 :       for (uInt i=0;i<nchanvec.nelements();i++) {
     354           0 :         maxnchan=max(nchanvec[i],maxnchan);
     355             :       }
     356             :       //cout<<"spwchansels_p.shape()="<<spwchansels_p.shape()<<endl;
     357           0 :       uInt maxnspw = 0;
     358           0 :       if (numMS_p ==1) {
     359           0 :         maxnspw=nspw;
     360             :       }
     361             :       else {
     362           0 :         for (Int i=0;i<numMS_p-1;i++) {
     363           0 :           maxnspw=max(maxnspw,blockSpw_p[i].nelements());
     364             :         }
     365           0 :         maxnspw=max(nspw,maxnspw);
     366             :       }
     367           0 :       spwchansels_p.resize(nms,maxnspw,maxnchan,true);
     368             :       //cout<<"After resize: spwchansels_p.shape()="<<spwchansels_p.shape()<<endl;
     369           0 :       uInt nselspw=0;
     370           0 :       if (nrow==0) {
     371             :         //no channel selection, select all channels
     372           0 :         spwchansels_p.yzPlane(numMS_p-1)=1; 
     373           0 :         dataspectralwindowids_p=thisSelection.getSpwList();
     374             :       }
     375             :       else {
     376           0 :         spwchansels_p.yzPlane(numMS_p-1)=0; 
     377           0 :         Int prvspwid=-1;
     378           0 :         Vector<Int> selspw;
     379           0 :         for (uInt i=0;i<nrow;i++) {
     380           0 :           Vector<Int> sel = chansels.row(i);
     381           0 :           Int spwid = sel[0];
     382           0 :           if((sel[1] >= nchanvec[spwid]) || (sel[2] >=nchanvec[spwid]))
     383           0 :             throw(AipsError("Unexpected selection  in spw selection of spwid "+String::toString(spwid)));
     384           0 :           if (spwid != prvspwid){
     385           0 :             nselspw++;
     386           0 :             selspw.resize(nselspw,true);
     387           0 :             selspw[nselspw-1]=spwid;
     388             :           }
     389           0 :           uInt minc= sel[1];
     390           0 :           uInt maxc = sel[2];
     391           0 :           uInt step = sel[3];
     392             :           // step as the same context as in im.selectvis
     393             :           // select channels
     394           0 :           for (uInt k=minc;k<(maxc+1);k+=step) {
     395           0 :             spwchansels_p(numMS_p-1,spwid,k)=1;
     396             :           }
     397           0 :           prvspwid=spwid;
     398             :         }
     399           0 :         dataspectralwindowids_p=selspw;
     400             :       }
     401             :       
     402             :       //cout<<"spwchansels_p(before shifting)="<<spwchansels_p<<endl;
     403           0 :       if(dataspectralwindowids_p.nelements()==0){
     404           0 :         Int nspwinms=thisms.spectralWindow().nrow();
     405           0 :         dataspectralwindowids_p.resize(nspwinms);
     406           0 :         indgen(dataspectralwindowids_p);
     407             :       }
     408             :       
     409             :       // old code
     410             :       /***
     411             :           if(dataspectralwindowids_p.nelements()==0){
     412             :           Int nspwinms=thisms.spectralWindow().nrow();
     413             :           dataspectralwindowids_p.resize(nspwinms);
     414             :           indgen(dataspectralwindowids_p);
     415             :           }
     416             :       ***/
     417             :       
     418             :       // Map the selected spectral window ids to data description ids
     419           0 :       MSDataDescIndex msDatIndex(thisms.dataDescription());
     420           0 :       datadescids_p.resize(0);
     421           0 :       datadescids_p=msDatIndex.matchSpwId(dataspectralwindowids_p);
     422             :       
     423           0 :       freqrange_p.resize(nms,2,true);
     424           0 :       if(mode=="none"){
     425             :         //check if we can find channel selection in the spw string
     426             :         //if(nselspw==dataspectralwindowids_p.nelements()){
     427           0 :         dataMode_p="channel";
     428           0 :         dataStep_p.resize(dataspectralwindowids_p.nelements());
     429           0 :         dataStart_p.resize(dataspectralwindowids_p.nelements());
     430           0 :         dataNchan_p.resize(dataspectralwindowids_p.nelements());
     431           0 :         Double fmin=C::dbl_max;
     432           0 :         Double fmax=-(C::dbl_max);
     433             :         
     434           0 :         Cube<Int> spwchansels_tmp=spwchansels_p;
     435           0 :         for (uInt k =0 ; k < dataspectralwindowids_p.nelements(); ++k){
     436           0 :           uInt curspwid=dataspectralwindowids_p[k];
     437           0 :           Vector<Double> chanFreq=spwc.chanFreq()(curspwid);
     438           0 :           Vector<Double> freqResolution = spwc.chanWidth()(curspwid);
     439             :           
     440             :           
     441             :           //dataStep_p[k]=chanselmat.row(k)(3);
     442           0 :           if (nrow==0) {
     443             :             //dataStep_p=step[0];
     444           0 :             dataStep_p[k]=step[0];
     445             :           }
     446             :           else {
     447           0 :             dataStep_p[k]=chansels.row(k)(3);
     448             :           }
     449             :           //if(dataStep_p[k] < 1)
     450             :           //  dataStep_p[k]=1;
     451           0 :           dataStart_p[k]=0;
     452           0 :           dataNchan_p[k]=nchanvec(curspwid);
     453             :           //cout<<"SetDataOnThisMS: initial setting dataNchan_p["<<k<<"]="<<dataNchan_p[k]<<endl;
     454             :           //find start
     455           0 :           Bool first = true;
     456           0 :           uInt nchn = 0;
     457           0 :           uInt lastchan = 0;
     458           0 :           for (Int j=0 ; j < nchanvec(curspwid); j++) {
     459           0 :             if (spwchansels_p(numMS_p-1,curspwid,j)==1) {
     460           0 :               if(first) {
     461           0 :                 dataStart_p[k]=j;
     462           0 :                 first = false;
     463             :               }
     464           0 :               lastchan=j;
     465           0 :               nchn++;
     466             :             }
     467             :           }
     468             :           //dataStart_p[k]=chanselmat.row(k)(1);
     469             :           //dataNchan_p[k]=Int(ceil(Double(chanselmat.row(k)(2)-dataStart_p[k]))/Double(dataStep_p[k]))+1;
     470           0 :           dataNchan_p[k]=Int(ceil(Double(lastchan-dataStart_p[k])/Double(dataStep_p[k])))+1;
     471             :           //cout<<"SetDataOnThisMS: after recalc. of nchan dataNchan_p["<<k<<"]="<<dataNchan_p[k]<<endl;
     472             :           //if(dataNchan_p[k]<1)
     473             :           //  dataNchan_p[k]=1;
     474             :           // 
     475             :           //Since msselet will be applied to the data before flags from spwchansels_p
     476             :           //are applied to the data in FTMachine, shift spwchansels_p by dataStart_p
     477           0 :           for (Int j=0  ; j < nchanvec(curspwid); j++){
     478           0 :             if (j<nchanvec(curspwid)-dataStart_p[k]) {
     479           0 :               spwchansels_tmp(numMS_p-1,curspwid,j) = spwchansels_p(numMS_p-1,curspwid,j+dataStart_p[k]);
     480             :             }
     481             :             else {
     482           0 :               spwchansels_tmp(numMS_p-1,curspwid,j) = 0;
     483             :             }
     484             :           }
     485             :           //for mfs mode need to keep fmin,max info for later image setup
     486             :           //Int lastchan=dataStart_p[k]+ dataNchan_p[k]*dataStep_p[k];
     487             :           Int endchanused;
     488           0 :           if (nrow==0) {
     489             :             // default spw case
     490           0 :             endchanused=nchanvec(curspwid);
     491             :           }
     492             :           else {
     493           0 :             endchanused=lastchan;
     494             :           }
     495           0 :           for(Int j=dataStart_p[k] ; j < endchanused ;  j+=dataStep_p[k]){
     496           0 :             fmin=min(fmin,chanFreq[j]-abs(freqResolution[j]*(dataStep_p[k]-0.5)));
     497           0 :             fmax=max(fmax,chanFreq[j]+abs(freqResolution[j]*(dataStep_p[k]-0.5)));
     498             :           }
     499             :         }
     500             :         //cerr<<"numMS_p="<<numMS_p<<" fmin="<<fmin<<" fmax="<<fmax<<endl;
     501           0 :         freqrange_p(numMS_p-1,0)=fmin;
     502           0 :         freqrange_p(numMS_p-1,1)=fmax;
     503             :         
     504           0 :         spwchansels_p=spwchansels_tmp;
     505             :         //}
     506             :       }
     507             :       
     508             :       
     509             :       
     510             :       // Now remake the selected ms
     511           0 :       if(!(exprNode.isNull())){
     512           0 :         mssel_p = new MeasurementSet(thisms(exprNode));
     513             :       }
     514             :       else{
     515             :         // Null take all the ms ...setdata() blank means that
     516           0 :         mssel_p = new MeasurementSet(thisms);
     517             :       } 
     518           0 :       AlwaysAssert(!mssel_p.null(), AipsError);
     519           0 :       if(mssel_p->nrow()==0) {
     520             :         //delete mssel_p; 
     521           0 :         mssel_p=0;
     522             :         
     523             :         os << "Selection is empty: you may want to review this MSs selection"
     524           0 :            << LogIO::EXCEPTION;
     525             :       }
     526             :       else {
     527           0 :         mssel_p->flush();
     528             :       }
     529             :       
     530           0 :       if(mssel_p->nrow()!=thisms.nrow()) {
     531           0 :         os << "Selected " << mssel_p->nrow() << " out of  "
     532           0 :            << thisms.nrow() << " rows." << LogIO::POST;
     533             :       }
     534             :       else {
     535           0 :         os << "Selected all " << mssel_p->nrow() << " rows" << LogIO::POST;
     536             :       }
     537             :       //  }
     538             :       
     539             :       // Tell the user how many channels have been selected.
     540             :       // NOTE : This code is replicated in Imager.cc.
     541           0 :       Vector<Int> chancounts(dataspectralwindowids_p.nelements());
     542           0 :       chancounts=0;
     543             :       //    if( spwstring == "" ) os << "Selected all spws and channels" << LogIO::POST;
     544             :       //   else os << "Channel selection : " << spwstring << LogIO::POST;
     545           0 :       os << "Selected :";
     546           0 :       for(uInt k=0;k<dataspectralwindowids_p.nelements();k++)
     547             :         {
     548           0 :           for(uInt ch=0;ch<uInt(nchanvec(dataspectralwindowids_p[k]));ch++) 
     549           0 :             {if(spwchansels_p(numMS_p-1,dataspectralwindowids_p[k],ch)) chancounts[k]++; }
     550             :           //if(chancounts[k]<1)
     551             :           //  throw(AipsError("bad selection in spw "+ String::toString( dataspectralwindowids_p[k])));
     552           0 :           os << " [" << chancounts[k] << " chans in spw " << dataspectralwindowids_p[k] << "]";
     553             :           //    os << "Selected " << chancounts[k] << " chans in spw " 
     554             :           //       << dataspectralwindowids_p[k] << LogIO::POST;
     555             :         }
     556           0 :       os << LogIO::POST;
     557             :       
     558             :       
     559           0 :       blockMSSel_p[numMS_p-1]=*mssel_p;
     560             :       //lets make the visSet now
     561           0 :       Block<Matrix<Int> > noChanSel;
     562           0 :       noChanSel.resize(numMS_p);
     563           0 :       Block<Int> sort(0);
     564             :       //if(vs_p) delete vs_p; vs_p=0;
     565           0 :       if(rvi_p) delete rvi_p;
     566           0 :       rvi_p=0;
     567           0 :       wvi_p=0;
     568             :       
     569             :       //vs_p= new VisSet(blockMSSel_p, sort, noChanSel, useModelCol_p);
     570           0 :       if(!(mssel_p->isWritable())){
     571           0 :         rvi_p=new ROVisibilityIterator(blockMSSel_p, sort);
     572             :         
     573             :       }
     574             :       else{
     575           0 :         wvi_p=new VisibilityIterator(blockMSSel_p, sort);
     576           0 :         rvi_p=wvi_p;    
     577             :       }
     578             :       
     579           0 :       if(imwgt_p.getType()=="none")
     580           0 :         imwgt_p=VisImagingWeight("natural");
     581           0 :       rvi_p->useImagingWeight(imwgt_p);
     582             :       //rvi_p->slurp();
     583             :       
     584           0 :       selectDataChannel();
     585           0 :       dataSet_p=true;
     586             :       
     587           0 :       return dataSet_p;
     588             :     }
     589           0 :     catch(AipsError x){
     590             :       //Ayeee...lets back out of this one
     591           0 :       --numMS_p;
     592           0 :       blockMSSel_p.resize(numMS_p, true);
     593           0 :       blockNChan_p.resize(numMS_p, true);
     594           0 :       blockStart_p.resize(numMS_p, true);
     595           0 :       blockStep_p.resize(numMS_p, true);
     596           0 :       blockSpw_p.resize(numMS_p, true);
     597             :       //point it back to the previous ms
     598           0 :       if(numMS_p >0){
     599           0 :         mssel_p=new MeasurementSet(blockMSSel_p[numMS_p-1]);
     600             :       }
     601           0 :       throw(AipsError(x));
     602             :     }
     603             : 
     604             :     } //End of setDataPerMS
     605             :     
     606             : 
     607           0 : Bool ImagerMultiMS::setimage(const Int nx, const Int ny,
     608             :                              const Quantity& cellx, const Quantity& celly,
     609             :                              const String& stokes,
     610             :                              Bool doShift,
     611             :                              const MDirection& phaseCenter, 
     612             :                              const Quantity& shiftx, const Quantity& shifty,
     613             :                              const String& mode, const Int nchan,
     614             :                              const Int start, const Int step,
     615             :                              const MRadialVelocity& mStart, 
     616             :                              const MRadialVelocity& mStep,
     617             :                              const Vector<Int>& spectralwindowids,
     618             :                              const Int fieldid,
     619             :                              const Int facets,
     620             :                              const Quantity& distance)
     621             : {
     622             : 
     623           0 :   if(!dataSet_p){
     624           0 :     LogIO os(LogOrigin("imagerMultiMS", "setimage()"), logSink_p);  
     625             :     os << LogIO::SEVERE 
     626             :        << "Please use setdata before setimage as imager need one ms at least " 
     627           0 :        << LogIO::POST;
     628           0 :     return false;
     629             : 
     630             :   }
     631             : 
     632           0 :   Bool returnval=Imager::setimage(nx, ny, cellx, celly, stokes,doShift,
     633             :                                   phaseCenter, shiftx, shifty, mode, nchan,
     634             :                                   start, step, mStart, mStep, 
     635             :                                   spectralwindowids, 
     636             :                                   fieldid, facets, distance);
     637             : 
     638           0 :   return returnval;
     639             : }
     640             : 
     641           0 :   Bool ImagerMultiMS::lock(){
     642             :     //Do nothing for now as its Autolocked..but a better scheme is necessary
     643             :     //for parallel access to same data for modification
     644             : 
     645           0 :     return true;
     646             :   }
     647             : 
     648           0 :   Bool ImagerMultiMS::unlock(){
     649             : 
     650           0 :     for (uInt k=0; k < blockMSSel_p.nelements(); ++k){
     651           0 :       blockMSSel_p[k].relinquishAutoLocks(true);
     652             :     }
     653           0 :     return true;
     654             : 
     655             :   }
     656             : 
     657             : 
     658           0 :   Bool ImagerMultiMS::selectDataChannel(){
     659             : 
     660           0 :     LogIO os(LogOrigin("imager", "selectDataChannel()"), logSink_p);
     661             : 
     662           0 :     (blockNChan_p[numMS_p-1]).resize(dataspectralwindowids_p.nelements());
     663           0 :     (blockStart_p[numMS_p-1]).resize(dataspectralwindowids_p.nelements());
     664           0 :     (blockStart_p[numMS_p-1]).set(0);
     665           0 :     (blockStep_p[numMS_p-1]).resize(dataspectralwindowids_p.nelements());
     666           0 :     (blockStep_p[numMS_p-1]).set(1);
     667           0 :     (blockSpw_p[numMS_p-1]).resize(dataspectralwindowids_p.nelements());
     668           0 :     (blockSpw_p[numMS_p-1]).resize();
     669           0 :     (blockSpw_p[numMS_p-1])=dataspectralwindowids_p;
     670             :     {
     671             :       //Fill default numChan for now
     672             :       
     673           0 :       MSSpWindowColumns msSpW(ms_p->spectralWindow());
     674           0 :       Vector<Int> numChan=msSpW.numChan().getColumn(); 
     675           0 :       for (uInt k=0; k < dataspectralwindowids_p.nelements(); ++k){
     676           0 :         blockNChan_p[numMS_p-1][k]=numChan[dataspectralwindowids_p[k]];
     677             : 
     678             :       }
     679             :     }
     680             : 
     681           0 :      if(dataMode_p=="channel") {
     682             : 
     683           0 :       if (dataNchan_p.nelements() != dataspectralwindowids_p.nelements()){
     684           0 :         if(dataNchan_p.nelements()==1){
     685           0 :           dataNchan_p.resize(dataspectralwindowids_p.nelements(), true);
     686           0 :           for(uInt k=1; k < dataspectralwindowids_p.nelements(); ++k){
     687           0 :             dataNchan_p[k]=dataNchan_p[0];
     688             :           }
     689             :         }
     690             :         else{
     691             :           os << LogIO::SEVERE 
     692             :              << "Vector of nchan has to be of size 1 or be of the same shape as spw " 
     693           0 :              << LogIO::POST;
     694           0 :           return false; 
     695             :         }
     696             :       }
     697           0 :       if (dataStart_p.nelements() != dataspectralwindowids_p.nelements()){
     698           0 :         if(dataStart_p.nelements()==1){
     699           0 :           dataStart_p.resize(dataspectralwindowids_p.nelements(), true);
     700           0 :           for(uInt k=1; k < dataspectralwindowids_p.nelements(); ++k){
     701           0 :             dataStart_p[k]=dataStart_p[0];
     702             :           }
     703             :         }
     704             :         else{
     705             :           os << LogIO::SEVERE 
     706             :              << "Vector of start has to be of size 1 or be of the same shape as spw " 
     707           0 :              << LogIO::POST;
     708           0 :           return false; 
     709             :         }
     710             :       }
     711           0 :       if (dataStep_p.nelements() != dataspectralwindowids_p.nelements()){
     712           0 :         if(dataStep_p.nelements()==1){
     713           0 :           dataStep_p.resize(dataspectralwindowids_p.nelements(), true);
     714           0 :           for(uInt k=1; k < dataspectralwindowids_p.nelements(); ++k){
     715           0 :             dataStep_p[k]=dataStep_p[0];
     716             :           }
     717             :         }
     718             :         else{
     719             :           os << LogIO::SEVERE 
     720             :              << "Vector of step has to be of size 1 or be of the same shape as spw " 
     721           0 :              << LogIO::POST;
     722           0 :           return false; 
     723             :         }
     724             :       }
     725             : 
     726             :        {
     727           0 :         Int nch=0;
     728           0 :         for(uInt i=0;i<dataspectralwindowids_p.nelements();i++) {
     729           0 :           Int spwid=dataspectralwindowids_p(i);
     730           0 :           if(dataStart_p[i]<0) {
     731             :             os << LogIO::SEVERE << "Illegal start pixel = " 
     732           0 :                << dataStart_p[i]  << " for spw " << spwid
     733           0 :                << LogIO::POST;
     734           0 :             return false;
     735             :           }
     736             :          
     737           0 :           if(dataNchan_p[i]<=0){
     738           0 :             if(dataStep_p[i] <= 0)
     739           0 :               dataStep_p[i]=1;
     740           0 :             nch=(blockNChan_p[numMS_p-1](i)-dataStart_p[i])/Int(dataStep_p[i])+1;
     741             :             
     742             :           }
     743           0 :           else nch = dataNchan_p[i];
     744           0 :           while((nch*dataStep_p[i]+dataStart_p[i]) >
     745           0 :                 blockNChan_p[numMS_p-1](i)){
     746           0 :             --nch;
     747             :           }
     748           0 :           Int end = Int(dataStart_p[i]) + Int(nch-1) * Int(dataStep_p[i]);
     749           0 :           if(end < 0 || end > (blockNChan_p[numMS_p-1](i)-1)) {
     750           0 :             os << LogIO::SEVERE << "Illegal step pixel = " << dataStep_p[i]
     751             :                << " for spw " << spwid
     752             :                << "\n end channel " << end << " out of range " 
     753           0 :                << dataStart_p[i] << " to "   
     754           0 :                << (blockNChan_p[numMS_p-1](i)-1)
     755             : 
     756           0 :                << LogIO::POST;
     757           0 :             return false;
     758             :           }
     759             :           os << LogIO::DEBUG1 << "Selecting "<< nch
     760             :              << " channels, starting at visibility channel "
     761           0 :              << dataStart_p[i]  << " stepped by "
     762           0 :              << dataStep_p[i] << " for spw " << spwid << LogIO::POST;
     763           0 :           dataNchan_p[i]=nch;
     764           0 :           blockNChan_p[numMS_p-1][i]=nch;
     765           0 :           blockStep_p[numMS_p-1][i]=dataStep_p[i];
     766           0 :           blockStart_p[numMS_p-1][i]=dataStart_p[i];
     767             :         }
     768             :        }
     769             :      
     770             :      }
     771             :  
     772           0 :      Block<Vector<Int> > blockGroup(numMS_p);
     773           0 :      for (Int k=0; k < numMS_p; ++k){
     774           0 :        blockGroup[k].resize(blockSpw_p[k].nelements());
     775           0 :        blockGroup[k].set(1);
     776             :      }
     777             : 
     778           0 :      rvi_p->selectChannel(blockGroup, blockStart_p, blockNChan_p, 
     779           0 :                           blockStep_p, blockSpw_p);
     780           0 :      return true;
     781             :   }
     782             : 
     783           0 :   Bool ImagerMultiMS::openSubTables(){
     784             : 
     785             :       // Reopen disk-resident tables with the default table lock
     786             : 
     787           0 :       if((ms_p->tableType()) != Table::Memory){
     788             : 
     789           0 :           TableLock tableLock; // default table lock
     790             : 
     791           0 :           openSubTable (ms_p->antenna(), antab_p, tableLock);
     792           0 :           openSubTable (ms_p->dataDescription (), datadesctab_p, tableLock);
     793           0 :           openSubTable (ms_p->doppler(), dopplertab_p, tableLock);
     794           0 :           openSubTable (ms_p->feed(), feedtab_p, tableLock);
     795           0 :           openSubTable (ms_p->field(), fieldtab_p, tableLock);
     796           0 :           openSubTable (ms_p->flagCmd(), flagcmdtab_p, tableLock);
     797           0 :           openSubTable (ms_p->freqOffset(), freqoffsettab_p, tableLock);
     798           0 :           openSubTable (ms_p->observation(), obstab_p, tableLock);
     799           0 :           openSubTable (ms_p->pointing(), pointingtab_p, tableLock);
     800           0 :           openSubTable (ms_p->polarization(), poltab_p, tableLock);
     801           0 :           openSubTable (ms_p->processor(), proctab_p, tableLock);
     802           0 :           openSubTable (ms_p->source(), sourcetab_p, tableLock);
     803           0 :           openSubTable (ms_p->spectralWindow(), spwtab_p, tableLock);
     804           0 :           openSubTable (ms_p->state(), statetab_p, tableLock);
     805           0 :           openSubTable (ms_p->sysCal(), syscaltab_p, tableLock);
     806           0 :           openSubTable (ms_p->weather(), weathertab_p, tableLock);
     807             : 
     808             :           // Handle the history table specially
     809             : 
     810           0 :           if(ms_p->isWritable()){
     811             : 
     812           0 :               if(!(Table::isReadable(ms_p->historyTableName()))){
     813             : 
     814             :                   // setup a new table in case its not there
     815           0 :                   TableRecord &kws = ms_p->rwKeywordSet();
     816           0 :                   SetupNewTable historySetup(ms_p->historyTableName(),
     817           0 :                                              MSHistory::requiredTableDesc(),Table::New);
     818           0 :                   kws.defineTable(MS::keywordName(MS::HISTORY), Table(historySetup));
     819             : 
     820             :               }
     821             : 
     822           0 :               historytab_p=Table(ms_p->historyTableName(), TableLock(), Table::Update);
     823             : 
     824           0 :               hist_p= new MSHistoryHandler(*ms_p, "imager");
     825             :           }
     826             :       }
     827             : 
     828           0 :       return true;
     829             :   }
     830             : 
     831             : #define INITIALIZE_DIRECTION_VECTOR(name) \
     832             :     do { \
     833             :         if (name.nelements() < 2) { \
     834             :             name.resize(2); \
     835             :             name = 0.0; \
     836             :         } \
     837             :     } while (false)
     838           0 :  Bool ImagerMultiMS::mapExtent(const String &referenceFrame, const String &movingSource,
     839             :           const String &pointingColumn, Vector<Double> &center, Vector<Double> &blc,
     840             :           Vector<Double> &trc, Vector<Double> &extent) {
     841             :       // initialize if necessary
     842           0 :       INITIALIZE_DIRECTION_VECTOR(center);
     843           0 :       INITIALIZE_DIRECTION_VECTOR(blc);
     844           0 :       INITIALIZE_DIRECTION_VECTOR(trc);
     845           0 :       INITIALIZE_DIRECTION_VECTOR(extent);
     846             : 
     847             :       try {
     848           0 :           Bool isValueSet = false;
     849           0 :           for (size_t i = 0; i < blockMSSel_p.nelements(); ++i) {
     850             :               //cout << "start MS " << i << endl;
     851           0 :               MeasurementSet ms = blockMSSel_p[i];
     852           0 :               Vector<Double> wcenter(2);
     853           0 :               Vector<Double> wblc(2);
     854           0 :               Vector<Double> wtrc(2);
     855           0 :               Vector<Double> wextent(2);
     856             :               //cout << "run getMapExtent" << endl;
     857           0 :               Bool status = getMapExtent(ms, referenceFrame, movingSource, pointingColumn,
     858             :                       wcenter, wblc, wtrc, wextent);
     859             :               //cout << "done Imager::mapExtent" << endl;
     860           0 :               if (status) {
     861           0 :                   if (!isValueSet) {
     862           0 :                       center = wcenter;
     863           0 :                       blc = wblc;
     864           0 :                       trc = wtrc;
     865           0 :                       extent = wextent;
     866           0 :                       isValueSet = true;
     867             :                   }
     868             :                   else {
     869           0 :                       blc[0] = min(blc[0], wblc[0]);
     870           0 :                       blc[1] = min(blc[1], wblc[1]);
     871           0 :                       trc[0] = max(trc[0], wtrc[0]);
     872           0 :                       trc[1] = max(trc[1], wtrc[1]);
     873             :                   }
     874             :               }
     875             :           }
     876             : 
     877           0 :           if (!isValueSet) {
     878           0 :               LogIO os(LogOrigin("ImagerMultiMS", "mapExtent", WHERE));
     879           0 :               os << LogIO::SEVERE << "No valid data found. Failed." << LogIO::POST;
     880             : 
     881           0 :               return false;
     882             :           }
     883             : 
     884             :           // extent is re-evaluated using true trc and blc
     885           0 :           extent = trc - blc;
     886             : 
     887             :           // declination correction factor
     888           0 :           Double declinationCorrection = cos(center[1]);
     889             : 
     890             :           // center needs to be updated according to specified column name
     891             :           // and moving source name
     892             :           MDirection::Types refType;
     893           0 :           Bool status = MDirection::getType(refType, movingSource);
     894           0 :           Bool doMovingSourceCorrection = (status == true &&
     895           0 :                   MDirection::N_Types < refType &&
     896           0 :                   refType < MDirection::N_Planets);
     897           0 :           Bool isOffsetColumn = (pointingColumn.contains("OFFSET")
     898           0 :                   || pointingColumn.contains("Offset")
     899           0 :                   || pointingColumn.contains("offset"));
     900           0 :           if (isOffsetColumn) {
     901             :               // center is always (0,0)
     902           0 :               center = 0.0;
     903           0 :               declinationCorrection = cos((blc[1] + trc[1]) / 2.0);
     904             :           }
     905           0 :           else if (!doMovingSourceCorrection) {
     906             :               // initial center value should be kept
     907             :               // if doMovingSourceCorrection is true.
     908             :               // otherwise, center should be re-evaluated
     909             :               // using true trc and blc
     910           0 :               center = (blc + trc) / 2.0;
     911           0 :               declinationCorrection = cos(center[1]);
     912             :           }
     913             : 
     914           0 :           assert(declinationCorrection != 0.0);
     915             :           //cout << "declinationCorrection = " << declinationCorrection << endl;
     916             : 
     917             :           // apply declinationCorrection to extent[0]
     918           0 :           extent[0] *= declinationCorrection;
     919             :       }
     920           0 :       catch (...) {
     921           0 :           LogIO os(LogOrigin("ImagerMultiMS", "mapExtent", WHERE));
     922           0 :           os << LogIO::SEVERE << "Failed due to unknown error" << LogIO::POST;
     923           0 :           return false;
     924             :       }
     925           0 :       return true;
     926             :   }
     927             : } //# NAMESPACE CASA - END

Generated by: LCOV version 1.16