LCOV - code coverage report
Current view: top level - synthesis/ImagerObjects - SDAlgorithmBase.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 15 208 7.2 %
Date: 2025-08-21 08:01:32 Functions: 4 12 33.3 %

          Line data    Source code
       1             : //# SDAlgorithmBase.cc: Implementation of SDAlgorithmBase classes
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
       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 Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 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 Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id$
      27             : 
      28             : #include <casacore/casa/Arrays/ArrayMath.h>
      29             : #include <casacore/casa/OS/HostInfo.h>
      30             : #include <synthesis/ImagerObjects/SDAlgorithmBase.h>
      31             : #include <components/ComponentModels/SkyComponent.h>
      32             : #include <components/ComponentModels/ComponentList.h>
      33             : #include <casacore/images/Images/TempImage.h>
      34             : #include <casacore/images/Images/SubImage.h>
      35             : #include <casacore/images/Regions/ImageRegion.h>
      36             : #include <casacore/casa/OS/File.h>
      37             : #include <casacore/lattices/LEL/LatticeExpr.h>
      38             : #include <casacore/lattices/Lattices/TiledLineStepper.h>
      39             : #include <casacore/lattices/Lattices/LatticeStepper.h>
      40             : #include <casacore/lattices/Lattices/LatticeIterator.h>
      41             : #include <synthesis/TransformMachines/StokesImageUtil.h>
      42             : #include <casacore/coordinates/Coordinates/StokesCoordinate.h>
      43             : #include <casacore/casa/Exceptions/Error.h>
      44             : #include <casacore/casa/BasicSL/String.h>
      45             : #include <casacore/casa/Utilities/Assert.h>
      46             : #include <casacore/casa/OS/Directory.h>
      47             : #include <casacore/tables/Tables/TableLock.h>
      48             : 
      49             : #include<synthesis/ImagerObjects/SIMinorCycleController.h>
      50             : #include <imageanalysis/ImageAnalysis/CasaImageBeamSet.h>
      51             : 
      52             : #include <sstream>
      53             : #include <casacore/casa/OS/EnvVar.h>
      54             : 
      55             : #include <casacore/casa/Logging/LogMessage.h>
      56             : #include <casacore/casa/Logging/LogIO.h>
      57             : #include <casacore/casa/Logging/LogSink.h>
      58             : 
      59             : using namespace casacore;
      60             : namespace casa { //# NAMESPACE CASA - BEGIN
      61             : 
      62             : 
      63          17 :   SDAlgorithmBase::SDAlgorithmBase():
      64          17 :     itsAlgorithmName("Test")
      65             :     //    itsDecSlices (),
      66             :     //    itsResidual(), itsPsf(), itsModel()
      67             :  {
      68          17 :  }
      69             : 
      70          17 :   SDAlgorithmBase::~SDAlgorithmBase()
      71             :  {
      72             :    
      73          17 :  }
      74             : 
      75             : 
      76           0 :   void SDAlgorithmBase::deconvolve( SIMinorCycleController &loopcontrols, 
      77             :                                     std::shared_ptr<SIImageStore> &imagestore,
      78             :                                     Int deconvolverid,
      79             :                                     Bool isautomasking, Bool fastnoise, Record robuststats, bool fullsummary)
      80             :   {
      81           0 :     LogIO os( LogOrigin("SDAlgorithmBase","deconvolve",WHERE) );
      82             : 
      83             :     // Make a list of Slicers.
      84             :     //partitionImages( imagestore );
      85             : 
      86             :     Int nSubChans, nSubPols;
      87           0 :     queryDesiredShape(nSubChans, nSubPols, imagestore->getShape());
      88             : 
      89             :     //    cout << "Check imstore from deconvolver : " << endl;
      90           0 :     imagestore->validate();
      91             : 
      92             :     //itsImages = imagestore;
      93             : 
      94             :     //    loadMask();
      95             : 
      96             :     //os << "-------------------------------------------------------------------------------------------------------------" << LogIO::POST;
      97             : 
      98             : 
      99           0 :     os << "[" << imagestore->getName() << "]";
     100           0 :     os << " Run " << itsAlgorithmName << " minor-cycle " ;
     101           0 :     if( nSubChans>1 || nSubPols>1 ) os << "on ";
     102           0 :     if( nSubChans >1 ) os << nSubChans << " chans " ;
     103           0 :     if( nSubPols >1 ) os << nSubPols << " pols ";
     104           0 :     os << "| CycleThreshold=" << loopcontrols.getCycleThreshold()
     105             :        << ", CycleNiter=" << loopcontrols.getCycleNiter() 
     106           0 :        << ", Gain=" << loopcontrols.getLoopGain()
     107           0 :        << LogIO::POST;
     108             : 
     109           0 :     Float itsPBMask = loopcontrols.getPBMask();
     110           0 :     Int cycleStartIteration = loopcontrols.getIterDone();
     111             : 
     112           0 :     Float maxResidualAcrossPlanes=0.0; Int maxResChan=0,maxResPol=0;
     113           0 :     Float totalFluxAcrossPlanes=0.0;
     114             : 
     115           0 :     for( Int chanid=0; chanid<nSubChans;chanid++)
     116             :       {
     117           0 :         for( Int polid=0; polid<nSubPols; polid++)
     118             :           {
     119             :             //      itsImages = imagestore->getSubImageStoreOld( chanid, onechan, polid, onepol );
     120           0 :             itsImages = imagestore->getSubImageStore( 0, 1, chanid, nSubChans, polid, nSubPols );
     121             : 
     122           0 :             Int startiteration = loopcontrols.getIterDone(); // TODO : CAS-8767 key off subimage index
     123           0 :             Float peakresidual=0.0, peakresidualnomask=0.0;
     124           0 :             Float modelflux=0.0;
     125           0 :             Int iterdone=0;
     126             : 
     127             :             ///itsMaskHandler.resetMask( itsImages ); //, (loopcontrols.getCycleThreshold()/peakresidual) );
     128           0 :             Int stopCode=0;
     129             : 
     130           0 :             Float startpeakresidual = 0.0, startpeakresidualnomask = 0.0;
     131           0 :             Float startmodelflux = 0.0;
     132           0 :             Array<Double> robustrms;
     133             : 
     134           0 :             Float masksum = itsImages->getMaskSum();
     135           0 :             Bool validMask = ( masksum > 0 );
     136             : 
     137           0 :             peakresidualnomask = itsImages->getPeakResidual();
     138           0 :             if( validMask ) peakresidual = itsImages->getPeakResidualWithinMask();
     139           0 :         else peakresidual = 0; // CAS-14201 : If mask is zero, peakresidual is zero
     140             :             //else peakresidual = peakresidualnomask;
     141           0 :             modelflux = itsImages->getModelFlux();
     142             : 
     143           0 :             startpeakresidual = peakresidual;
     144           0 :             startpeakresidualnomask = peakresidualnomask;
     145           0 :             startmodelflux = modelflux;
     146             : 
     147             :             //Float nsigma = 150.0; // will set by user, fixed for 3sigma for now.
     148           0 :             Float nsigma = loopcontrols.getNsigma();
     149             :             //os<<"robustrms nelements="<<robustrms.nelements()<<LogIO::POST;
     150             :             Float nsigmathresh; 
     151           0 :             if (robustrms.nelements()==0) {
     152           0 :               nsigmathresh = 0.0; 
     153             :             } else{
     154           0 :               nsigmathresh = nsigma * (Float)robustrms(IPosition(1,0)); 
     155             :             }
     156             :               
     157             :             Float thresholdtouse;
     158           0 :             if (nsigma>0.0) {
     159             :               // returns as an Array but itsImages is already single plane so 
     160             :               // the return rms contains only a single element
     161           0 :               Array<Double> medians;
     162             :               //os<<"robuststats rec size="<<robuststats.nfields()<<LogIO::POST;
     163           0 :               Bool statsexists = false;
     164           0 :               IPosition statsindex;
     165           0 :               if (robuststats.nfields()) {
     166             :                 // use existing stats
     167           0 :                 if (robuststats.isDefined("robustrms")) {
     168           0 :                   robuststats.get(RecordFieldId("robustrms"), robustrms);
     169           0 :                   robuststats.get(RecordFieldId("median"), medians);
     170           0 :                   statsexists=True;
     171             :                   
     172             :                 }
     173           0 :                 else if(robuststats.isDefined("medabsdevmed")) {
     174           0 :                   Array<Double> mads;
     175           0 :                   robuststats.get(RecordFieldId("medabsdevmed"), mads);
     176           0 :                   robuststats.get(RecordFieldId("median"), medians);
     177           0 :                   robustrms = mads * 1.4826; // convert to rms
     178           0 :                   statsexists=True;
     179             :                   
     180           0 :                 }
     181             :                 //statsindex=IPosition(1,chanid); // this only support for npol =1, need to fix this
     182           0 :                 if((robustrms.shape().nelements() ==2) && (robustrms.shape()[0] > polid) &&  (robustrms.shape()[1] > chanid) )
     183           0 :                   statsindex=IPosition(2,polid,chanid);
     184           0 :                 else if((robustrms.shape().nelements() ==1) && (robustrms.shape()[0] > chanid))
     185           0 :                   statsindex=IPosition(1,chanid);
     186             :                 else ///no idea what got passed in the record
     187           0 :                   statsexists=False;
     188             :                 
     189             :               }
     190           0 :               if (statsexists) {
     191           0 :                 os<<LogIO::DEBUG1<<"Using the existing robust image statatistics!"<<LogIO::POST;
     192             :               } 
     193             :               else {
     194           0 :                 robustrms = itsImages->calcRobustRMS(medians, itsPBMask, fastnoise);
     195           0 :                 statsindex=IPosition(1,0);
     196             :               }
     197           0 :               if (isautomasking) { // new threshold defination 
     198             :                 //nsigmathresh = (Float)medians(IPosition(1,0)) + nsigma * (Float)robustrms(IPosition(1,0));
     199           0 :                 nsigmathresh = (Float)medians(statsindex) + nsigma * (Float)robustrms(statsindex);
     200             :               }
     201             :               else {
     202           0 :                 nsigmathresh = nsigma * (Float)robustrms(statsindex);
     203             :               }
     204           0 :               thresholdtouse = max( nsigmathresh, loopcontrols.getCycleThreshold());
     205           0 :             }
     206             :             else {
     207           0 :               thresholdtouse = loopcontrols.getCycleThreshold();
     208             :             }
     209             :             //os << LogIO::DEBUG1<<"loopcontrols.getCycleThreshold()="<<loopcontrols.getCycleThreshold()<<LogIO::POST;
     210           0 :             os << LogIO::NORMAL3<<"current CycleThreshold="<<loopcontrols.getCycleThreshold()<<" nsigma threshold="<<nsigmathresh<<LogIO::POST;
     211           0 :             String thresholddesc = (thresholdtouse == loopcontrols.getCycleThreshold() ? "cyclethreshold" : "n-sigma");
     212           0 :             os << LogIO::NORMAL3<< "thresholdtouse="<< thresholdtouse << "("<<thresholddesc<<")"<< LogIO::POST;
     213             : 
     214           0 :             if (thresholddesc=="n-sigma") {
     215             :               //os << LogIO::DEBUG1<< "Set nsigma thresh="<<nsigmathresh<<LogIO::POST;
     216           0 :               loopcontrols.setNsigmaThreshold(nsigmathresh);
     217             :             }
     218           0 :             loopcontrols.setPeakResidual( peakresidual );
     219           0 :             loopcontrols.resetMinResidual(); // Set it to current initial peakresidual.
     220             :             
     221           0 :             stopCode = checkStop( loopcontrols,  peakresidual );
     222             : 
     223           0 :             if( validMask && stopCode==0 )
     224             :               {
     225             :                 // Init the deconvolver
     226             :                  //where we write in model and residual may be
     227             :                 {
     228             : 
     229           0 :                   LatticeLocker lockresid (*(itsImages->residual()), FileLocker::Read);
     230           0 :                   LatticeLocker lockmodel (*(itsImages->model()), FileLocker::Read);
     231           0 :                   LatticeLocker lockmask (*(itsImages->mask()), FileLocker::Read);
     232           0 :                   LatticeLocker lockpsf (*(itsImages->psf()), FileLocker::Read);
     233             :                   
     234           0 :                   initializeDeconvolver();
     235           0 :                 }
     236             :                 
     237           0 :                 while ( stopCode==0 )
     238             :                   {
     239             : 
     240           0 :                     if (nsigma>0.0) {
     241           0 :                       os << "Using " << thresholddesc << " for threshold criterion: (cyclethreshold="<<loopcontrols.getCycleThreshold()<< ", nsigma threshold="<<nsigmathresh<<" )" << LogIO::POST;
     242           0 :                       loopcontrols.setNsigmaThreshold(nsigmathresh);
     243             :                     }
     244           0 :                     Int thisniter = loopcontrols.getCycleNiter() <5000 ? loopcontrols.getCycleNiter() : 2000;
     245             : 
     246           0 :                     loopcontrols.setPeakResidual( peakresidual );
     247             : 
     248             :                      //where we write in model and residual may be
     249             :                     {
     250             :                       //no need to lock here as only arrays are used
     251             : 
     252             :                       //LatticeLocker lock1 (*(itsImages->residual()), FileLocker::Write);
     253             :                       //LatticeLocker lock2 (*(itsImages->model()), FileLocker::Write);
     254           0 :                     takeOneStep( loopcontrols.getLoopGain(), 
     255             :                                  //                              loopcontrols.getCycleNiter(),
     256             :                                  thisniter,
     257             :                                  //loopcontrols.getCycleThreshold(),
     258             :                                  thresholdtouse,
     259             :                                  peakresidual, 
     260             :                                  modelflux,
     261             :                                  iterdone);
     262             :                     }
     263             : 
     264           0 :                     os << LogIO::NORMAL1  << "SDAlgoBase: After one step, dec : " << deconvolverid << "    residual=" << peakresidual << " model=" << modelflux << " iters=" << iterdone << LogIO::POST; 
     265             : 
     266           0 :                     SynthesisUtilMethods::getResource("In Deconvolver : one step" );
     267             :                     
     268           0 :                     loopcontrols.incrementMinorCycleCount( iterdone ); // CAS-8767 : add subimageindex and merge with addSummaryMinor call later.
     269             :                     
     270           0 :                     stopCode = checkStop( loopcontrols,  peakresidual );
     271             : 
     272             :                     /// Catch the situation where takeOneStep returns without satisfying any
     273             :                     ///  convergence criterion. For now, takeOneStep is the entire minor cycle.
     274             :                     /// Later, when you can interrupt minor cycles, takeOneStep will become more
     275             :                     /// fine grained, and then stopCode=0 will be valid.  For now though, check on
     276             :                     /// it and handle it (for CAS-7898).
     277           0 :                     if(stopCode==0 && iterdone != thisniter)
     278             :                       {
     279           0 :                         os << LogIO::NORMAL1 << "Exited " << itsAlgorithmName << " minor cycle without satisfying stopping criteria " << LogIO::POST;
     280           0 :                         stopCode=5;
     281             :                       }
     282             :                     
     283             :                   }// end of minor cycle iterations for this subimage.
     284             : 
     285             :                 //where we write in model and residual may be
     286             :                 {
     287             : 
     288           0 :                   LatticeLocker lock1 (*(itsImages->residual()), FileLocker::Write);
     289           0 :                   LatticeLocker lock2 (*(itsImages->model()), FileLocker::Write);
     290           0 :                   finalizeDeconvolver();
     291           0 :                 }
     292             : 
     293             :                 // get the new peakres without a mask for the summary minor
     294           0 :                 peakresidualnomask = itsImages->getPeakResidual();
     295             : 
     296             :               }// if validmask
     297             :             
     298             :             // same as checking on itscycleniter.....
     299           0 :             loopcontrols.setUpdatedModelFlag( loopcontrols.getIterDone()-startiteration );
     300             :             
     301           0 :             os << "[" << imagestore->getName();
     302           0 :             if(nSubChans>1) os << ":C" << chanid ;
     303           0 :             if(nSubPols>1) os << ":P" << polid ;
     304           0 :             Int iterend = loopcontrols.getIterDone();
     305             :             os << "]"
     306             :               //               <<" iters=" << ( (iterend>startiteration) ? startiteration+1 : startiteration )<< "->" << iterend
     307             :                <<" iters=" << startiteration << "->" << iterend << " [" << iterend-startiteration << "]"
     308             :                << ", model=" << startmodelflux << "->" << modelflux
     309           0 :                << ", peakres=" << startpeakresidual << "->" << peakresidual ;
     310             : 
     311           0 :             switch (stopCode)
     312             :               {
     313           0 :               case 0:
     314           0 :                 os << ", Skipped this plane. Zero mask.";
     315           0 :                 break;
     316           0 :               case 1: 
     317           0 :                 os << ", Reached cycleniter.";
     318           0 :                 break;
     319           0 :               case 2:
     320           0 :                 os << ", Reached cyclethreshold.";
     321           0 :                 break;
     322           0 :               case 3:
     323           0 :                 os << ", Zero iterations performed.";
     324           0 :                 break;
     325           0 :               case 4:
     326           0 :                 os << ", Possible divergence. Peak residual increased by 10% from minimum.";
     327           0 :                 break;
     328           0 :               case 5:
     329           0 :                 os << ", Exited " << itsAlgorithmName << " minor cycle without reaching any stopping criterion.";
     330           0 :                 break;
     331           0 :               case 6:
     332           0 :                 os << ", Reached n-sigma threshold.";
     333           0 :               default:
     334           0 :                 break;
     335             :               }
     336             : 
     337           0 :                os << LogIO::POST;
     338             :                
     339           0 :             Int rank(0);
     340           0 :             String rankStr = EnvironmentVariable::get("OMPI_COMM_WORLD_RANK");
     341           0 :             if (!rankStr.empty()) {
     342           0 :               rank = stoi(rankStr);
     343             :             }
     344             : 
     345           0 :             int chunkId = chanid; // temporary CAS-13683 workaround
     346           0 :             loopcontrols.addSummaryMinor( deconvolverid, chunkId, polid, cycleStartIteration,
     347             :                                           startiteration, startmodelflux, startpeakresidual, startpeakresidualnomask,
     348             :                                           modelflux, peakresidual, peakresidualnomask, masksum, rank, stopCode, fullsummary);
     349           0 :             loopcontrols.resetCycleIter(); 
     350             : 
     351           0 :             if( peakresidual > maxResidualAcrossPlanes && stopCode!=0 )
     352           0 :               {maxResidualAcrossPlanes=peakresidual; maxResChan=chanid; maxResPol=polid;}
     353             : 
     354           0 :             totalFluxAcrossPlanes += modelflux;
     355             :             
     356           0 :           }// end of polid loop
     357             :         
     358             :       }// end of chanid loop
     359             :     
     360           0 :     loopcontrols.setPeakResidual( maxResidualAcrossPlanes );
     361             : 
     362             :     /// Print total flux over all planes (and max res over all planes). IFF there are more than one plane !!
     363           0 :     if( nSubChans>1 || nSubPols>1 )
     364             :       {
     365           0 :         os << "[" << imagestore->getName() << "] ";
     366           0 :         os << "Total model flux (over all planes) : " << totalFluxAcrossPlanes; //<< LogIO::POST;
     367           0 :         os << "     Peak Residual (over all planes) : " << maxResidualAcrossPlanes << " in C"<<maxResChan << ":P"<<maxResPol << LogIO::POST;
     368             :       }
     369             : 
     370           0 :   }// end of deconvolve
     371             :   
     372           0 :   Int SDAlgorithmBase::checkStop( SIMinorCycleController &loopcontrols, 
     373             :                                    Float currentresidual )
     374             :   {
     375           0 :     return loopcontrols.majorCycleRequired(currentresidual);
     376             :   }
     377             : 
     378           0 :   Long SDAlgorithmBase::estimateRAM(const vector<int>& imsize){
     379           0 :     Long mem=0;
     380           0 :     if(itsImages)
     381             :     //Simple deconvolvers will have psf + residual + model + mask (1 plane at a time)
     382           0 :       mem=sizeof(Float)*(itsImages->getShape()(0))*(itsImages->getShape()(1))*4/1024;
     383           0 :     else if(imsize.size() >1)
     384           0 :       mem=sizeof(Float)*(imsize[0])*(imsize[1])*4/1024;
     385             :     else
     386           0 :       return 0;
     387             :       //throw(AipsError("Deconvolver cannot estimate the memory usage at this point"));
     388           0 :     return mem;
     389             :   }
     390             : 
     391          17 :   void SDAlgorithmBase::setRestoringBeam( GaussianBeam restbeam, String usebeam )
     392             :   {
     393          34 :     LogIO os( LogOrigin("SDAlgorithmBase","setRestoringBeam",WHERE) );
     394          17 :     itsRestoringBeam = restbeam;
     395          17 :     itsUseBeam = usebeam;
     396          17 :   }
     397             : 
     398             :   /*
     399             :   void SDAlgorithmBase::setMaskOptions( String maskstring )
     400             :   {
     401             :     itsMaskString = maskstring;
     402             :   }
     403             :   */
     404             :   /*
     405             :   void SDAlgorithmBase::loadMask()
     406             :   { 
     407             :     if (! itsIsMaskLoaded ) {
     408             :         if( itsMaskString.length()==0 )   {
     409             :           itsMaskHandler.resetMask( itsImages );
     410             :         }
     411             :         else {
     412             :           itsMaskHandler.fillMask( itsImages->mask() , itsMaskString );
     413             :         }
     414             :         itsIsMaskLoaded=true;
     415             :       }
     416             :   }
     417             :   */
     418             : 
     419          17 :    void SDAlgorithmBase::restore(std::shared_ptr<SIImageStore> imagestore )
     420             :   {
     421             : 
     422          34 :     LogIO os( LogOrigin("SDAlgorithmBase","restore",WHERE) );
     423             : 
     424          17 :     os << "[" << imagestore->getName() << "] : Restoring model image." << LogIO::POST;
     425             : 
     426          17 :     if( imagestore->hasResidualImage() )  imagestore->restore( itsRestoringBeam, itsUseBeam );
     427           0 :     else{os << "Cannot restore with a residual image" << LogIO::POST;}
     428             :       
     429             : 
     430             :    
     431          17 :   }
     432             : 
     433             :  
     434           0 :   void SDAlgorithmBase::pbcor(std::shared_ptr<SIImageStore> imagestore )
     435             :   {
     436             : 
     437           0 :     LogIO os( LogOrigin("SDAlgorithmBase","pbcor",WHERE) );
     438             : 
     439           0 :     os << "[" << imagestore->getName() << "] : Applying PB correction" << LogIO::POST;
     440             : 
     441           0 :     imagestore->pbcor();
     442             : 
     443           0 :   }
     444             :   
     445             :   /*  
     446             :   void SDAlgorithmBase::restorePlane()
     447             :   {
     448             : 
     449             :     LogIO os( LogOrigin("SDAlgorithmBase","restorePlane",WHERE) );
     450             :     //     << ". Optionally, PB-correct too." << LogIO::POST;
     451             : 
     452             :     try
     453             :       {
     454             :         // Fit a Gaussian to the PSF.
     455             :         GaussianBeam beam = itsImages->getPSFGaussian();
     456             : 
     457             :         os << "Restore with beam : " << beam.getMajor(Unit("arcmin")) << " arcmin, " << beam.getMinor(Unit("arcmin"))<< " arcmin, " << beam.getPA(Unit("deg")) << " deg)" << LogIO::POST; 
     458             :         
     459             :         // Initialize restored image
     460             :         itsImage.set(0.0);
     461             :         // Copy model into it
     462             :         itsImage.copyData( LatticeExpr<Float>(itsModel )  );
     463             :         // Smooth model by beam
     464             :         StokesImageUtil::Convolve( itsImage, beam);
     465             :         // Add residual image
     466             :         itsImage.copyData( LatticeExpr<Float>( itsImage + itsResidual ) );
     467             :       }
     468             :     catch(AipsError &x)
     469             :       {
     470             :         throw( AipsError("Restoration Error " + x.getMesg() ) );
     471             :       }
     472             : 
     473             :   }
     474             :   */
     475             : 
     476             :   // Use this decide how to partition
     477             :   // the image for separate calls to 'deconvolve'.
     478             :   // Give codes to signal one or more of the following.
     479             :     ///    - channel planes separate
     480             :     ///    - stokes planes separate
     481             :     ///    - partitioned-image clean (facets ?)
     482             :   // Later, can add more complex partitioning schemes.... 
     483             :   // but there will be one place to do it, per deconvolver.
     484           0 :   void SDAlgorithmBase::queryDesiredShape(Int &nchanchunks, Int &npolchunks, IPosition imshape) // , nImageFacets.
     485             :   {  
     486           0 :     AlwaysAssert( imshape.nelements()==4, AipsError );
     487           0 :     nchanchunks=imshape(3);  // Each channel should appear separately.
     488           0 :     npolchunks=imshape(2); // Each pol should appear separately.
     489           0 :   }
     490             : 
     491             :   /*
     492             :   /// Make a list of Slices, to send sequentially to the deconvolver.
     493             :   /// Loop over this list of reference subimages in the 'deconvolve' call.
     494             :   /// This will support...
     495             :   ///    - channel cube clean
     496             :   ///    - stokes cube clean
     497             :   ///    - partitioned-image clean (facets ?)
     498             :   ///    - 3D deconvolver
     499             :   void SDAlgorithmBase::partitionImages( std::shared_ptr<SIImageStore> &imagestore )
     500             :   {
     501             :     LogIO os( LogOrigin("SDAlgorithmBase","partitionImages",WHERE) );
     502             : 
     503             :     IPosition imshape = imagestore->getShape();
     504             : 
     505             : 
     506             :     // TODO : Check which axes is which first !!!
     507             :     ///// chanAxis_p=CoordinateUtil::findSpectralAxis(dirty_p->coordinates());
     508             :     //// Vector<Stokes::StokesTypes> whichPols;
     509             :     //// polAxis_p=CoordinateUtil::findStokesAxis(whichPols, dirty_p->coordinates());
     510             :     uInt nx = imshape[0];
     511             :     uInt ny = imshape[1];
     512             :     uInt npol = imshape[2];
     513             :     uInt nchan = imshape[3];
     514             : 
     515             :     /// (1) /// Set up the Deconvolver Slicers.
     516             : 
     517             :     // Ask the deconvolver what shape it wants.
     518             :     Bool onechan=false, onepol=false;
     519             :     queryDesiredShape(onechan, onepol);
     520             : 
     521             :     uInt nSubImages = ( (onechan)?imshape[3]:1 ) * ( (onepol)?imshape[2]:1 ) ;
     522             :     uInt polstep = (onepol)?1:npol;
     523             :     uInt chanstep = (onechan)?1:nchan;
     524             : 
     525             :     itsDecSlices.resize( nSubImages );
     526             : 
     527             :     uInt subindex=0;
     528             :     for(uInt pol=0; pol<npol; pol+=polstep)
     529             :       {
     530             :         for(uInt chan=0; chan<nchan; chan+=chanstep)
     531             :           {
     532             :             AlwaysAssert( subindex < nSubImages , AipsError );
     533             :             IPosition substart(4,0,0,pol,chan);
     534             :             IPosition substop(4,nx-1,ny-1, pol+polstep-1, chan+chanstep-1);
     535             :             itsDecSlices[subindex] = Slicer(substart, substop, Slicer::endIsLast);
     536             :             subindex++;
     537             :           }
     538             :       }
     539             : 
     540             :    }// end of partitionImages
     541             :   */
     542             : 
     543             :   /*
     544             :   void SDAlgorithmBase::initializeSubImages( std::shared_ptr<SIImageStore> &imagestore, uInt subim)
     545             :   {
     546             :     itsResidual = SubImage<Float>( *(imagestore->residual()), itsDecSlices[subim], true );
     547             :     itsPsf = SubImage<Float>( *(imagestore->psf()), itsDecSlices[subim], true );
     548             :     itsModel = SubImage<Float>( *(imagestore->model()), itsDecSlices[subim], true );
     549             : 
     550             :     itsImages = imagestore;
     551             : 
     552             :   }
     553             :   */
     554             : 
     555             :   /////////// Helper Functions for all deconvolvers to use if they need it.
     556             : 
     557           0 :   Bool SDAlgorithmBase::findMaxAbs(const Array<Float>& lattice,
     558             :                                           Float& maxAbs,
     559             :                                           IPosition& posMaxAbs)
     560             :   {
     561             :     //    cout << "findmax : lat shape : " << lattice.shape() << " posmax : " << posMaxAbs << endl;
     562           0 :     posMaxAbs = IPosition(lattice.shape().nelements(), 0);
     563           0 :     maxAbs=0.0;
     564             :     Float minVal;
     565           0 :     IPosition posmin(lattice.shape().nelements(), 0);
     566           0 :     minMax(minVal, maxAbs, posmin, posMaxAbs, lattice);
     567             :     //cout << "min " << minVal << "  " << maxAbs << "   " << max(lattice) << endl;
     568           0 :     if(abs(minVal) > abs(maxAbs)){
     569           0 :       maxAbs=abs(minVal);
     570           0 :       posMaxAbs=posmin;
     571             :     }
     572           0 :     return true;
     573           0 :   }
     574             : 
     575           0 :   Bool SDAlgorithmBase::findMaxAbsMask(const Array<Float>& lattice,
     576             :                                        const Array<Float>& mask,
     577             :                                           Float& maxAbs,
     578             :                                           IPosition& posMaxAbs)
     579             :   {
     580             : 
     581             :     //cout << "maxabsmask shapes : " << lattice.shape() << " " << mask.shape() << endl;
     582             : 
     583           0 :     posMaxAbs = IPosition(lattice.shape().nelements(), 0);
     584           0 :     maxAbs=0.0;
     585             :     Float minVal;
     586           0 :     IPosition posmin(lattice.shape().nelements(), 0);
     587           0 :     minMaxMasked(minVal, maxAbs, posmin, posMaxAbs, lattice,mask);
     588             :     //cout << "min " << minVal << "  " << maxAbs << "   " << max(lattice) << endl;
     589           0 :     if(abs(minVal) > abs(maxAbs)){
     590           0 :       maxAbs=abs(minVal);
     591           0 :       posMaxAbs=posmin;
     592             :     }
     593           0 :     return true;
     594           0 :   }
     595             : 
     596             :   /*
     597             :   Bool SDAlgorithmBase::findMinMaxMask(const Array<Float>& lattice,
     598             :                                        const Array<Float>& mask,
     599             :                                        Float& minVal, Float& maxVal)
     600             :   //                                   IPosition& minPos, IPosition& maxPos)
     601             :   {
     602             :     //posMaxAbs = IPosition(lattice.shape().nelements(), 0);
     603             :     //maxAbs=0.0;
     604             :     IPosition posmin(lattice.shape().nelements(), 0);
     605             :     IPosition posmax(lattice.shape().nelements(), 0);
     606             :     minMaxMasked(minVal, maxVal, posmin, posmax, lattice,mask);
     607             : 
     608             :     return true;
     609             :   }
     610             :   */
     611             :   /*
     612             : 
     613             :   GaussianBeam SDAlgorithmBase::getPSFGaussian()
     614             :   {
     615             : 
     616             :     GaussianBeam beam;
     617             :     try
     618             :       {
     619             :         if( itsPsf.ndim() > 0 )
     620             :           {
     621             :             StokesImageUtil::FitGaussianPSF( itsPsf, beam );
     622             :           }
     623             :       }
     624             :     catch(AipsError &x)
     625             :       {
     626             :         LogIO os( LogOrigin("SDAlgorithmBase","getPSFGaussian",WHERE) );
     627             :         os << "Error in fitting a Gaussian to the PSF : " << x.getMesg() << LogIO::POST;
     628             :         throw( AipsError("Error in fitting a Gaussian to the PSF" + x.getMesg()) );
     629             :       }
     630             : 
     631             :     return beam;
     632             :   }
     633             : 
     634             : */  
     635             : } //# NAMESPACE CASA - END
     636             : 

Generated by: LCOV version 1.16