LCOV - code coverage report
Current view: top level - synthesis/ImagerObjects - CubeMajorCycleAlgorithm.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 343 415 82.7 %
Date: 2024-12-11 20:54:31 Functions: 14 14 100.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         828 :   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         828 : }
      44         829 : CubeMajorCycleAlgorithm::~CubeMajorCycleAlgorithm() {
      45             :         
      46         829 : }
      47             :         
      48         827 : void CubeMajorCycleAlgorithm::get() {
      49         827 :         reset();
      50             :         //cerr << "in get for child process " << applicator.isWorker() << endl;
      51         827 :         Record vecImParsRec;
      52         827 :         Record vecSelParsRec;
      53         827 :         Record vecGridParsRec;
      54             :         // get data sel params #1
      55         827 :         applicator.get(vecSelParsRec);
      56             :         // get image sel params #2
      57         827 :         applicator.get(vecImParsRec);
      58             :         // get gridders params #3
      59         827 :         applicator.get(vecGridParsRec);
      60             :         // get which channel to process #4
      61         827 :         applicator.get(chanRange_p);
      62             :         //cerr <<"GET chanRange " << chanRange_p << endl;
      63             :         // psf or residual CubeMajorCycleAlgorithm #5
      64         827 :         applicator.get(dopsf_p);
      65             :         // store modelvis and other controls #6
      66         827 :         applicator.get(controlRecord_p);
      67             :         // weight params
      68         827 :         applicator.get(weightParams_p);
      69             :         //Somewhere before this we have to make sure that vecSelPars has more than 0 fields)
      70         827 :         dataSel_p.resize(vecSelParsRec.nfields());
      71             :         /// Fill the private variables
      72        1683 :         for (Int k=0; k < Int(dataSel_p.nelements()); ++k){
      73         856 :                 (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         827 :         Int nmajorcycles=0;
      78         827 :         if(controlRecord_p.isDefined("nmajorcycles"))
      79         543 :                 controlRecord_p.get("nmajorcycles",nmajorcycles);
      80         827 :         imSel_p.resize(vecImParsRec.nfields());
      81         827 :         gridSel_p.resize(vecImParsRec.nfields());
      82         827 :         ftmRec_p.resize(vecImParsRec.nfields());
      83         827 :         iftmRec_p.resize(vecImParsRec.nfields());
      84         827 :         polRep_p.resize(vecImParsRec.nfields());
      85         827 :         polRep_p.set(-1);
      86         827 :         startmodel_p.resize(vecImParsRec.nfields());
      87         827 :         startmodel_p.set(Vector<String>(0));
      88             :         //TESTOO 
      89             :         //Int CPUID;
      90             :         //MPI_Comm_rank(MPI_COMM_WORLD, &CPUID);
      91             :         //////////////////
      92        1669 :         for (uInt k=0; k < imSel_p.nelements(); ++k){
      93        1684 :                 Record imSelRec=vecImParsRec.asRecord(String::toString(k));
      94             :                 //cerr << k << " imsel " << imSelRec << endl;
      95         842 :                 if(imSelRec.isDefined("polrep"))
      96         842 :                         imSelRec.get("polrep", polRep_p[k]);
      97             :                 ///Get moving source name
      98         842 :                 if(imSelRec.isDefined("movingsource") && imSelRec.asString("movingsource") != ""){
      99           8 :                   imSelRec.get("movingsource", movingSource_p);
     100             :                 }
     101             :                 //cerr << CPUID << " POLREP " << polRep_p << endl;
     102             :                 //Only first major cycle we need to reset model
     103         842 :                 if(nmajorcycles==1)
     104         292 :                         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         842 :                 imSelRec.define("startmodel", Vector<String>(0));
     107         842 :                 (imSel_p[k]).fromRecord(imSelRec);
     108        1684 :                 Record recGridSel=vecGridParsRec.asRecord(String::toString(k));
     109         842 :                 (gridSel_p[k]).fromRecord(recGridSel);
     110         842 :                 if(!recGridSel.isDefined("ftmachine")){
     111         842 :                         ftmRec_p.resize();
     112         842 :                         iftmRec_p.resize();
     113             :                 }
     114         842 :                 if(ftmRec_p.nelements() >0){
     115           0 :                         ftmRec_p[k]=recGridSel.asRecord("ftmachine");
     116           0 :                         iftmRec_p[k]=recGridSel.asRecord("iftmachine");
     117             :                 }
     118             :                         
     119         842 :         }
     120             :         
     121             :         
     122         827 : }
     123         827 : 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         827 :   applicator.put(returnRec_p);
     132         827 :   applicator.put(status_p);     
     133             :         
     134         827 : }
     135             :         
     136         827 : void CubeMajorCycleAlgorithm::task(){
     137        1654 :         LogIO logger(LogOrigin("CubeMajorCycleAlgorithm", "task", WHERE));
     138         827 :         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        1669 :           for (uInt k=0; k < gridSel_p.nelements(); ++k)
     146         842 :             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         827 :           SynthesisImagerVi2 subImgr;
     156         827 :           subImgr.setCubeGridding(False);
     157        1683 :           for (Int k=0; k < Int(dataSel_p.nelements()); ++k){
     158             :             //The original SynthesisImager would have cleared the model if it was requested
     159         856 :             dataSel_p[k].incrmodel=True;
     160         856 :             dataSel_p[k].freqbeg="";
     161         856 :             subImgr.selectData(dataSel_p[k]);
     162             :           }
     163             :           //cerr <<"***Time for select data " << tim.real() << endl;
     164             :           //tim.mark();
     165         827 :           subImgr.setMovingSource(movingSource_p);
     166         827 :           Vector<CountedPtr<SIImageStore> > subImStor(imSel_p.nelements());
     167             :           //copy as shared_ptr as we mix the usage of countedptr and sharedptr
     168         827 :           Vector<std::shared_ptr<SIImageStore> > subImStorShared(imSel_p.nelements());
     169         827 :           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         827 :           if(chanRange_p[0]==0){
     173        1669 :             for (uInt k=0; k < imSel_p.nelements(); ++k){
     174         842 :               subImStorShared[k]=subImageStore(k);
     175         842 :               subImStor[k]=CountedPtr<SIImageStore>(subImStorShared[k]);
     176             :              
     177         842 :               if(ftmRec_p.nelements()>0){
     178           0 :                 subImgr.defineImage(subImStor[k], ftmRec_p[k], iftmRec_p[k]);   
     179             :               }else{
     180         842 :                 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         827 :           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         827 :           if(!weightParams_p.isDefined("type") ){
     198           0 :             subImgr.weight("natural");
     199             :           }
     200             :           else{
     201         827 :             if(controlRecord_p.isDefined("weightdensity")){
     202           2 :               String densName=controlRecord_p.asString("weightdensity");
     203             :               //cerr << "Loading weightdensity " << densName << endl;
     204           2 :               if(Table::isReadable(densName))
     205           2 :                 subImgr.setWeightDensity(densName);
     206           2 :             }
     207             :             else{
     208         825 :               subImgr.weight(weightParams_p);
     209             :             }
     210             :           }
     211             :           ///Now do the selection tuning if needed
     212         827 :           if(imSel_p[0].mode !="cubedata"){
     213             :             //cerr << "IN RETUNING " << endl;
     214         821 :             if(retuning_p)
     215         821 :               subImgr.tuneSelectData();
     216             :           }
     217             :           
     218             :           //cerr << "***Time for all other setting " << tim.real() << endl;
     219             :           //tim.mark();
     220         827 :           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         543 :           subImgr.loadMosaicSensitivity();
     225         543 :             Record outrec=subImgr.executeMajorCycle(controlRecord_p);
     226         543 :             if(outrec.isDefined("tempfilenames")){
     227         524 :               returnRec_p.define("tempfilenames", outrec.asArrayString("tempfilenames"));
     228             :             }
     229        1096 :             for(uInt k=0; k < subImStor.nelements(); ++k){
     230         553 :               if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight")){
     231             :                 {
     232         553 :                   if(controlRecord_p.isDefined("normpars")){
     233         553 :                     Record normpars=controlRecord_p.asRecord("normpars");
     234         553 :                     SynthesisNormalizer norm;
     235         553 :                     if(nterms_p[k] > 0){
     236           2 :                       if(!normpars.isDefined("nterms"))
     237           0 :                         normpars.define("nterms", uInt(nterms_p[k]));
     238           2 :                       normpars.define("deconvolver", "mtmfs");
     239             :                     }
     240             :                     
     241         553 :                     norm.setupNormalizer(normpars);
     242         553 :                     norm.setImageStore(subImStorShared[k]);
     243         553 :                     norm.divideResidualByWeight();
     244         553 :                   }
     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         553 :                 subImStor[k]->residual()->unlock();
     253         553 :                 if(subImStor[k]->hasModel())
     254         289 :                   subImStor[k]->model()->unlock();
     255             :               }
     256         553 :               Int chanBeg=0; Int chanEnd=0;
     257         553 :               if(k==0){
     258         543 :                 chanBeg=chanRange_p[0];
     259         543 :                 chanEnd=chanRange_p[1];
     260             :               }
     261             :               else{
     262          10 :                 chanBeg=0;
     263          10 :                 chanEnd=subImStor[k]->sumwt()->shape()[3]-1;
     264             :               }
     265         553 :               if(subImStor[k]->getType() != "multiterm"){
     266         551 :                 writeBackToFullImage(residualNames_p[k], chanBeg, chanEnd, (subImStor[k]->residual()));
     267         551 :                 writeBackToFullImage(sumwtNames_p[k], chanBeg, chanEnd, (subImStor[k]->sumwt()));
     268             :               }
     269             :               
     270             :             }
     271             :             
     272             :             
     273         543 :           }
     274             :           else{
     275         284 :             Record&& outrec=subImgr.makePSF();
     276         283 :             if(outrec.isDefined("tempfilenames")){
     277         283 :               returnRec_p.define("tempfilenames", outrec.asArrayString("tempfilenames"));
     278             :             }
     279             :             ////tclean expects a PB to be always there...
     280             :             //so for standard make it
     281         283 :             subImgr.makePB();
     282         571 :             for(uInt k=0; k < subImStor.nelements(); ++k){
     283         288 :               if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight"))
     284             :                 {
     285         288 :                   if(controlRecord_p.isDefined("normpars")){
     286         288 :                     Record normpars=controlRecord_p.asRecord("normpars");
     287         288 :                     if(nterms_p[k] > 0){
     288           1 :                       if(!normpars.isDefined("nterms"))
     289           0 :                         normpars.define("nterms", uInt(nterms_p[k]));
     290           1 :                       normpars.define("deconvolver", "mtmfs");
     291             :                     }
     292             :                     //                        cerr  << k << " " << nterms_p[k] <<" NORMPARS " << normpars << endl;
     293         288 :                     SynthesisNormalizer norm;
     294         288 :                     norm.setupNormalizer(normpars);
     295         288 :                     norm.setImageStore(subImStorShared[k]);
     296         288 :                     norm.dividePSFByWeight();
     297         288 :                     copyBeamSet(*(subImStorShared[k]->psf()), k);
     298         288 :                   }
     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           0 :                   }
     306             :                 }
     307         288 :               Int chanBeg=0; Int chanEnd=0;
     308         288 :               if(k==0){
     309         283 :                 chanBeg=chanRange_p[0];
     310         283 :                 chanEnd=chanRange_p[1];
     311             :               }
     312             :               else{
     313           5 :                 chanBeg=0;
     314           5 :                 chanEnd=subImStor[k]->sumwt()->shape()[3]-1;
     315             :               }
     316         288 :               if(subImStor[k]->getType() != "multiterm"){
     317         287 :                 writeBackToFullImage(psfNames_p[k], chanBeg, chanEnd, (subImStor[k]->psf()));
     318         287 :                 writeBackToFullImage(sumwtNames_p[k], chanBeg, chanEnd, (subImStor[k]->sumwt()));
     319         287 :                 if((subImStor[k]->hasSensitivity()) && Table::isWritable(weightNames_p[k])){
     320          60 :                   writeBackToFullImage(weightNames_p[k], chanBeg, chanEnd, (subImStor[k]->weight()));
     321             :                   
     322             :                 }
     323         287 :                 if( doPB_p && Table::isWritable(pbNames_p[k])){
     324         227 :                   writeBackToFullImage(pbNames_p[k], chanBeg, chanEnd, (subImStor[k]->pb()));
     325             :                   
     326             :                 }
     327             :                 
     328             :               }
     329         288 :               subImStor[k]->psf()->unlock();
     330             :               
     331             :             }
     332         283 :           }
     333             :         //cerr << "***Time gridding/ffting " << tim.real() << endl;
     334         826 :           status_p = True;
     335         830 :         }
     336           1 :         catch (AipsError x) {
     337             : 
     338           2 :            LogIO os( LogOrigin("SynthesisImagerVi2","CubeMajorCycle",WHERE) );
     339           1 :            os << LogIO::WARN << "Exception for chan range "  << chanRange_p  << " ---   "<< x.getMesg()   << LogIO::POST;
     340           1 :           cerr << "##################################\n#############################\nException: " << x.getMesg() << endl;
     341             : 
     342           1 :           status_p=false;
     343           1 :         }
     344           0 :         catch(std::exception& exc) {
     345           0 :           logger << LogIO::SEVERE << "Exception (std): " << exc.what() << LogIO::POST;
     346           0 :           returnRec_p=Record();
     347           0 :         }
     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           0 :           }
     359             : 
     360           0 :           logger << LogIO::SEVERE << "Unknown exception "  << LogIO::POST;
     361           0 :           status_p=False;
     362           0 :         }
     363         827 : }
     364        3309 : String&     CubeMajorCycleAlgorithm::name(){
     365        3309 :         return myName_p;
     366             : }
     367             : 
     368         842 :   shared_ptr<SIImageStore> CubeMajorCycleAlgorithm::subImageStore(const int imId){
     369             :         //For some reason multiterm deconvolver is allowed with cubes !
     370         842 :         String isMTdeconv="";
     371         842 :         nterms_p.resize(imId+1, True);
     372         842 :         nterms_p[imId]=-1;
     373         842 :         if(imId==0 && imSel_p[imId].deconvolver=="mtmfs"){
     374           0 :           isMTdeconv=".tt0";
     375           0 :           nterms_p[0]=1;
     376             :         }
     377             :         
     378         842 :         String residname=imSel_p[imId].imageName+".residual"+isMTdeconv;
     379         842 :         String psfname=imSel_p[imId].imageName+".psf"+isMTdeconv;
     380         842 :         String sumwgtname=imSel_p[imId].imageName+".sumwt"+isMTdeconv;
     381         842 :         if(imId > 0 && !Table::isReadable(sumwgtname)){
     382           3 :                 return multiTermImageStore(imId);
     383             :         }
     384         839 :         shared_ptr<ImageInterface<Float> >subpsf=nullptr;
     385         839 :         shared_ptr<ImageInterface<Float> >subresid=nullptr;
     386         839 :         shared_ptr<ImageInterface<Float> >submodel=nullptr;
     387         839 :         shared_ptr<ImageInterface<Float> > subweight=nullptr;
     388         839 :         shared_ptr<ImageInterface<Float> > subpb=nullptr;
     389             :         //cerr << imId << " sumwt name " << sumwgtname << endl;
     390         839 :         String workingdir="";
     391         839 :         if(controlRecord_p.isDefined("workingdirectory"))
     392         839 :                 controlRecord_p.get("workingdirectory", workingdir);
     393             :         //cerr <<"WORKINGDIR " << workingdir << endl;
     394         839 :         if(Table::isReadable(workingdir+"/"+sumwgtname)){
     395         839 :                 workingdir=workingdir+"/";
     396         839 :                 residname=workingdir+residname;
     397         839 :                 psfname=workingdir+psfname;
     398         839 :                 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         839 :         PagedImage<Float> sumwt(sumwgtname, TableLock::UserLocking);
     407         839 :         sumwt.lock(FileLocker::Write, 200);
     408             :         //PagedImage<Float> sumwt(sumwgtname, TableLock::AutoNoReadLocking);
     409         839 :         if(sumwtNames_p.nelements() <= uInt(imId)){
     410         839 :           sumwtNames_p.resize(imId+1, True);
     411         839 :           psfNames_p.resize(imId+1, True);
     412         839 :           residualNames_p.resize(imId+1, True);
     413         839 :           sumwtNames_p[imId]=sumwgtname;
     414         839 :           residualNames_p[imId]=residname;
     415         839 :           psfNames_p[imId]=psfname;
     416             :         }
     417         839 :         Int nchannels=sumwt.shape()[3];
     418             : 
     419             :        
     420             :        
     421             :         //Should be partitioning for main image only
     422             :         //chanRange
     423         839 :         Int chanBeg=0;
     424         839 :         Int chanEnd=0;
     425         839 :         if(imId==0){
     426         827 :                 chanBeg=chanRange_p[0];
     427         827 :                 chanEnd=chanRange_p[1];
     428             :         }
     429             :         else{
     430          12 :                 chanBeg=0;
     431          12 :                 chanEnd=sumwt.shape()[3]-1;
     432             :         }
     433         839 :         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         839 :         Vector<String> weightnams(controlRecord_p.asArrayString("weightnames"));
     443         839 :         Vector<String> pbnams(controlRecord_p.asArrayString("pbnames"));
     444         839 :         pbNames_p.resize();
     445         839 :         pbNames_p=pbnams;
     446         839 :         weightNames_p.resize();
     447         839 :         weightNames_p=weightnams;
     448             :         
     449         839 :         if(imId >= int(weightNames_p.nelements()))
     450           0 :           throw(AipsError("Number of weight images does not match number of image fields defined"));
     451         839 :         if(Table::isReadable(workingdir+weightNames_p[imId])){
     452           0 :                 weightNames_p[imId]=workingdir+weightNames_p[imId];
     453             :         }
     454         839 :          if(Table::isReadable(workingdir+pbNames_p[imId])){
     455           0 :                 pbNames_p[imId]=workingdir+pbNames_p[imId];
     456             :         }
     457             :        
     458         839 :         if(dopsf_p){
     459             :           //PagedImage<Float> psf(psfname, TableLock::UserNoReadLocking);
     460             :           //subpsf.reset(SpectralImageUtil::getChannel(psf, chanBeg, chanEnd, true));
     461         288 :           getSubImage(subpsf, chanBeg, chanEnd, psfname, False);
     462             :           //cerr << "PBNAMES " << pbNames_p << endl;
     463         288 :           if(Table::isReadable(pbNames_p[imId])){
     464             : 
     465         228 :             doPB_p=True;
     466         228 :             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         551 :           getSubImage(subresid, chanBeg, chanEnd, residname, False);
     474             :  
     475         551 :           if(controlRecord_p.isDefined("modelnames")){
     476         288 :                         Vector<String> modelnames(controlRecord_p.asArrayString("modelnames"));
     477         288 :                         if(imId >= int(modelnames.nelements()))
     478           0 :                                 throw(AipsError("Number of model images does not match number of image fields defined"));
     479         288 :                         if(Table::isReadable(workingdir+modelnames[imId])){
     480         288 :                                 modelnames[imId]=workingdir+modelnames[imId];
     481             :                         }
     482         288 :                         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         288 :                                 Int startmodchan=(chanBeg-2) >0 ? chanBeg-2 : 0;
     487         288 :                                 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         288 :                                 getSubImage(submodel, startmodchan, endmodchan, modelnames[imId], True);
     495             :                                 //
     496         288 :                                 if(Table::isReadable(weightNames_p[imId])){
     497          71 :                                   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         288 :                 }
     505             :                 
     506             :         }
     507             :         
     508         839 :         if(Table::isReadable(weightNames_p[imId])){
     509             :           //PagedImage<Float> weight(weightnames[imId], TableLock::UserNoReadLocking);
     510             :           //subweight.reset(SpectralImageUtil::getChannel(weight, chanBeg, chanEnd, true));
     511         179 :           getSubImage(subweight, chanBeg, chanEnd, weightNames_p[imId], True); 
     512             :         }
     513         839 :         shared_ptr<ImageInterface<Float> >subsumwt=nullptr;
     514             :         //      subsumwt.reset(SpectralImageUtil::getChannel(sumwt, chanBeg, chanEnd, true));
     515         839 :         getSubImage(subsumwt, chanBeg, chanEnd, sumwgtname, True);
     516         839 :         bool useweightimage=(subweight) ? true : false;
     517        1678 :         shared_ptr<SIImageStore> subimstor(new SimpleSIImageStore(imSel_p[imId].imageName, submodel, subresid, subpsf, subweight, nullptr, nullptr, subsumwt, nullptr, subpb, nullptr, nullptr, useweightimage));
     518         839 :         if(polRep_p[imId]< 0)
     519           0 :                 throw(AipsError("data polarization type is not defined"));
     520         839 :         StokesImageUtil::PolRep polrep=(StokesImageUtil::PolRep)polRep_p[imId];
     521         839 :         subimstor->setDataPolFrame(polrep);
     522         839 :         if(startmodel_p[imId].nelements() >0){
     523           3 :           LatticeLocker lock1 (*(subimstor->model()), FileLocker::Write);
     524           3 :                 subimstor->setModelImage(startmodel_p[imId]);        
     525           3 :         }
     526             :         //cerr << "subimagestor TYPE" << subimstor->getType() << endl;
     527         839 :         return subimstor;
     528         842 : }
     529             : 
     530             :   
     531           3 :   std::shared_ptr<SIImageStore> CubeMajorCycleAlgorithm::multiTermImageStore(const Int imId){
     532           3 :         uInt nterms=0;
     533           6 :         String sumwgtname=imSel_p[imId].imageName+".sumwt.tt"+String::toString(nterms);
     534          12 :         while (Table::isReadable(sumwgtname)){
     535           9 :                 ++nterms;
     536           9 :                 sumwgtname=imSel_p[imId].imageName+".sumwt.tt"+String::toString(nterms);
     537             :         }
     538           3 :         if(nterms==0){
     539           0 :                 throw(AipsError("outlier "+String::toString(imId)+" field weight image is not defined"));
     540             :         }
     541           3 :         nterms=(nterms+1)/2;
     542           3 :         nterms_p[imId]=nterms;
     543           3 :         shared_ptr<SIImageStore> subimstor(new SIImageStoreMultiTerm(imSel_p[imId].imageName, nterms, True));
     544           3 :         if(polRep_p[imId]< 0)
     545           0 :                 throw(AipsError("data polarization type is not defined"));
     546           3 :         StokesImageUtil::PolRep polrep=(StokesImageUtil::PolRep)polRep_p[imId];
     547           3 :         subimstor->setDataPolFrame(polrep);
     548           6 :         return subimstor;
     549           3 : }
     550          71 :   void CubeMajorCycleAlgorithm::divideModelByWeight(casacore::String imageName, shared_ptr<ImageInterface<Float> >&submodel, const Int startchan, const Int endchan, const String weightname){
     551          71 :     if(controlRecord_p.isDefined("dividebyweight") && controlRecord_p.asBool("dividebyweight")){
     552          71 :       if(controlRecord_p.isDefined("normpars")){
     553          71 :                         Record normpars=controlRecord_p.asRecord("normpars");
     554          71 :                         SynthesisNormalizer norm;
     555          71 :                         norm.setupNormalizer(normpars);
     556          71 :                         shared_ptr<ImageInterface<Float> > subweight=nullptr;
     557          71 :                         getSubImage(subweight, startchan, endchan, weightname, True);
     558          71 :                         LatticeLocker lock1(*(subweight), FileLocker::Read);
     559          71 :                         LatticeLocker lock2(*(submodel), FileLocker::Read);
     560         142 :                         std::shared_ptr<SIImageStore> subimstor(new SimpleSIImageStore(imageName, submodel, nullptr, nullptr, subweight, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, True));
     561          71 :                         norm.setImageStore(subimstor);
     562          71 :                         norm.divideModelByWeight();
     563             :                         
     564          71 :       }
     565             :     }
     566          71 :   }
     567             : 
     568             : 
     569             : 
     570             :                                                                                                                                                      
     571         827 : void CubeMajorCycleAlgorithm::reset(){
     572             :                 
     573         827 :                 dataSel_p.resize();
     574         827 :                 imSel_p.resize();
     575         827 :                 gridSel_p.resize();
     576         827 :                 ftmRec_p.resize();
     577         827 :                 iftmRec_p.resize();
     578         827 :                 polRep_p.resize();
     579         827 :                 chanRange_p.resize();
     580         827 :                 dopsf_p=False;
     581         827 :                 controlRecord_p=Record();
     582         827 :                 weightParams_p=Record();
     583         827 :                 returnRec_p=Record();
     584         827 :                 startmodel_p.resize();
     585         827 :                 status_p=False;
     586         827 :                 residualNames_p.resize();
     587         827 :                 psfNames_p.resize();
     588         827 :                 sumwtNames_p.resize();
     589         827 :                 weightNames_p.resize();
     590         827 :                 pbNames_p.resize();
     591         827 :                 movingSource_p="";
     592         827 :                 retuning_p=True;
     593         827 :                 doPB_p=False;
     594         827 :                 nterms_p.resize();
     595             :                 
     596             :         
     597             :         
     598         827 : }
     599             :         
     600        2444 :   void CubeMajorCycleAlgorithm::getSubImage(std::shared_ptr<ImageInterface<Float> >& subimptr, const Int chanBeg, const Int chanEnd, const String imagename, const Bool copy){
     601        4888 :     LogIO os( LogOrigin("CubeMajorCycle","getSubImage",WHERE) );
     602        2444 :     CountedPtr<PagedImage<Float> > im=nullptr;
     603             :     {///work around
     604        2444 :       uInt exceptCounter=0;
     605             :       while(true){
     606             :         try{
     607        2444 :           im = new PagedImage<Float> (imagename, TableLock::UserLocking);
     608             :           //PagedImage<Float> im(imagename, TableLock::AutoNoReadLocking);
     609        2444 :           im->lock(FileLocker::Read, 1000);
     610        2444 :           SubImage<Float> *tmpptr=nullptr;
     611        2444 :           tmpptr=SpectralImageUtil::getChannel(*im, chanBeg, chanEnd, false);
     612        2444 :           subimptr.reset(new TempImage<Float>(TiledShape(tmpptr->shape(), tmpptr->niceCursorShape()), tmpptr->coordinates()));
     613             :           
     614        2444 :           if(copy)
     615        1377 :             subimptr->copyData(*tmpptr);
     616             :           //subimptr->flush();
     617        2444 :           im->unlock();
     618        2444 :           delete tmpptr;
     619        2444 :           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           0 :         }
     637           0 :         ++exceptCounter;
     638           0 :       }
     639             :     }     
     640             : 
     641        2444 :   }
     642             : 
     643        1963 :   void CubeMajorCycleAlgorithm::writeBackToFullImage(const String imagename, const Int chanBeg, const Int chanEnd, std::shared_ptr<ImageInterface<Float> > subimptr){
     644        3926 :     LogIO os( LogOrigin("CubeMajorCycle","writebacktofullimage",WHERE) );
     645        1963 :     CountedPtr<PagedImage<Float> > im=nullptr;
     646             :     {///work around
     647        1963 :       uInt exceptCounter=0;
     648             :       while(true){
     649             :         try{
     650        1963 :           im=new PagedImage<Float> (imagename, TableLock::UserLocking);
     651             :           
     652             :           
     653             :           //PagedImage<Float> im(imagename, TableLock::AutoLocking);
     654        1963 :           SubImage<Float> *tmpptr=nullptr;
     655             :           {
     656        1963 :             tmpptr=SpectralImageUtil::getChannel(*im, chanBeg, chanEnd, true);
     657        1963 :             LatticeLocker lock1 (*(tmpptr), FileLocker::Write);
     658        1963 :             tmpptr->set(0.0);
     659        1963 :             tmpptr->copyData(*(subimptr));
     660        1963 :           }
     661        1963 :           im->flush();
     662        1963 :           im->unlock();
     663        1963 :           delete tmpptr;
     664        1963 :           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           0 :         }
     682           0 :         ++exceptCounter;
     683           0 :       }
     684             :     }//End of work around for table disappearing bug
     685             : 
     686             :     
     687        1963 :   }
     688         288 :   void CubeMajorCycleAlgorithm::copyBeamSet(ImageInterface<Float>& subpsf, const Int imageid){
     689             :     //For now lets do for the main image only
     690         288 :     if(imageid != 0)
     691           5 :       return;
     692         283 :     ImageBeamSet iibeamset=subpsf.imageInfo().getBeamSet();
     693         283 :     uInt nchan=chanRange_p[1]-chanRange_p[0]+1;
     694         283 :     if(nchan ==iibeamset.nchan()){
     695         283 :       Matrix<GaussianBeam> gbs=iibeamset.getBeams();
     696         283 :       Cube<Float> beams(nchan, iibeamset.nstokes(),3);
     697             :       
     698        2549 :       for (uInt k=0; k < nchan; ++k){
     699        4703 :         for (uInt j=0; j < iibeamset.nstokes(); ++j){
     700        2437 :           beams(k,j, 0)=gbs(k, 0).getMajor("arcsec");
     701        2437 :           beams(k,j, 1)=gbs(k, 0).getMinor("arcsec");
     702        2437 :           beams(k,j, 2)=gbs(k, 0).getPA("deg", True);
     703             :         }
     704             :       }
     705         283 :       returnRec_p.define("imageid", imageid);
     706         283 :       returnRec_p.define("chanrange", chanRange_p);
     707         283 :       returnRec_p.define("beams", beams);
     708             : 
     709             : 
     710         283 :     }
     711             : 
     712             : 
     713             : 
     714         283 :   }
     715             :         
     716             :         
     717             :         
     718             : } //# NAMESPACE CASA - END

Generated by: LCOV version 1.16