LCOV - code coverage report
Current view: top level - synthesis/ImagerObjects - CubeMajorCycleAlgorithm.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 426 0.0 %
Date: 2025-08-21 08:01:32 Functions: 0 14 0.0 %

          Line data    Source code
       1             : //# CubeMajorCycleAlgorithm.cc: implementation of class to grid and degrid (and write model vis when necessary) in parallel/serial 
       2             : //# Copyright (C) 2019
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU General Public License as published by
       7             : //# the Free Software Foundation; either version 3 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      13             : //# License for more details.
      14             : //#
      15             : //# https://www.gnu.org/licenses/
      16             : //#
      17             : //# Queries concerning CASA should be submitted at
      18             : //#        https://help.nrao.edu
      19             : //#
      20             : //#        Postal address: CASA Project Manager 
      21             : //#                        National Radio Astronomy Observatory
      22             : //#                        520 Edgemont Road
      23             : //#                        Charlottesville, VA 22903-2475 USA
      24             : //#
      25             : //#
      26             : //# $Id$
      27             : #include <casacore/lattices/Lattices/LatticeLocker.h>
      28             : #include <synthesis/ImagerObjects/CubeMajorCycleAlgorithm.h>
      29             : #include <synthesis/ImagerObjects/SynthesisImagerVi2.h>
      30             : #include <synthesis/ImagerObjects/SynthesisNormalizer.h>
      31             : #include <casacore/casa/Containers/Record.h>
      32             : #include <synthesis/ImagerObjects/SimpleSIImageStore.h>
      33             : #include <imageanalysis/Utilities/SpectralImageUtil.h>
      34             : #include <casacore/casa/OS/Timer.h>
      35             : #include <chrono>
      36             : #include <thread>
      37             : using namespace casacore;
      38             : namespace casa { //# NAMESPACE CASA - BEGIN
      39             : extern Applicator applicator;
      40             : 
      41           0 :   CubeMajorCycleAlgorithm::CubeMajorCycleAlgorithm() : myName_p("CubeMajorCycleAlgorithm"),  ftmRec_p(0), iftmRec_p(0), polRep_p(0),startmodel_p(0), residualNames_p(0), psfNames_p(0), sumwtNames_p(0), weightNames_p(0), pbNames_p(0), movingSource_p(""),status_p(False), retuning_p(True), doPB_p(False), nterms_p(0){
      42             :         
      43           0 : }
      44           0 : CubeMajorCycleAlgorithm::~CubeMajorCycleAlgorithm() {
      45             :         
      46           0 : }
      47             :         
      48           0 : void CubeMajorCycleAlgorithm::get() {
      49           0 :         reset();
      50             :         //cerr << "in get for child process " << applicator.isWorker() << endl;
      51           0 :         Record vecImParsRec;
      52           0 :         Record vecSelParsRec;
      53           0 :         Record vecGridParsRec;
      54             :         // get data sel params #1
      55           0 :         applicator.get(vecSelParsRec);
      56             :         // get image sel params #2
      57           0 :         applicator.get(vecImParsRec);
      58             :         // get gridders params #3
      59           0 :         applicator.get(vecGridParsRec);
      60             :         // get which channel to process #4
      61           0 :         applicator.get(chanRange_p);
      62             :         //cerr <<"GET chanRange " << chanRange_p << endl;
      63             :         // psf or residual CubeMajorCycleAlgorithm #5
      64           0 :         applicator.get(dopsf_p);
      65             :         // store modelvis and other controls #6
      66           0 :         applicator.get(controlRecord_p);
      67             :         // weight params
      68           0 :         applicator.get(weightParams_p);
      69             :         //Somewhere before this we have to make sure that vecSelPars has more than 0 fields)
      70           0 :         dataSel_p.resize(vecSelParsRec.nfields());
      71             :         /// Fill the private variables
      72           0 :         for (Int k=0; k < Int(dataSel_p.nelements()); ++k){
      73           0 :                 (dataSel_p[k]).fromRecord(vecSelParsRec.asRecord(String::toString(k)));
      74             :         //      cerr << k << "datasel " << vecSelParsRec.asRecord(String::toString(k)) << endl;
      75             :         }
      76             :         //imsel and gridsel should be the same numbers (number of image fields)
      77           0 :         Int nmajorcycles=0;
      78           0 :         if(controlRecord_p.isDefined("nmajorcycles"))
      79           0 :                 controlRecord_p.get("nmajorcycles",nmajorcycles);
      80           0 :         imSel_p.resize(vecImParsRec.nfields());
      81           0 :         gridSel_p.resize(vecImParsRec.nfields());
      82           0 :         ftmRec_p.resize(vecImParsRec.nfields());
      83           0 :         iftmRec_p.resize(vecImParsRec.nfields());
      84           0 :         polRep_p.resize(vecImParsRec.nfields());
      85           0 :         polRep_p.set(-1);
      86           0 :         startmodel_p.resize(vecImParsRec.nfields());
      87           0 :         startmodel_p.set(Vector<String>(0));
      88             :         //TESTOO 
      89             :         //Int CPUID;
      90             :         //MPI_Comm_rank(MPI_COMM_WORLD, &CPUID);
      91             :         //////////////////
      92           0 :         for (uInt k=0; k < imSel_p.nelements(); ++k){
      93           0 :                 Record imSelRec=vecImParsRec.asRecord(String::toString(k));
      94             :                 //cerr << k << " imsel " << imSelRec << endl;
      95           0 :                 if(imSelRec.isDefined("polrep"))
      96           0 :                         imSelRec.get("polrep", polRep_p[k]);
      97             :                 ///Get moving source name
      98           0 :                 if(imSelRec.isDefined("movingsource") && imSelRec.asString("movingsource") != ""){
      99           0 :                   imSelRec.get("movingsource", movingSource_p);
     100             :                 }
     101             :                 //cerr << CPUID << " POLREP " << polRep_p << endl;
     102             :                 //Only first major cycle we need to reset model
     103           0 :                 if(nmajorcycles==1)
     104           0 :                         imSelRec.get("startmodel", startmodel_p[k]);
     105             :                 //have to do that as fromRecord check does not like to have both model and startmodel on disk !
     106           0 :                 imSelRec.define("startmodel", Vector<String>(0));
     107           0 :                 (imSel_p[k]).fromRecord(imSelRec);
     108           0 :                 Record recGridSel=vecGridParsRec.asRecord(String::toString(k));
     109           0 :                 (gridSel_p[k]).fromRecord(recGridSel);
     110           0 :                 if(!recGridSel.isDefined("ftmachine")){
     111           0 :                         ftmRec_p.resize();
     112           0 :                         iftmRec_p.resize();
     113             :                 }
     114           0 :                 if(ftmRec_p.nelements() >0){
     115           0 :                         ftmRec_p[k]=recGridSel.asRecord("ftmachine");
     116           0 :                         iftmRec_p[k]=recGridSel.asRecord("iftmachine");
     117             :                 }
     118             :                         
     119           0 :         }
     120             :         
     121             :         
     122           0 : }
     123           0 : void CubeMajorCycleAlgorithm::put() {
     124             :         
     125             :   //if(applicator.isSerial()){
     126             :   //            serialBug_p=Applicator::DONE;
     127             :                 //applicator.put(serialBug_p);
     128             :                 
     129             :   //    }
     130             :         //cerr << "in put " << status_p << endl;
     131           0 :   applicator.put(returnRec_p);
     132           0 :   applicator.put(status_p);     
     133             :         
     134           0 : }
     135             :         
     136           0 : void CubeMajorCycleAlgorithm::task(){
     137           0 :         LogIO logger(LogOrigin("CubeMajorCycleAlgorithm", "task", WHERE));
     138           0 :         status_p = True;
     139             :         try{
     140             :           //Timer tim;
     141             :           //tim.mark();
     142             :           //SynthesisImagerVi2 imgr;
     143             :           //imgr.selectData(dataSel_p);
     144             :           // We do not use chanchunking in this model
     145           0 :           for (uInt k=0; k < gridSel_p.nelements(); ++k)
     146           0 :             gridSel_p[k].chanchunks = 1;
     147             :           
     148             :           //imgr.defineImage(imSel_p,gridSel_p);
     149             :           // need to find how many subfields/outliers have been set
     150             :           //CountedPtr<SIImageStore> imstor =imgr.imageStore(0);
     151             :           //CountedPtr<ImageInterface<Float> > resid=imstor->residual();
     152             :           //Int nchan = resid->shape()(3);
     153             :           //std::shared_ptr<SIImageStore> subImStor=imstor->getSubImageStore(0, 1, chanId_p, nchan, 0,1);
     154             :           
     155           0 :           SynthesisImagerVi2 subImgr;
     156           0 :           subImgr.setCubeGridding(False);
     157           0 :           for (Int k=0; k < Int(dataSel_p.nelements()); ++k){
     158             :             //The original SynthesisImager would have cleared the model if it was requested
     159           0 :             dataSel_p[k].incrmodel=True;
     160           0 :             dataSel_p[k].freqbeg="";
     161           0 :             subImgr.selectData(dataSel_p[k]);
     162             :           }
     163             :           //cerr <<"***Time for select data " << tim.real() << endl;
     164             :           //tim.mark();
     165           0 :           subImgr.setMovingSource(movingSource_p);
     166           0 :           Vector<CountedPtr<SIImageStore> > subImStor(imSel_p.nelements());
     167             :           //copy as shared_ptr as we mix the usage of countedptr and sharedptr
     168           0 :           Vector<std::shared_ptr<SIImageStore> > subImStorShared(imSel_p.nelements());
     169           0 :           Vector<SIImageStore *> p(imSel_p.nelements());
     170             :           //Do multifield in one process only for now 
     171             :           //TODO if all fields have same nchan then partition all on all subcalls
     172           0 :           if(chanRange_p[0]==0){
     173           0 :             for (uInt k=0; k < imSel_p.nelements(); ++k){
     174           0 :               subImStorShared[k]=subImageStore(k);
     175           0 :               subImStor[k]=CountedPtr<SIImageStore>(subImStorShared[k]);
     176             :              
     177           0 :               if(ftmRec_p.nelements()>0){
     178           0 :                 subImgr.defineImage(subImStor[k], ftmRec_p[k], iftmRec_p[k]);   
     179             :               }else{
     180           0 :                 subImgr.defineImage(subImStor[k],  imSel_p[k], gridSel_p[k]);
     181             :               }
     182             :             }
     183             :           }else{
     184           0 :             subImStor.resize(1);
     185           0 :             subImStorShared[0]=subImageStore(0);
     186           0 :             subImStor[0]=CountedPtr<SIImageStore>(subImStorShared[0]);
     187             : 
     188           0 :             if(ftmRec_p.nelements()>0){
     189           0 :               subImgr.defineImage(subImStor[0], ftmRec_p[0], iftmRec_p[0]);
     190             :             }else{
     191           0 :               subImgr.defineImage(subImStor[0],  imSel_p[0], gridSel_p[0]);
     192             :             }
     193             :           }
     194           0 :           subImgr.setCubeGridding(False);
     195             :           // TO DO get weight param and set weight
     196             :           // Modified to fix CAS-13660 bug for natural weight setting with uvtaper
     197           0 :           if(!weightParams_p.isDefined("type") ){
     198           0 :             subImgr.weight("natural");
     199             :           }
     200             :           else{
     201           0 :             if(controlRecord_p.isDefined("weightdensity")){
     202           0 :               String densName=controlRecord_p.asString("weightdensity");
     203             :               //cerr << "Loading weightdensity " << densName << endl;
     204           0 :               if(Table::isReadable(densName))
     205           0 :                 subImgr.setWeightDensity(densName);
     206           0 :             }
     207             :             else{
     208           0 :               subImgr.weight(weightParams_p);
     209             :             }
     210             :           }
     211             :           ///Now do the selection tuning if needed
     212           0 :           if(imSel_p[0].mode !="cubedata"){
     213             :             //cerr << "IN RETUNING " << endl;
     214           0 :             if(retuning_p)
     215           0 :               subImgr.tuneSelectData();
     216             :           }
     217             :           
     218             :           //cerr << "***Time for all other setting " << tim.real() << endl;
     219             :           //tim.mark();
     220           0 :           if (!dopsf_p){
     221             :             ///In case weightimages for mosaicft is done load it...we can get rid of this if we are using fromrecord ftm
     222             :             ///doing it for non-psf only ...psf divides it by sumwt for some reason in
     223             :             ///SIImageStore ..so restart with psf creates havoc
     224           0 :           subImgr.loadMosaicSensitivity();
     225           0 :             Record outrec=subImgr.executeMajorCycle(controlRecord_p);
     226           0 :             if(outrec.isDefined("tempfilenames")){
     227           0 :               returnRec_p.define("tempfilenames", outrec.asArrayString("tempfilenames"));
     228             :             }
     229           0 :             for(uInt k=0; k < subImStor.nelements(); ++k){
     230           0 :               if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight")){
     231             :                 {
     232           0 :                   if(controlRecord_p.isDefined("normpars")){
     233           0 :                     Record normpars=controlRecord_p.asRecord("normpars");
     234           0 :                     SynthesisNormalizer norm;
     235           0 :                     if(nterms_p[k] > 0){
     236           0 :                       if(!normpars.isDefined("nterms"))
     237           0 :                         normpars.define("nterms", uInt(nterms_p[k]));
     238           0 :                       normpars.define("deconvolver", "mtmfs");
     239             :                     }
     240             :                     
     241           0 :                     norm.setupNormalizer(normpars);
     242           0 :                     norm.setImageStore(subImStorShared[k]);
     243           0 :                     norm.divideResidualByWeight();
     244           0 :                   }
     245             :                   else{
     246           0 :                     LatticeLocker lock1 (*(subImStor[k]->residual()), FileLocker::Write);
     247           0 :                     LatticeLocker lock2 (*(subImStor[k]->sumwt()), FileLocker::Read);
     248           0 :                     subImStor[k]->divideResidualByWeight();
     249             :                     //subImStor[k]->residual()->flush();
     250           0 :                   }
     251             :                 }
     252           0 :                 subImStor[k]->residual()->unlock();
     253           0 :                 if(subImStor[k]->hasModel())
     254           0 :                   subImStor[k]->model()->unlock();
     255             :               }
     256           0 :               Int chanBeg=0; Int chanEnd=0;
     257           0 :               if(k==0){
     258           0 :                 chanBeg=chanRange_p[0];
     259           0 :                 chanEnd=chanRange_p[1];
     260             :               }
     261             :               else{
     262           0 :                 chanBeg=0;
     263           0 :                 chanEnd=subImStor[k]->sumwt()->shape()[3]-1;
     264             :               }
     265           0 :               if(subImStor[k]->getType() != "multiterm"){
     266           0 :                 writeBackToFullImage(residualNames_p[k], chanBeg, chanEnd, (subImStor[k]->residual()));
     267           0 :                 writeBackToFullImage(sumwtNames_p[k], chanBeg, chanEnd, (subImStor[k]->sumwt()));
     268             :               }
     269             :               
     270             :             }
     271             :             
     272             :             
     273           0 :           }
     274             :           else{
     275           0 :             if((gridSel_p[0]).ftmachine=="awphpg"){
     276           0 :               if(!subImgr.loadMosaicSensitivity()){
     277           0 :                 subImgr.makeMosaicSensitivity();
     278           0 :                 writeBackToFullImage(weightNames_p[0], chanRange_p[0],chanRange_p[1], (subImStor[0]->weight()));
     279           0 :                 writeBackToFullImage(sumwtNames_p[0], chanRange_p[0], chanRange_p[1], (subImStor[0]->sumwt()));
     280             :                                                                                                                    
     281             :                 
     282             :               }
     283           0 :               subImgr.loadMosaicSensitivity();
     284             :             }
     285           0 :             Record&& outrec=subImgr.makePSF();
     286           0 :             if(outrec.isDefined("tempfilenames")){
     287           0 :               returnRec_p.define("tempfilenames", outrec.asArrayString("tempfilenames"));
     288             :             }
     289             :             ////tclean expects a PB to be always there...
     290             :             //so for standard make it
     291             :             
     292           0 :       subImgr.makePB();
     293             :             
     294           0 :             for(uInt k=0; k < subImStor.nelements(); ++k){
     295           0 :               if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight"))
     296             :                 {
     297           0 :                   if(controlRecord_p.isDefined("normpars")){
     298           0 :                     Record normpars=controlRecord_p.asRecord("normpars");
     299           0 :                     if(nterms_p[k] > 0){
     300           0 :                       if(!normpars.isDefined("nterms"))
     301           0 :                         normpars.define("nterms", uInt(nterms_p[k]));
     302           0 :                       normpars.define("deconvolver", "mtmfs");
     303             :                     }
     304             :                     //                        cerr  << k << " " << nterms_p[k] <<" NORMPARS " << normpars << endl;
     305           0 :                     SynthesisNormalizer norm;
     306           0 :                     norm.setupNormalizer(normpars);
     307           0 :                     norm.setImageStore(subImStorShared[k]);
     308           0 :                     norm.dividePSFByWeight();
     309           0 :                     norm.divideWeightBySumWt();
     310           0 :                     copyBeamSet(*(subImStorShared[k]->psf()), k);
     311           0 :                   }
     312             :                   else{
     313           0 :                     LatticeLocker lock1 (*(subImStor[k]->psf()), FileLocker::Write);
     314           0 :                     LatticeLocker lock2 (*(subImStor[k]->sumwt()), FileLocker::Read);
     315           0 :                     subImStor[k]->dividePSFByWeight();
     316           0 :                     subImStor[k]->divideWeightBySumwt();
     317           0 :                     copyBeamSet(*(subImStor[k]->psf()), k);
     318             :                     //subImStor[k]->psf()->flush();
     319           0 :                   }
     320             :                 }
     321           0 :               Int chanBeg=0; Int chanEnd=0;
     322           0 :               if(k==0){
     323           0 :                 chanBeg=chanRange_p[0];
     324           0 :                 chanEnd=chanRange_p[1];
     325             :               }
     326             :               else{
     327           0 :                 chanBeg=0;
     328           0 :                 chanEnd=subImStor[k]->sumwt()->shape()[3]-1;
     329             :               }
     330           0 :               if(subImStor[k]->getType() != "multiterm"){
     331           0 :                 writeBackToFullImage(psfNames_p[k], chanBeg, chanEnd, (subImStor[k]->psf()));
     332           0 :                 writeBackToFullImage(sumwtNames_p[k], chanBeg, chanEnd, (subImStor[k]->sumwt()));
     333           0 :                 if((subImStor[k]->hasSensitivity()) && Table::isWritable(weightNames_p[k]) && (gridSel_p[0]).ftmachine != "awphpg"){
     334             :                   
     335           0 :                   writeBackToFullImage(weightNames_p[k], chanBeg, chanEnd, (subImStor[k]->weight()));
     336             :                   
     337             :                 }
     338           0 :                 if( doPB_p && Table::isWritable(pbNames_p[k])){
     339           0 :                   writeBackToFullImage(pbNames_p[k], chanBeg, chanEnd, (subImStor[k]->pb()));
     340             :                   
     341             :                 }
     342             :                 
     343             :               }
     344           0 :               subImStor[k]->psf()->unlock();
     345             :               
     346             :             }
     347           0 :           }
     348             :         //cerr << "***Time gridding/ffting " << tim.real() << endl;
     349           0 :           status_p = True;
     350           0 :         }
     351           0 :         catch (AipsError x) {
     352             : 
     353           0 :            LogIO os( LogOrigin("SynthesisImagerVi2","CubeMajorCycle",WHERE) );
     354           0 :            os << LogIO::WARN << "Exception for chan range "  << chanRange_p  << " ---   "<< x.getMesg()   << LogIO::POST;
     355           0 :           cerr << "##################################\n#############################\nException: " << x.getMesg() << endl;
     356             : 
     357           0 :           status_p=false;
     358           0 :         }
     359           0 :         catch(std::exception& exc) {
     360           0 :           logger << LogIO::SEVERE << "Exception (std): " << exc.what() << LogIO::POST;
     361           0 :           returnRec_p=Record();
     362           0 :         }
     363           0 :         catch(...){
     364           0 :           cerr << "###################################\n#######################3##\nUnknown exception "  << endl;
     365           0 :           std::exception_ptr eptr=std::current_exception();
     366             :           try{
     367           0 :             if(eptr)
     368           0 :               std::rethrow_exception(eptr);
     369             :           }
     370           0 :           catch(const std::exception& a){
     371           0 :             LogIO os( LogOrigin("SynthesisImagerVi2","CubeMajorCycle",WHERE) );
     372           0 :             os  << LogIO::WARN << "Unknown Exception for chan range "  << chanRange_p  << " ---   "<<  a.what()   << LogIO::POST;
     373           0 :           }
     374             : 
     375           0 :           logger << LogIO::SEVERE << "Unknown exception "  << LogIO::POST;
     376           0 :           status_p=False;
     377           0 :         }
     378           0 : }
     379           0 : String&     CubeMajorCycleAlgorithm::name(){
     380           0 :         return myName_p;
     381             : }
     382             : 
     383           0 :   shared_ptr<SIImageStore> CubeMajorCycleAlgorithm::subImageStore(const int imId){
     384             :         //For some reason multiterm deconvolver is allowed with cubes !
     385           0 :         String isMTdeconv="";
     386           0 :         nterms_p.resize(imId+1, True);
     387           0 :         nterms_p[imId]=-1;
     388           0 :         if(imId==0 && imSel_p[imId].deconvolver=="mtmfs"){
     389           0 :           isMTdeconv=".tt0";
     390           0 :           nterms_p[0]=1;
     391             :         }
     392             :         
     393           0 :         String residname=imSel_p[imId].imageName+".residual"+isMTdeconv;
     394           0 :         String psfname=imSel_p[imId].imageName+".psf"+isMTdeconv;
     395           0 :         String sumwgtname=imSel_p[imId].imageName+".sumwt"+isMTdeconv;
     396           0 :         if(imId > 0 && !Table::isReadable(sumwgtname)){
     397           0 :                 return multiTermImageStore(imId);
     398             :         }
     399           0 :         shared_ptr<ImageInterface<Float> >subpsf=nullptr;
     400           0 :         shared_ptr<ImageInterface<Float> >subresid=nullptr;
     401           0 :         shared_ptr<ImageInterface<Float> >submodel=nullptr;
     402           0 :         shared_ptr<ImageInterface<Float> > subweight=nullptr;
     403           0 :         shared_ptr<ImageInterface<Float> > subpb=nullptr;
     404             :         //cerr << imId << " sumwt name " << sumwgtname << endl;
     405           0 :         String workingdir="";
     406           0 :         if(controlRecord_p.isDefined("workingdirectory"))
     407           0 :                 controlRecord_p.get("workingdirectory", workingdir);
     408             :         //cerr <<"WORKINGDIR " << workingdir << endl;
     409           0 :         if(Table::isReadable(workingdir+"/"+sumwgtname)){
     410           0 :                 workingdir=workingdir+"/";
     411           0 :                 residname=workingdir+residname;
     412           0 :                 psfname=workingdir+psfname;
     413           0 :                 sumwgtname=workingdir+sumwgtname;
     414             :                 
     415             :         }
     416           0 :         else if(!Table::isReadable(sumwgtname) )
     417           0 :                 throw(AipsError("Programmer error: sumwt disk image is non existant")); 
     418             :         else
     419           0 :                 workingdir="";
     420             :         ///Use user locking to make sure locks are compliant
     421           0 :         PagedImage<Float> sumwt(sumwgtname, TableLock::UserLocking);
     422           0 :         sumwt.lock(FileLocker::Write, 200);
     423             :         //PagedImage<Float> sumwt(sumwgtname, TableLock::AutoNoReadLocking);
     424           0 :         if(sumwtNames_p.nelements() <= uInt(imId)){
     425           0 :           sumwtNames_p.resize(imId+1, True);
     426           0 :           psfNames_p.resize(imId+1, True);
     427           0 :           residualNames_p.resize(imId+1, True);
     428           0 :           sumwtNames_p[imId]=sumwgtname;
     429           0 :           residualNames_p[imId]=residname;
     430           0 :           psfNames_p[imId]=psfname;
     431             :         }
     432           0 :         Int nchannels=sumwt.shape()[3];
     433             : 
     434             :        
     435             :        
     436             :         //Should be partitioning for main image only
     437             :         //chanRange
     438           0 :         Int chanBeg=0;
     439           0 :         Int chanEnd=0;
     440           0 :         if(imId==0){
     441           0 :                 chanBeg=chanRange_p[0];
     442           0 :                 chanEnd=chanRange_p[1];
     443             :         }
     444             :         else{
     445           0 :                 chanBeg=0;
     446           0 :                 chanEnd=sumwt.shape()[3]-1;
     447             :         }
     448           0 :         sumwt.tempClose();
     449             :         ////For some small channel ms's retuning trigger a vi2/vb2 bug in nChannels
     450             :         ///avoid retuning for small images
     451             :         ////Skipping this here..
     452             :         //overloaded SynthesisImagerVi2::retune to do this check
     453             :         //if(nchannels < 30 && imId==0 && ((chanEnd-chanBeg) < 10)){
     454             :         //  retuning_p=False;
     455             :         //}
     456             :         //cerr << "chanBeg " << chanBeg << " chanEnd " << chanEnd << " imId " << imId << endl;
     457           0 :         Vector<String> weightnams(controlRecord_p.asArrayString("weightnames"));
     458           0 :         Vector<String> pbnams(controlRecord_p.asArrayString("pbnames"));
     459           0 :         pbNames_p.resize();
     460           0 :         pbNames_p=pbnams;
     461           0 :         weightNames_p.resize();
     462           0 :         weightNames_p=weightnams;
     463             :         
     464           0 :         if(imId >= int(weightNames_p.nelements()))
     465           0 :           throw(AipsError("Number of weight images does not match number of image fields defined"));
     466           0 :         if(Table::isReadable(workingdir+weightNames_p[imId])){
     467           0 :                 weightNames_p[imId]=workingdir+weightNames_p[imId];
     468             :         }
     469           0 :          if(Table::isReadable(workingdir+pbNames_p[imId])){
     470           0 :                 pbNames_p[imId]=workingdir+pbNames_p[imId];
     471             :         }
     472             :        
     473           0 :         if(dopsf_p){
     474             :           //PagedImage<Float> psf(psfname, TableLock::UserNoReadLocking);
     475             :           //subpsf.reset(SpectralImageUtil::getChannel(psf, chanBeg, chanEnd, true));
     476           0 :           getSubImage(subpsf, chanBeg, chanEnd, psfname, False);
     477             :           //cerr << "PBNAMES " << pbNames_p << endl;
     478           0 :           if(Table::isReadable(pbNames_p[imId])){
     479             : 
     480           0 :             doPB_p=True;
     481           0 :             getSubImage(subpb, chanBeg, chanEnd, pbNames_p[imId], False);
     482             :           }
     483             :         }
     484             :         else{
     485             :           //need to loop over all fields somewhere
     486             :           //PagedImage<Float> resid(residname, TableLock::UserNoReadLocking);
     487             :           //subresid.reset(SpectralImageUtil::getChannel(resid, chanBeg, chanEnd, true));
     488           0 :           getSubImage(subresid, chanBeg, chanEnd, residname, False);
     489             :  
     490           0 :           if(controlRecord_p.isDefined("modelnames")){
     491           0 :                         Vector<String> modelnames(controlRecord_p.asArrayString("modelnames"));
     492           0 :                         if(imId >= int(modelnames.nelements()))
     493           0 :                                 throw(AipsError("Number of model images does not match number of image fields defined"));
     494           0 :                         if(Table::isReadable(workingdir+modelnames[imId])){
     495           0 :                                 modelnames[imId]=workingdir+modelnames[imId];
     496             :                         }
     497           0 :                         if(Table::isReadable(modelnames[imId])){
     498             :                                 
     499             :                                 
     500             :                                 ///Pass some extra channels for interpolation while degridding..should match or be less than in SynthesisImager::tuneSelect
     501           0 :                                 Int startmodchan=(chanBeg-2) >0 ? chanBeg-2 : 0;
     502           0 :                                 Int endmodchan=(chanEnd+2) < nchannels ? chanEnd+2 : nchannels-1 ;
     503           0 :                                 if((gridSel_p[0]).ftmachine=="awphpg"){
     504             :                                   ////Only one channel is used
     505           0 :                                   startmodchan=chanBeg;
     506           0 :                                   endmodchan=chanEnd;
     507             :                                 }
     508             :                                 
     509             :                                 //cerr << "START END mod " << startmodchan << "  " << endmodchan << endl;
     510             :                                 //Darn has to lock it as writable because overlap in SIMapperCollection code 
     511             :                                 //wants that...though we are not really modifying it here
     512             :                                 //Bool writeisneeded=(imSel_p.nelements()!=1 || startmodel_p[imId].nelements() >0);
     513             :                                 //PagedImage<Float> model(modelnames[imId], TableLock::UserNoReadLocking);
     514             :                                 //submodel.reset(SpectralImageUtil::getChannel(model, startmodchan, endmodchan, writeisneeded));
     515           0 :                                 getSubImage(submodel, startmodchan, endmodchan, modelnames[imId], True);
     516             :                                 //
     517           0 :                                 if(Table::isReadable(weightNames_p[imId])){
     518           0 :                                   divideModelByWeight(imSel_p[imId].imageName, submodel, startmodchan, endmodchan, weightNames_p[imId]);
     519             :                                 }
     520             :                                 //ImageInterface<Float>* modim=new PagedImage<Float>(modelnames[imId], TableLock::UserNoReadLocking);
     521             :                                 //submodel.reset(modim);
     522             :                                 
     523             :                         }
     524             :                         
     525           0 :                 }
     526             :                 
     527             :         }
     528             :         
     529           0 :         if(Table::isReadable(weightNames_p[imId])){
     530             :           //PagedImage<Float> weight(weightnames[imId], TableLock::UserNoReadLocking);
     531             :           //subweight.reset(SpectralImageUtil::getChannel(weight, chanBeg, chanEnd, true));
     532           0 :           getSubImage(subweight, chanBeg, chanEnd, weightNames_p[imId], True); 
     533             :         }
     534           0 :         shared_ptr<ImageInterface<Float> >subsumwt=nullptr;
     535             :         //      subsumwt.reset(SpectralImageUtil::getChannel(sumwt, chanBeg, chanEnd, true));
     536           0 :         getSubImage(subsumwt, chanBeg, chanEnd, sumwgtname, True);
     537           0 :         bool useweightimage=(subweight) ? true : false;
     538           0 :         shared_ptr<SIImageStore> subimstor(new SimpleSIImageStore(imSel_p[imId].imageName, submodel, subresid, subpsf, subweight, nullptr, nullptr, subsumwt, nullptr, subpb, nullptr, nullptr, useweightimage));
     539           0 :         if(polRep_p[imId]< 0)
     540           0 :                 throw(AipsError("data polarization type is not defined"));
     541           0 :         StokesImageUtil::PolRep polrep=(StokesImageUtil::PolRep)polRep_p[imId];
     542           0 :         subimstor->setDataPolFrame(polrep);
     543           0 :         if(startmodel_p[imId].nelements() >0){
     544           0 :           LatticeLocker lock1 (*(subimstor->model()), FileLocker::Write);
     545           0 :                 subimstor->setModelImage(startmodel_p[imId]);        
     546           0 :         }
     547             :         //cerr << "subimagestor TYPE" << subimstor->getType() << endl;
     548           0 :         return subimstor;
     549           0 : }
     550             : 
     551             :   
     552           0 :   std::shared_ptr<SIImageStore> CubeMajorCycleAlgorithm::multiTermImageStore(const Int imId){
     553           0 :         uInt nterms=0;
     554           0 :         String sumwgtname=imSel_p[imId].imageName+".sumwt.tt"+String::toString(nterms);
     555           0 :         while (Table::isReadable(sumwgtname)){
     556           0 :                 ++nterms;
     557           0 :                 sumwgtname=imSel_p[imId].imageName+".sumwt.tt"+String::toString(nterms);
     558             :         }
     559           0 :         if(nterms==0){
     560           0 :                 throw(AipsError("outlier "+String::toString(imId)+" field weight image is not defined"));
     561             :         }
     562           0 :         nterms=(nterms+1)/2;
     563           0 :         nterms_p[imId]=nterms;
     564           0 :         shared_ptr<SIImageStore> subimstor(new SIImageStoreMultiTerm(imSel_p[imId].imageName, nterms, True));
     565           0 :         if(polRep_p[imId]< 0)
     566           0 :                 throw(AipsError("data polarization type is not defined"));
     567           0 :         StokesImageUtil::PolRep polrep=(StokesImageUtil::PolRep)polRep_p[imId];
     568           0 :         subimstor->setDataPolFrame(polrep);
     569           0 :         return subimstor;
     570           0 : }
     571           0 :   void CubeMajorCycleAlgorithm::divideModelByWeight(casacore::String imageName, shared_ptr<ImageInterface<Float> >&submodel, const Int startchan, const Int endchan, const String weightname){
     572           0 :     if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight")){
     573           0 :       if(controlRecord_p.isDefined("normpars")){
     574           0 :                         Record normpars=controlRecord_p.asRecord("normpars");
     575           0 :                         SynthesisNormalizer norm;
     576           0 :                         norm.setupNormalizer(normpars);
     577           0 :                         shared_ptr<ImageInterface<Float> > subweight=nullptr;
     578           0 :                         getSubImage(subweight, startchan, endchan, weightname, True);
     579           0 :                         LatticeLocker lock1(*(subweight), FileLocker::Read);
     580           0 :                         LatticeLocker lock2(*(submodel), FileLocker::Read);
     581           0 :                         std::shared_ptr<SIImageStore> subimstor(new SimpleSIImageStore(imageName, submodel, nullptr, nullptr, subweight, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, True));
     582           0 :                         norm.setImageStore(subimstor);
     583           0 :                         norm.divideModelByWeight();
     584             :                         
     585           0 :       }
     586             :     }
     587           0 :   }
     588             : 
     589             : 
     590             : 
     591             :                                                                                                                                                      
     592           0 : void CubeMajorCycleAlgorithm::reset(){
     593             :                 
     594           0 :                 dataSel_p.resize();
     595           0 :                 imSel_p.resize();
     596           0 :                 gridSel_p.resize();
     597           0 :                 ftmRec_p.resize();
     598           0 :                 iftmRec_p.resize();
     599           0 :                 polRep_p.resize();
     600           0 :                 chanRange_p.resize();
     601           0 :                 dopsf_p=False;
     602           0 :                 controlRecord_p=Record();
     603           0 :                 weightParams_p=Record();
     604           0 :                 returnRec_p=Record();
     605           0 :                 startmodel_p.resize();
     606           0 :                 status_p=False;
     607           0 :                 residualNames_p.resize();
     608           0 :                 psfNames_p.resize();
     609           0 :                 sumwtNames_p.resize();
     610           0 :                 weightNames_p.resize();
     611           0 :                 pbNames_p.resize();
     612           0 :                 movingSource_p="";
     613           0 :                 retuning_p=True;
     614           0 :                 doPB_p=False;
     615           0 :                 nterms_p.resize();
     616             :                 
     617             :         
     618             :         
     619           0 : }
     620             :         
     621           0 :   void CubeMajorCycleAlgorithm::getSubImage(std::shared_ptr<ImageInterface<Float> >& subimptr, const Int chanBeg, const Int chanEnd, const String imagename, const Bool copy){
     622           0 :     LogIO os( LogOrigin("CubeMajorCycle","getSubImage",WHERE) );
     623           0 :     CountedPtr<PagedImage<Float> > im=nullptr;
     624             :     {///work around
     625           0 :       uInt exceptCounter=0;
     626             :       while(true){
     627             :         try{
     628           0 :           im = new PagedImage<Float> (imagename, TableLock::UserLocking);
     629             :           //PagedImage<Float> im(imagename, TableLock::AutoNoReadLocking);
     630           0 :           im->lock(FileLocker::Read, 1000);
     631           0 :           SubImage<Float> *tmpptr=nullptr;
     632           0 :           tmpptr=SpectralImageUtil::getChannel(*im, chanBeg, chanEnd, false);
     633           0 :           subimptr.reset(new TempImage<Float>(TiledShape(tmpptr->shape(), tmpptr->niceCursorShape()), tmpptr->coordinates()));
     634             :           
     635           0 :           if(copy)
     636           0 :             subimptr->copyData(*tmpptr);
     637             :           //subimptr->flush();
     638           0 :           im->unlock();
     639           0 :           delete tmpptr;
     640           0 :           break; ///get out of while loop
     641             :         }
     642           0 :         catch(AipsError &x){
     643           0 :           im=nullptr;
     644           0 :           String mes=x.getMesg();
     645           0 :           if(mes.contains("FilebufIO::readBlock") ){
     646           0 :             std::this_thread::sleep_for(std::chrono::milliseconds(50));
     647           0 :             os << LogIO::WARN << "#####CATCHING a sleep because "<< mes<< LogIO::POST;
     648             :           }
     649             :           else
     650           0 :             throw(AipsError("Error in readimage "+imagename+" : "+mes));
     651             :           
     652           0 :           if(exceptCounter > 100){
     653           0 :             throw(AipsError("Error in readimage got 100 of this exeception: "+mes));
     654             :             
     655             :           }
     656             :           
     657           0 :         }
     658           0 :         ++exceptCounter;
     659           0 :       }
     660             :     }     
     661             : 
     662           0 :   }
     663             : 
     664           0 :   void CubeMajorCycleAlgorithm::writeBackToFullImage(const String imagename, const Int chanBeg, const Int chanEnd, std::shared_ptr<ImageInterface<Float> > subimptr){
     665           0 :     LogIO os( LogOrigin("CubeMajorCycle","writebacktofullimage",WHERE) );
     666           0 :     CountedPtr<PagedImage<Float> > im=nullptr;
     667             :     {///work around
     668           0 :       uInt exceptCounter=0;
     669             :       while(true){
     670             :         try{
     671           0 :           im=new PagedImage<Float> (imagename, TableLock::UserLocking);
     672             :           
     673             :           
     674             :           //PagedImage<Float> im(imagename, TableLock::AutoLocking);
     675           0 :           SubImage<Float> *tmpptr=nullptr;
     676             :           {
     677           0 :             tmpptr=SpectralImageUtil::getChannel(*im, chanBeg, chanEnd, true);
     678           0 :             LatticeLocker lock1 (*(tmpptr), FileLocker::Write);
     679           0 :             tmpptr->set(0.0);
     680           0 :             tmpptr->copyData(*(subimptr));
     681           0 :           }
     682           0 :           im->flush();
     683           0 :           im->unlock();
     684           0 :           delete tmpptr;
     685           0 :           break; //get out of while loop
     686             :         }
     687           0 :         catch(AipsError &x){
     688             :           
     689           0 :           String mes=x.getMesg();
     690           0 :           if(mes.contains("FilebufIO::readBlock") ){
     691           0 :             std::this_thread::sleep_for(std::chrono::milliseconds(50));
     692           0 :             os << LogIO::WARN << "#####CATCHING a sleep because "<< mes<< LogIO::POST;
     693             :           }
     694             :           else
     695           0 :             throw(AipsError("Error in writing back image "+imagename+" : "+mes));
     696             :           
     697           0 :           if(exceptCounter > 100){
     698           0 :             throw(AipsError("Error in writeimage got 100 of this exeception: "+mes));
     699             :             
     700             :           }
     701             :           
     702           0 :         }
     703           0 :         ++exceptCounter;
     704           0 :       }
     705             :     }//End of work around for table disappearing bug
     706             : 
     707             :     
     708           0 :   }
     709           0 :   void CubeMajorCycleAlgorithm::copyBeamSet(ImageInterface<Float>& subpsf, const Int imageid){
     710             :     //For now lets do for the main image only
     711           0 :     if(imageid != 0)
     712           0 :       return;
     713           0 :     ImageBeamSet iibeamset=subpsf.imageInfo().getBeamSet();
     714           0 :     uInt nchan=chanRange_p[1]-chanRange_p[0]+1;
     715           0 :     if(nchan ==iibeamset.nchan()){
     716           0 :       Matrix<GaussianBeam> gbs=iibeamset.getBeams();
     717           0 :       Cube<Float> beams(nchan, iibeamset.nstokes(),3);
     718             :       
     719           0 :       for (uInt k=0; k < nchan; ++k){
     720           0 :         for (uInt j=0; j < iibeamset.nstokes(); ++j){
     721           0 :           beams(k,j, 0)=gbs(k, 0).getMajor("arcsec");
     722           0 :           beams(k,j, 1)=gbs(k, 0).getMinor("arcsec");
     723           0 :           beams(k,j, 2)=gbs(k, 0).getPA("deg", True);
     724             :         }
     725             :       }
     726           0 :       returnRec_p.define("imageid", imageid);
     727           0 :       returnRec_p.define("chanrange", chanRange_p);
     728           0 :       returnRec_p.define("beams", beams);
     729             : 
     730             : 
     731           0 :     }
     732             : 
     733             : 
     734             : 
     735           0 :   }
     736             :         
     737             :         
     738             :         
     739             : } //# NAMESPACE CASA - END

Generated by: LCOV version 1.16