LCOV - code coverage report
Current view: top level - synthesis/ImagerObjects - CubeMajorCycleAlgorithm.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 0 392 0.0 %
Date: 2023-11-02 14:27:30 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             :         }
     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             :             }
     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             :                   }
     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             :                   }
     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             :           }
     274             :           else{
     275           0 :             Record&& outrec=subImgr.makePSF();
     276           0 :             if(outrec.isDefined("tempfilenames")){
     277           0 :               returnRec_p.define("tempfilenames", outrec.asArrayString("tempfilenames"));
     278             :             }
     279             :             ////tclean expects a PB to be always there...
     280             :             //so for standard make it
     281           0 :             subImgr.makePB();
     282           0 :             for(uInt k=0; k < subImStor.nelements(); ++k){
     283           0 :               if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight"))
     284             :                 {
     285           0 :                   if(controlRecord_p.isDefined("normpars")){
     286           0 :                     Record normpars=controlRecord_p.asRecord("normpars");
     287           0 :                     if(nterms_p[k] > 0){
     288           0 :                       if(!normpars.isDefined("nterms"))
     289           0 :                         normpars.define("nterms", uInt(nterms_p[k]));
     290           0 :                       normpars.define("deconvolver", "mtmfs");
     291             :                     }
     292             :                     //                        cerr  << k << " " << nterms_p[k] <<" NORMPARS " << normpars << endl;
     293           0 :                     SynthesisNormalizer norm;
     294           0 :                     norm.setupNormalizer(normpars);
     295           0 :                     norm.setImageStore(subImStorShared[k]);
     296           0 :                     norm.dividePSFByWeight();
     297           0 :                     copyBeamSet(*(subImStorShared[k]->psf()), k);
     298             :                   }
     299             :                   else{
     300           0 :                     LatticeLocker lock1 (*(subImStor[k]->psf()), FileLocker::Write);
     301           0 :                     LatticeLocker lock2 (*(subImStor[k]->sumwt()), FileLocker::Read);
     302           0 :                     subImStor[k]->dividePSFByWeight();
     303           0 :                     copyBeamSet(*(subImStor[k]->psf()), k);
     304             :                     //subImStor[k]->psf()->flush();
     305             :                   }
     306             :                 }
     307           0 :               Int chanBeg=0; Int chanEnd=0;
     308           0 :               if(k==0){
     309           0 :                 chanBeg=chanRange_p[0];
     310           0 :                 chanEnd=chanRange_p[1];
     311             :               }
     312             :               else{
     313           0 :                 chanBeg=0;
     314           0 :                 chanEnd=subImStor[k]->sumwt()->shape()[3]-1;
     315             :               }
     316           0 :               if(subImStor[k]->getType() != "multiterm"){
     317           0 :                 writeBackToFullImage(psfNames_p[k], chanBeg, chanEnd, (subImStor[k]->psf()));
     318           0 :                 writeBackToFullImage(sumwtNames_p[k], chanBeg, chanEnd, (subImStor[k]->sumwt()));
     319           0 :                 if((subImStor[k]->hasSensitivity()) && Table::isWritable(weightNames_p[k])){
     320           0 :                   writeBackToFullImage(weightNames_p[k], chanBeg, chanEnd, (subImStor[k]->weight()));
     321             :                   
     322             :                 }
     323           0 :                 if( doPB_p && Table::isWritable(pbNames_p[k])){
     324           0 :                   writeBackToFullImage(pbNames_p[k], chanBeg, chanEnd, (subImStor[k]->pb()));
     325             :                   
     326             :                 }
     327             :                 
     328             :               }
     329           0 :               subImStor[k]->psf()->unlock();
     330             :               
     331             :             }
     332             :           }
     333             :         //cerr << "***Time gridding/ffting " << tim.real() << endl;
     334           0 :           status_p = True;
     335             :         }
     336           0 :         catch (AipsError x) {
     337             : 
     338           0 :            LogIO os( LogOrigin("SynthesisImagerVi2","CubeMajorCycle",WHERE) );
     339           0 :            os << LogIO::WARN << "Exception for chan range "  << chanRange_p  << " ---   "<< x.getMesg()   << LogIO::POST;
     340           0 :           cerr << "##################################\n#############################\nException: " << x.getMesg() << endl;
     341             : 
     342           0 :           status_p=false;
     343             :         }
     344           0 :         catch(std::exception& exc) {
     345           0 :           logger << LogIO::SEVERE << "Exception (std): " << exc.what() << LogIO::POST;
     346           0 :           returnRec_p=Record();
     347             :         }
     348           0 :         catch(...){
     349           0 :           cerr << "###################################\n#######################3##\nUnknown exception "  << endl;
     350           0 :           std::exception_ptr eptr=std::current_exception();
     351             :           try{
     352           0 :             if(eptr)
     353           0 :               std::rethrow_exception(eptr);
     354             :           }
     355           0 :           catch(const std::exception& a){
     356           0 :             LogIO os( LogOrigin("SynthesisImagerVi2","CubeMajorCycle",WHERE) );
     357           0 :             os  << LogIO::WARN << "Unknown Exception for chan range "  << chanRange_p  << " ---   "<<  a.what()   << LogIO::POST;
     358             :           }
     359             : 
     360           0 :           logger << LogIO::SEVERE << "Unknown exception "  << LogIO::POST;
     361           0 :           status_p=False;
     362             :         }
     363           0 : }
     364           0 : String&     CubeMajorCycleAlgorithm::name(){
     365           0 :         return myName_p;
     366             : }
     367             : 
     368           0 :   shared_ptr<SIImageStore> CubeMajorCycleAlgorithm::subImageStore(const int imId){
     369             :         //For some reason multiterm deconvolver is allowed with cubes !
     370           0 :         String isMTdeconv="";
     371           0 :         nterms_p.resize(imId+1, True);
     372           0 :         nterms_p[imId]=-1;
     373           0 :         if(imId==0 && imSel_p[imId].deconvolver=="mtmfs"){
     374           0 :           isMTdeconv=".tt0";
     375           0 :           nterms_p[0]=1;
     376             :         }
     377             :         
     378           0 :         String residname=imSel_p[imId].imageName+".residual"+isMTdeconv;
     379           0 :         String psfname=imSel_p[imId].imageName+".psf"+isMTdeconv;
     380           0 :         String sumwgtname=imSel_p[imId].imageName+".sumwt"+isMTdeconv;
     381           0 :         if(imId > 0 && !Table::isReadable(sumwgtname)){
     382           0 :                 return multiTermImageStore(imId);
     383             :         }
     384           0 :         shared_ptr<ImageInterface<Float> >subpsf=nullptr;
     385           0 :         shared_ptr<ImageInterface<Float> >subresid=nullptr;
     386           0 :         shared_ptr<ImageInterface<Float> >submodel=nullptr;
     387           0 :         shared_ptr<ImageInterface<Float> > subweight=nullptr;
     388           0 :         shared_ptr<ImageInterface<Float> > subpb=nullptr;
     389             :         //cerr << imId << " sumwt name " << sumwgtname << endl;
     390           0 :         String workingdir="";
     391           0 :         if(controlRecord_p.isDefined("workingdirectory"))
     392           0 :                 controlRecord_p.get("workingdirectory", workingdir);
     393             :         //cerr <<"WORKINGDIR " << workingdir << endl;
     394           0 :         if(Table::isReadable(workingdir+"/"+sumwgtname)){
     395           0 :                 workingdir=workingdir+"/";
     396           0 :                 residname=workingdir+residname;
     397           0 :                 psfname=workingdir+psfname;
     398           0 :                 sumwgtname=workingdir+sumwgtname;
     399             :                 
     400             :         }
     401           0 :         else if(!Table::isReadable(sumwgtname) )
     402           0 :                 throw(AipsError("Programmer error: sumwt disk image is non existant")); 
     403             :         else
     404           0 :                 workingdir="";
     405             :         ///Use user locking to make sure locks are compliant
     406           0 :         PagedImage<Float> sumwt(sumwgtname, TableLock::UserLocking);
     407           0 :         sumwt.lock(FileLocker::Write, 200);
     408             :         //PagedImage<Float> sumwt(sumwgtname, TableLock::AutoNoReadLocking);
     409           0 :         if(sumwtNames_p.nelements() <= uInt(imId)){
     410           0 :           sumwtNames_p.resize(imId+1, True);
     411           0 :           psfNames_p.resize(imId+1, True);
     412           0 :           residualNames_p.resize(imId+1, True);
     413           0 :           sumwtNames_p[imId]=sumwgtname;
     414           0 :           residualNames_p[imId]=residname;
     415           0 :           psfNames_p[imId]=psfname;
     416             :         }
     417           0 :         Int nchannels=sumwt.shape()[3];
     418             : 
     419             :        
     420             :        
     421             :         //Should be partitioning for main image only
     422             :         //chanRange
     423           0 :         Int chanBeg=0;
     424           0 :         Int chanEnd=0;
     425           0 :         if(imId==0){
     426           0 :                 chanBeg=chanRange_p[0];
     427           0 :                 chanEnd=chanRange_p[1];
     428             :         }
     429             :         else{
     430           0 :                 chanBeg=0;
     431           0 :                 chanEnd=sumwt.shape()[3]-1;
     432             :         }
     433           0 :         sumwt.tempClose();
     434             :         ////For some small channel ms's retuning trigger a vi2/vb2 bug in nChannels
     435             :         ///avoid retuning for small images
     436             :         ////Skipping this here..
     437             :         //overloaded SynthesisImagerVi2::retune to do this check
     438             :         //if(nchannels < 30 && imId==0 && ((chanEnd-chanBeg) < 10)){
     439             :         //  retuning_p=False;
     440             :         //}
     441             :         //cerr << "chanBeg " << chanBeg << " chanEnd " << chanEnd << " imId " << imId << endl;
     442           0 :         Vector<String> weightnams(controlRecord_p.asArrayString("weightnames"));
     443           0 :         Vector<String> pbnams(controlRecord_p.asArrayString("pbnames"));
     444           0 :         pbNames_p.resize();
     445           0 :         pbNames_p=pbnams;
     446           0 :         weightNames_p.resize();
     447           0 :         weightNames_p=weightnams;
     448             :         
     449           0 :         if(imId >= int(weightNames_p.nelements()))
     450           0 :           throw(AipsError("Number of weight images does not match number of image fields defined"));
     451           0 :         if(Table::isReadable(workingdir+weightNames_p[imId])){
     452           0 :                 weightNames_p[imId]=workingdir+weightNames_p[imId];
     453             :         }
     454           0 :          if(Table::isReadable(workingdir+pbNames_p[imId])){
     455           0 :                 pbNames_p[imId]=workingdir+pbNames_p[imId];
     456             :         }
     457             :        
     458           0 :         if(dopsf_p){
     459             :           //PagedImage<Float> psf(psfname, TableLock::UserNoReadLocking);
     460             :           //subpsf.reset(SpectralImageUtil::getChannel(psf, chanBeg, chanEnd, true));
     461           0 :           getSubImage(subpsf, chanBeg, chanEnd, psfname, False);
     462             :           //cerr << "PBNAMES " << pbNames_p << endl;
     463           0 :           if(Table::isReadable(pbNames_p[imId])){
     464             : 
     465           0 :             doPB_p=True;
     466           0 :             getSubImage(subpb, chanBeg, chanEnd, pbNames_p[imId], False);
     467             :           }
     468             :         }
     469             :         else{
     470             :           //need to loop over all fields somewhere
     471             :           //PagedImage<Float> resid(residname, TableLock::UserNoReadLocking);
     472             :           //subresid.reset(SpectralImageUtil::getChannel(resid, chanBeg, chanEnd, true));
     473           0 :           getSubImage(subresid, chanBeg, chanEnd, residname, False);
     474             :  
     475           0 :           if(controlRecord_p.isDefined("modelnames")){
     476           0 :                         Vector<String> modelnames(controlRecord_p.asArrayString("modelnames"));
     477           0 :                         if(imId >= int(modelnames.nelements()))
     478           0 :                                 throw(AipsError("Number of model images does not match number of image fields defined"));
     479           0 :                         if(Table::isReadable(workingdir+modelnames[imId])){
     480           0 :                                 modelnames[imId]=workingdir+modelnames[imId];
     481             :                         }
     482           0 :                         if(Table::isReadable(modelnames[imId])){
     483             :                                 
     484             :                                 
     485             :                                 ///Pass some extra channels for interpolation while degridding..should match or be less than in SynthesisImager::tuneSelect
     486           0 :                                 Int startmodchan=(chanBeg-2) >0 ? chanBeg-2 : 0;
     487           0 :                                 Int endmodchan=(chanEnd+2) < nchannels ? chanEnd+2 : nchannels-1 ;
     488             :                                 //cerr << "START END mod " << startmodchan << "  " << endmodchan << endl;
     489             :                                 //Darn has to lock it as writable because overlap in SIMapperCollection code 
     490             :                                 //wants that...though we are not really modifying it here
     491             :                                 //Bool writeisneeded=(imSel_p.nelements()!=1 || startmodel_p[imId].nelements() >0);
     492             :                                 //PagedImage<Float> model(modelnames[imId], TableLock::UserNoReadLocking);
     493             :                                 //submodel.reset(SpectralImageUtil::getChannel(model, startmodchan, endmodchan, writeisneeded));
     494           0 :                                 getSubImage(submodel, startmodchan, endmodchan, modelnames[imId], True);
     495             :                                 //
     496           0 :                                 if(Table::isReadable(weightNames_p[imId])){
     497           0 :                                   divideModelByWeight(imSel_p[imId].imageName, submodel, startmodchan, endmodchan, weightNames_p[imId]);
     498             :                                 }
     499             :                                 //ImageInterface<Float>* modim=new PagedImage<Float>(modelnames[imId], TableLock::UserNoReadLocking);
     500             :                                 //submodel.reset(modim);
     501             :                                 
     502             :                         }
     503             :                         
     504             :                 }
     505             :                 
     506             :         }
     507             :         
     508           0 :         if(Table::isReadable(weightNames_p[imId])){
     509             :           //PagedImage<Float> weight(weightnames[imId], TableLock::UserNoReadLocking);
     510             :           //subweight.reset(SpectralImageUtil::getChannel(weight, chanBeg, chanEnd, true));
     511           0 :           getSubImage(subweight, chanBeg, chanEnd, weightNames_p[imId], True); 
     512             :         }
     513           0 :         shared_ptr<ImageInterface<Float> >subsumwt=nullptr;
     514             :         //      subsumwt.reset(SpectralImageUtil::getChannel(sumwt, chanBeg, chanEnd, true));
     515           0 :         getSubImage(subsumwt, chanBeg, chanEnd, sumwgtname, True);
     516           0 :         bool useweightimage=(subweight) ? true : false;
     517           0 :         shared_ptr<SIImageStore> subimstor(new SimpleSIImageStore(imSel_p[imId].imageName, submodel, subresid, subpsf, subweight, nullptr, nullptr, subsumwt, nullptr, subpb, nullptr, nullptr, useweightimage));
     518           0 :         if(polRep_p[imId]< 0)
     519           0 :                 throw(AipsError("data polarization type is not defined"));
     520           0 :         StokesImageUtil::PolRep polrep=(StokesImageUtil::PolRep)polRep_p[imId];
     521           0 :         subimstor->setDataPolFrame(polrep);
     522           0 :         if(startmodel_p[imId].nelements() >0){
     523           0 :           LatticeLocker lock1 (*(subimstor->model()), FileLocker::Write);
     524           0 :                 subimstor->setModelImage(startmodel_p[imId]);        
     525             :         }
     526             :         //cerr << "subimagestor TYPE" << subimstor->getType() << endl;
     527           0 :         return subimstor;
     528             : }
     529             : 
     530             :   
     531           0 :   std::shared_ptr<SIImageStore> CubeMajorCycleAlgorithm::multiTermImageStore(const Int imId){
     532           0 :         uInt nterms=0;
     533           0 :         String sumwgtname=imSel_p[imId].imageName+".sumwt.tt"+String::toString(nterms);
     534           0 :         while (Table::isReadable(sumwgtname)){
     535           0 :                 ++nterms;
     536           0 :                 sumwgtname=imSel_p[imId].imageName+".sumwt.tt"+String::toString(nterms);
     537             :         }
     538           0 :         if(nterms==0){
     539           0 :                 throw(AipsError("outlier "+String::toString(imId)+" field weight image is not defined"));
     540             :         }
     541           0 :         nterms=(nterms+1)/2;
     542           0 :         nterms_p[imId]=nterms;
     543           0 :         shared_ptr<SIImageStore> subimstor(new SIImageStoreMultiTerm(imSel_p[imId].imageName, nterms, True));
     544           0 :         if(polRep_p[imId]< 0)
     545           0 :                 throw(AipsError("data polarization type is not defined"));
     546           0 :         StokesImageUtil::PolRep polrep=(StokesImageUtil::PolRep)polRep_p[imId];
     547           0 :         subimstor->setDataPolFrame(polrep);
     548           0 :         return subimstor;
     549             : }
     550           0 :   void CubeMajorCycleAlgorithm::divideModelByWeight(casacore::String imageName, shared_ptr<ImageInterface<Float> >&submodel, const Int startchan, const Int endchan, const String weightname){
     551           0 :     if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight")){
     552           0 :       if(controlRecord_p.isDefined("normpars")){
     553           0 :                         Record normpars=controlRecord_p.asRecord("normpars");
     554           0 :                         SynthesisNormalizer norm;
     555           0 :                         norm.setupNormalizer(normpars);
     556           0 :                         shared_ptr<ImageInterface<Float> > subweight=nullptr;
     557           0 :                         getSubImage(subweight, startchan, endchan, weightname, True);
     558           0 :                         LatticeLocker lock1(*(subweight), FileLocker::Read);
     559           0 :                         LatticeLocker lock2(*(submodel), FileLocker::Read);
     560           0 :                         std::shared_ptr<SIImageStore> subimstor(new SimpleSIImageStore(imageName, submodel, nullptr, nullptr, subweight, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, True));
     561           0 :                         norm.setImageStore(subimstor);
     562           0 :                         norm.divideModelByWeight();
     563             :                         
     564             :       }
     565             :     }
     566           0 :   }
     567             : 
     568             : 
     569             : 
     570             :                                                                                                                                                      
     571           0 : void CubeMajorCycleAlgorithm::reset(){
     572             :                 
     573           0 :                 dataSel_p.resize();
     574           0 :                 imSel_p.resize();
     575           0 :                 gridSel_p.resize();
     576           0 :                 ftmRec_p.resize();
     577           0 :                 iftmRec_p.resize();
     578           0 :                 polRep_p.resize();
     579           0 :                 chanRange_p.resize();
     580           0 :                 dopsf_p=False;
     581           0 :                 controlRecord_p=Record();
     582           0 :                 weightParams_p=Record();
     583           0 :                 returnRec_p=Record();
     584           0 :                 startmodel_p.resize();
     585           0 :                 status_p=False;
     586           0 :                 residualNames_p.resize();
     587           0 :                 psfNames_p.resize();
     588           0 :                 sumwtNames_p.resize();
     589           0 :                 weightNames_p.resize();
     590           0 :                 pbNames_p.resize();
     591           0 :                 movingSource_p="";
     592           0 :                 retuning_p=True;
     593           0 :                 doPB_p=False;
     594           0 :                 nterms_p.resize();
     595             :                 
     596             :         
     597             :         
     598           0 : }
     599             :         
     600           0 :   void CubeMajorCycleAlgorithm::getSubImage(std::shared_ptr<ImageInterface<Float> >& subimptr, const Int chanBeg, const Int chanEnd, const String imagename, const Bool copy){
     601           0 :     LogIO os( LogOrigin("CubeMajorCycle","getSubImage",WHERE) );
     602           0 :     CountedPtr<PagedImage<Float> > im=nullptr;
     603             :     {///work around
     604           0 :       uInt exceptCounter=0;
     605             :       while(true){
     606             :         try{
     607           0 :           im = new PagedImage<Float> (imagename, TableLock::UserLocking);
     608             :           //PagedImage<Float> im(imagename, TableLock::AutoNoReadLocking);
     609           0 :           im->lock(FileLocker::Read, 1000);
     610           0 :           SubImage<Float> *tmpptr=nullptr;
     611           0 :           tmpptr=SpectralImageUtil::getChannel(*im, chanBeg, chanEnd, false);
     612           0 :           subimptr.reset(new TempImage<Float>(TiledShape(tmpptr->shape(), tmpptr->niceCursorShape()), tmpptr->coordinates()));
     613             :           
     614           0 :           if(copy)
     615           0 :             subimptr->copyData(*tmpptr);
     616             :           //subimptr->flush();
     617           0 :           im->unlock();
     618           0 :           delete tmpptr;
     619           0 :           break; ///get out of while loop
     620             :         }
     621           0 :         catch(AipsError &x){
     622           0 :           im=nullptr;
     623           0 :           String mes=x.getMesg();
     624           0 :           if(mes.contains("FilebufIO::readBlock") ){
     625           0 :             std::this_thread::sleep_for(std::chrono::milliseconds(50));
     626           0 :             os << LogIO::WARN << "#####CATCHING a sleep because "<< mes<< LogIO::POST;
     627             :           }
     628             :           else
     629           0 :             throw(AipsError("Error in readimage "+imagename+" : "+mes));
     630             :           
     631           0 :           if(exceptCounter > 100){
     632           0 :             throw(AipsError("Error in readimage got 100 of this exeception: "+mes));
     633             :             
     634             :           }
     635             :           
     636             :         }
     637           0 :         ++exceptCounter;
     638           0 :       }
     639             :     }     
     640             : 
     641           0 :   }
     642             : 
     643           0 :   void CubeMajorCycleAlgorithm::writeBackToFullImage(const String imagename, const Int chanBeg, const Int chanEnd, std::shared_ptr<ImageInterface<Float> > subimptr){
     644           0 :     LogIO os( LogOrigin("CubeMajorCycle","writebacktofullimage",WHERE) );
     645           0 :     CountedPtr<PagedImage<Float> > im=nullptr;
     646             :     {///work around
     647           0 :       uInt exceptCounter=0;
     648             :       while(true){
     649             :         try{
     650           0 :           im=new PagedImage<Float> (imagename, TableLock::UserLocking);
     651             :           
     652             :           
     653             :           //PagedImage<Float> im(imagename, TableLock::AutoLocking);
     654           0 :           SubImage<Float> *tmpptr=nullptr;
     655             :           {
     656           0 :             tmpptr=SpectralImageUtil::getChannel(*im, chanBeg, chanEnd, true);
     657           0 :             LatticeLocker lock1 (*(tmpptr), FileLocker::Write);
     658           0 :             tmpptr->set(0.0);
     659           0 :             tmpptr->copyData(*(subimptr));
     660             :           }
     661           0 :           im->flush();
     662           0 :           im->unlock();
     663           0 :           delete tmpptr;
     664           0 :           break; //get out of while loop
     665             :         }
     666           0 :         catch(AipsError &x){
     667             :           
     668           0 :           String mes=x.getMesg();
     669           0 :           if(mes.contains("FilebufIO::readBlock") ){
     670           0 :             std::this_thread::sleep_for(std::chrono::milliseconds(50));
     671           0 :             os << LogIO::WARN << "#####CATCHING a sleep because "<< mes<< LogIO::POST;
     672             :           }
     673             :           else
     674           0 :             throw(AipsError("Error in writing back image "+imagename+" : "+mes));
     675             :           
     676           0 :           if(exceptCounter > 100){
     677           0 :             throw(AipsError("Error in writeimage got 100 of this exeception: "+mes));
     678             :             
     679             :           }
     680             :           
     681             :         }
     682           0 :         ++exceptCounter;
     683           0 :       }
     684             :     }//End of work around for table disappearing bug
     685             : 
     686             :     
     687           0 :   }
     688           0 :   void CubeMajorCycleAlgorithm::copyBeamSet(ImageInterface<Float>& subpsf, const Int imageid){
     689             :     //For now lets do for the main image only
     690           0 :     if(imageid != 0)
     691           0 :       return;
     692           0 :     ImageBeamSet iibeamset=subpsf.imageInfo().getBeamSet();
     693           0 :     uInt nchan=chanRange_p[1]-chanRange_p[0]+1;
     694           0 :     if(nchan ==iibeamset.nchan()){
     695           0 :       Matrix<GaussianBeam> gbs=iibeamset.getBeams();
     696           0 :       Cube<Float> beams(nchan, iibeamset.nstokes(),3);
     697             :       
     698           0 :       for (uInt k=0; k < nchan; ++k){
     699           0 :         for (uInt j=0; j < iibeamset.nstokes(); ++j){
     700           0 :           beams(k,j, 0)=gbs(k, 0).getMajor("arcsec");
     701           0 :           beams(k,j, 1)=gbs(k, 0).getMinor("arcsec");
     702           0 :           beams(k,j, 2)=gbs(k, 0).getPA("deg", True);
     703             :         }
     704             :       }
     705           0 :       returnRec_p.define("imageid", imageid);
     706           0 :       returnRec_p.define("chanrange", chanRange_p);
     707           0 :       returnRec_p.define("beams", beams);
     708             : 
     709             : 
     710             :     }
     711             : 
     712             : 
     713             : 
     714             :   }
     715             :         
     716             :         
     717             :         
     718             : } //# NAMESPACE CASA - END

Generated by: LCOV version 1.16