LCOV - code coverage report
Current view: top level - synthesis/ImagerObjects - SIImageStoreMultiTerm.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 454 624 72.8 %
Date: 2023-11-06 10:06:49 Functions: 36 46 78.3 %

          Line data    Source code
       1             : //# SIImageStoreMultiTerm.cc: Implementation of Imager.h
       2             : //# Copyright (C) 1997-2008
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This program is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU General Public License as published by the Free
       7             : //# Software Foundation; either version 2 of the License, or (at your option)
       8             : //# any later version.
       9             : //#
      10             : //# This program is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
      13             : //# more details.
      14             : //#
      15             : //# You should have received a copy of the GNU General Public License along
      16             : //# with this program; if not, write to the Free Software Foundation, Inc.,
      17             : //# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: aips2-request@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id$
      27             : 
      28             : #include <casacore/casa/Exceptions/Error.h>
      29             : #include <iostream>
      30             : #include <sstream>
      31             : 
      32             : #include <casacore/casa/Arrays/Matrix.h>
      33             : #include <casacore/casa/Arrays/ArrayMath.h>
      34             : #include <casacore/casa/Arrays/ArrayLogical.h>
      35             : 
      36             : #include <casacore/casa/Logging.h>
      37             : #include <casacore/casa/Logging/LogIO.h>
      38             : #include <casacore/casa/Logging/LogMessage.h>
      39             : #include <casacore/casa/Logging/LogSink.h>
      40             : #include <casacore/casa/Logging/LogMessage.h>
      41             : 
      42             : #include <casacore/casa/OS/DirectoryIterator.h>
      43             : #include <casacore/casa/OS/File.h>
      44             : #include <casacore/casa/OS/Path.h>
      45             : 
      46             : #include <casacore/casa/OS/HostInfo.h>
      47             : #include <casacore/images/Images/TempImage.h>
      48             : #include <casacore/images/Images/PagedImage.h>
      49             : #include <casacore/ms/MeasurementSets/MSHistoryHandler.h>
      50             : #include <casacore/ms/MeasurementSets/MeasurementSet.h>
      51             : #include <synthesis/TransformMachines/StokesImageUtil.h>
      52             : #include <casacore/images/Images/TempImage.h>
      53             : #include <casacore/images/Images/SubImage.h>
      54             : #include <casacore/images/Regions/ImageRegion.h>
      55             : 
      56             : #include <synthesis/ImagerObjects/SIImageStoreMultiTerm.h>
      57             : 
      58             : #include <casacore/casa/Arrays/MatrixMath.h>
      59             : #include <casacore/scimath/Mathematics/MatrixMathLA.h>
      60             : 
      61             : #include <sys/types.h>
      62             : #include <unistd.h>
      63             : using namespace std;
      64             : 
      65             : using namespace casacore;
      66             : namespace casa { //# NAMESPACE CASA - BEGIN
      67             : 
      68             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
      69             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
      70             :   
      71           0 :   SIImageStoreMultiTerm::SIImageStoreMultiTerm():SIImageStore()
      72             :   {
      73           0 :     itsNTerms=0;
      74             : 
      75           0 :     itsPsfs.resize(0);
      76           0 :     itsModels.resize(0);
      77           0 :     itsResiduals.resize(0);
      78           0 :     itsWeights.resize(0);
      79           0 :     itsImages.resize(0);
      80           0 :     itsSumWts.resize(0);
      81           0 :     itsImagePBcors.resize(0);
      82           0 :     itsPBs.resize(0);
      83             :     
      84           0 :     itsForwardGrids.resize(0);
      85           0 :     itsBackwardGrids.resize(0);
      86             : 
      87           0 :     itsUseWeight=false;
      88             : 
      89           0 :     init();
      90             : 
      91           0 :     validate();
      92             : 
      93           0 :   }
      94             : 
      95             :   // Used from SynthesisNormalizer::makeImageStore()
      96         116 :   SIImageStoreMultiTerm::SIImageStoreMultiTerm(const String &imagename,
      97             :                                                const CoordinateSystem &imcoordsys,
      98             :                                                const IPosition &imshape,
      99             :                                                const String &objectname,
     100             :                                                const Record &miscinfo,
     101             :                                                const Int /*nfacets*/,
     102             :                                                const Bool /*overwrite*/,
     103             :                                                uInt ntaylorterms,
     104         116 :                                                Bool useweightimage)
     105             :   {
     106         348 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","Open new Images",WHERE) );
     107             : 
     108         116 :     itsNTerms = ntaylorterms;
     109             : 
     110         116 :     itsPsfs.resize(2 * itsNTerms - 1);
     111         116 :     itsModels.resize(itsNTerms);
     112         116 :     itsResiduals.resize(itsNTerms);
     113         116 :     itsWeights.resize(2 * itsNTerms - 1);
     114         116 :     itsImages.resize(itsNTerms);
     115         116 :     itsSumWts.resize(2 * itsNTerms - 1);
     116         116 :     itsPBs.resize(itsNTerms);
     117         116 :     itsImagePBcors.resize(itsNTerms);
     118             : 
     119         116 :     itsMask.reset( );
     120         116 :     itsGridWt.reset( );
     121             : 
     122         116 :     itsForwardGrids.resize(itsNTerms);
     123         116 :     itsBackwardGrids.resize(2 * itsNTerms - 1);
     124             : 
     125             :     //    itsNFacets = nfacets;  // So that sumwt shape happens properly, via checkValidity
     126             :     //    itsFacetId = -1;
     127         116 :     itsNFacets=1;
     128         116 :     itsFacetId=0;
     129         116 :     itsNChanChunks = 1;
     130         116 :     itsChanId = 0;
     131         116 :     itsNPolChunks = 1;
     132         116 :     itsPolId = 0;
     133             : 
     134         116 :     itsImageName = imagename;
     135         116 :     itsCoordSys = imcoordsys;
     136         116 :     itsImageShape = imshape;
     137         116 :     itsObjectName = objectname;
     138         116 :     itsMiscInfo = miscinfo;
     139             : 
     140         116 :     itsUseWeight = useweightimage;
     141             : 
     142         116 :     init();
     143             : 
     144         116 :     validate();
     145             : 
     146         116 :   }
     147             : 
     148             :   // Used from SynthesisNormalizer::makeImageStore()
     149         603 :   SIImageStoreMultiTerm::SIImageStoreMultiTerm(const String &imagename, uInt ntaylorterms,
     150         603 :                                                const Bool ignorefacets, const Bool ignoresumwt)
     151             :   {
     152        1809 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","Open existing Images",WHERE) );
     153             : 
     154         603 :     itsNTerms = ntaylorterms;
     155             : 
     156       16105 :     auto fltPtrReset = [](Block<shared_ptr<ImageInterface<Float> > >&a) {for(uInt i=0; i < a.nelements(); ++i) a[i].reset();  };
     157         603 :     itsPsfs.resize(2 * itsNTerms - 1); fltPtrReset(itsPsfs);
     158         603 :     itsModels.resize(itsNTerms); fltPtrReset(itsModels);
     159         603 :     itsResiduals.resize(itsNTerms); fltPtrReset(itsResiduals);
     160         603 :     itsWeights.resize(2 * itsNTerms - 1); fltPtrReset(itsWeights);
     161         603 :     itsImages.resize(itsNTerms); fltPtrReset(itsImages);
     162         603 :     itsPBs.resize(itsNTerms); fltPtrReset(itsPBs);
     163         603 :     itsSumWts.resize(2 * itsNTerms - 1); fltPtrReset(itsSumWts);
     164         603 :     itsMask.reset( );
     165         603 :     itsGridWt.reset( );
     166         603 :     itsImagePBcors.resize(itsNTerms); fltPtrReset(itsImagePBcors);
     167             :     
     168             :     
     169             :     
     170         603 :     itsMiscInfo=Record();
     171        4173 :     auto cmplxPtrReset = [](Block<shared_ptr<ImageInterface<Complex> > >&a) {for(uInt i=0; i < a.nelements(); ++i) a[i].reset();  };
     172         603 :     itsForwardGrids.resize(itsNTerms); cmplxPtrReset(itsForwardGrids);
     173         603 :     itsBackwardGrids.resize(2 * itsNTerms - 1); cmplxPtrReset(itsBackwardGrids);
     174             : 
     175         603 :     itsImageName = imagename;
     176             : 
     177         603 :     itsNFacets=1;
     178         603 :     itsFacetId=0;
     179         603 :     itsNChanChunks = 1;
     180         603 :     itsChanId = 0;
     181         603 :     itsNPolChunks = 1;
     182         603 :     itsPolId = 0;
     183             : 
     184         603 :     Bool exists=true;
     185         603 :     Bool sumwtexists=true;
     186         603 :     Bool modelexists=true;
     187        2380 :     for(uInt tix=0;tix<2*itsNTerms-1;tix++) 
     188             :       {
     189        1777 :         if( tix<itsNTerms ) {
     190        2862 :             exists &= ( doesImageExist( itsImageName+String(".residual.tt")+String::toString(tix) ) ||
     191        1672 :                         doesImageExist( itsImageName+String(".psf.tt")+String::toString(tix) )  );
     192        2966 :             modelexists &= ( doesImageExist( itsImageName+String(".model.tt")+String::toString(tix) ) ||
     193        1776 :                         doesImageExist( itsImageName+String(".model.tt")+String::toString(tix) )  );
     194        1190 :             sumwtexists &= ( doesImageExist( itsImageName+String(".sumwt.tt")+String::toString(tix) ) );
     195             :           }else {
     196         587 :             exists &= ( doesImageExist( itsImageName+String(".psf.tt")+String::toString(tix) ) );
     197         587 :             sumwtexists &= ( doesImageExist( itsImageName+String(".sumwt.tt")+String::toString(tix) ) );
     198             :           }
     199             :       }
     200             : 
     201             :     // The PSF or Residual images must exist. ( or the gridwt image)
     202             :     //  All this is just for the shape and coordinate system.
     203         603 :     if( exists || modelexists || doesImageExist(itsImageName+String(".gridwt")) )
     204             :       {
     205           0 :         std::shared_ptr<ImageInterface<Float> > imptr;
     206         603 :         if( doesImageExist(itsImageName+String(".psf.tt0")) )
     207             :           {
     208         603 :             buildImage( imptr, (itsImageName+String(".psf.tt0")) );
     209             : 
     210             :             //cout << "Opening PSF image to read csys" << endl;
     211             :             //      imptr.reset( new PagedImage<Float> (itsImageName+String(".psf.tt0")) );
     212             :           }
     213           0 :         else if( doesImageExist(itsImageName+String(".residual.tt0")) )
     214             :           {
     215           0 :             buildImage( imptr, (itsImageName+String(".residual.tt0")) );
     216             :             //cout << "Opening Residual image to read csys" << endl;
     217             :             //    imptr.reset( new PagedImage<Float> (itsImageName+String(".residual.tt0")) );
     218             :           }
     219           0 :         else if( doesImageExist(itsImageName+String(".model.tt0")) )
     220             :           {
     221           0 :             buildImage( imptr, (itsImageName+String(".model.tt0")) );
     222             :             //cout << "Opening Model image to read csys" << endl;
     223             :             //      imptr.reset( new PagedImage<Float> (itsImageName+String(".model.tt0")) );
     224             :           }
     225             :         else
     226             :           {
     227             :             // How can this be right ?
     228             :             //cout << "Opening Sumwt image to read csys" << endl;
     229           0 :             buildImage( imptr, (itsImageName+String(".gridwt")) );
     230             :             //    imptr.reset( new PagedImage<Float> (itsImageName+String(".gridwt")) );
     231             :           }
     232             :           
     233         603 :         itsObjectName=imptr->imageInfo().objectName();
     234         603 :         itsImageShape = imptr->shape();
     235         603 :         itsCoordSys = imptr->coordinates();
     236         603 :         itsMiscInfo=imptr->miscInfo();
     237             : 
     238             :       }
     239             :     else
     240             :       {
     241           0 :         throw( AipsError( "Multi-term PSF,  Residual or Model Images do not exist. Please create one of them." ) );
     242             :       }
     243             : 
     244        1451 :     if( doesImageExist(itsImageName+String(".residual.tt0")) || 
     245         848 :         doesImageExist(itsImageName+String(".psf.tt0")) )
     246             :       {
     247         603 :     if( sumwtexists )
     248             :       {
     249         574 :         std::shared_ptr<ImageInterface<Float> > imptr;
     250             :         //      imptr.reset( new PagedImage<Float> (itsImageName+String(".sumwt.tt0")) );
     251         574 :         buildImage( imptr, (itsImageName+String(".sumwt.tt0")) );
     252         574 :         itsNFacets = imptr->shape()[0];
     253         574 :         itsFacetId = 0;
     254         574 :         itsUseWeight = getUseWeightImage( *imptr );
     255             :         /////redo this here as psf may have different coordinates
     256         574 :         itsCoordSys = imptr->coordinates();
     257         574 :         itsMiscInfo=imptr->miscInfo();
     258         574 :         if( itsUseWeight && ! doesImageExist(itsImageName+String(".weight.tt0")) )
     259             :           {
     260           0 :             throw(AipsError("Internal error : MultiTerm Sumwt has a useweightimage=true but the weight image does not exist."));
     261             :           }
     262             :       }
     263             :     else
     264             :       {
     265          29 :         if(!ignoresumwt)
     266           0 :           {throw( AipsError( "Multi-term SumWt does not exist. Please create PSFs or Residuals." ) );}
     267             :         else
     268             :           {
     269          29 :             os << "SumWt.ttx do not exist. Proceeding only with PSFs" << LogIO::POST;
     270           0 :             std::shared_ptr<ImageInterface<Float> > imptr;
     271             :             //  imptr.reset( new PagedImage<Float> (itsImageName+String(".sumwt.tt0")) );
     272          29 :             if( doesImageExist(itsImageName+String(".residual.tt0")) )
     273          29 :               {buildImage( imptr, (itsImageName+String(".residual.tt0")) );}
     274             :             else
     275           0 :               {buildImage( imptr, (itsImageName+String(".psf.tt0")) );}
     276             :             
     277          29 :             itsNFacets = 1;
     278          29 :             itsFacetId = 0;
     279          29 :             itsUseWeight = False;
     280          29 :             itsCoordSys = imptr->coordinates();
     281          29 :             itsMiscInfo=imptr->miscInfo();
     282             :           }
     283             :       }
     284             :       }// if psf0 or res0 exist
     285             :     
     286         603 :     if( ignorefacets==true ) itsNFacets=1;
     287             : 
     288         603 :     init();
     289         603 :     validate();
     290             : 
     291         603 :   }
     292             : 
     293             :   /*
     294             :   /////////////Constructor with pointers already created else where but taken over here
     295             :   SIImageStoreMultiTerm::SIImageStoreMultiTerm(Block<std::shared_ptr<ImageInterface<Float> > > modelims, 
     296             :                                                Block<std::shared_ptr<ImageInterface<Float> > >residims,
     297             :                                                Block<std::shared_ptr<ImageInterface<Float> > >psfims, 
     298             :                                                Block<std::shared_ptr<ImageInterface<Float> > >weightims, 
     299             :                                                Block<std::shared_ptr<ImageInterface<Float> > >restoredims,
     300             :                                                Block<std::shared_ptr<ImageInterface<Float> > >sumwtims, 
     301             :                                                std::shared_ptr<ImageInterface<Float> > newmask,
     302             :                                                std::shared_ptr<ImageInterface<Float> > newalpha,
     303             :                                                std::shared_ptr<ImageInterface<Float> > newbeta)
     304             :   {
     305             :     
     306             :     itsPsfs=psfims;
     307             :     itsModels=modelims;
     308             :     itsResiduals=residims;
     309             :     itsWeights=weightims;
     310             :     itsImages=restoredims;
     311             :     itsSumWts=sumwtims;
     312             :     itsMask = newmask;
     313             :     itsAlpha = newalpha;
     314             :     itsBeta = newbeta;
     315             : 
     316             :     itsNTerms = itsResiduals.nelements();
     317             :     itsMiscInfo=Record();
     318             : 
     319             :     AlwaysAssert( itsPsfs.nelements() == 2*itsNTerms-1 , AipsError ); 
     320             :     AlwaysAssert( itsPsfs.nelements()>0 && itsPsfs[0] , AipsError );
     321             :     AlwaysAssert( itsSumWts.nelements()>0 && itsSumWts[0] , AipsError );
     322             : 
     323             :     itsForwardGrids.resize( itsNTerms );
     324             :     itsBackwardGrids.resize( 2 * itsNTerms - 1 );
     325             : 
     326             :     itsImageShape=psfims[0]->shape();
     327             :     itsCoordSys = psfims[0]->coordinates();
     328             :     itsMiscInfo = psfims[0]->miscInfo();
     329             : 
     330             :     itsNFacets=sumwtims[0]->shape()[0];
     331             :     itsUseWeight=getUseWeightImage( *(sumwtims[0]) );
     332             : 
     333             :     itsImageName = String("reference");  // This is what the access functions use to guard against allocs...
     334             : 
     335             :     init();
     336             :     validate();
     337             :         
     338             :   }
     339             :   */
     340             : 
     341             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     342             :   /////////////Constructor with pointers already created else where but taken over here
     343             :   // used from getSubImageStore(), for example when creating the facets list
     344             :   // this would be safer if it was refactored as a copy constructor of the generic stuff +
     345             :   // initialization of the facet related parameters
     346         286 :   SIImageStoreMultiTerm::SIImageStoreMultiTerm(const Block<std::shared_ptr<ImageInterface<Float> > > &modelims,
     347             :                                                const Block<std::shared_ptr<ImageInterface<Float> > > &residims,
     348             :                                                const Block<std::shared_ptr<ImageInterface<Float> > > &psfims,
     349             :                                                const Block<std::shared_ptr<ImageInterface<Float> > > &weightims,
     350             :                                                const Block<std::shared_ptr<ImageInterface<Float> > > &restoredims,
     351             :                                                const Block<std::shared_ptr<ImageInterface<Float> > > &sumwtims,
     352             :                                                const Block<std::shared_ptr<ImageInterface<Float> > > &pbims,
     353             :                                                const Block<std::shared_ptr<ImageInterface<Float> > > &restoredpbcorims,
     354             :                                                const std::shared_ptr<ImageInterface<Float> > &newmask,
     355             :                                                const std::shared_ptr<ImageInterface<Float> > &newalpha,
     356             :                                                const std::shared_ptr<ImageInterface<Float> > &newbeta,
     357             :                                                const std::shared_ptr<ImageInterface<Float> > &newalphaerror,
     358             :                                                const std::shared_ptr<ImageInterface<Float> > &newalphapbcor,
     359             :                                                const std::shared_ptr<ImageInterface<Float> > &newbetapbcor,
     360             :                                                const CoordinateSystem& csys,
     361             :                                                const IPosition &imshape,
     362             :                                                const String &imagename,
     363             :                                                const String &objectname,
     364             :                                                const Record &miscinfo,
     365             :                                                const Int facet, const Int nfacets,
     366             :                                                const Int chan, const Int nchanchunks,
     367         286 :                                                const Int pol, const Int npolchunks)
     368             :   {
     369         286 :     itsPsfs=psfims;
     370         286 :     itsModels=modelims;
     371         286 :     itsResiduals=residims;
     372         286 :     itsWeights=weightims;
     373         286 :     itsImages=restoredims;
     374         286 :     itsSumWts=sumwtims;
     375         286 :     itsMask = newmask;
     376         286 :     itsAlpha = newalpha;
     377         286 :     itsBeta = newbeta;
     378         286 :     itsAlphaError = newalphaerror;
     379         286 :     itsAlphaPBcor = newalphapbcor;
     380         286 :     itsBetaPBcor = newbetapbcor;
     381             : 
     382         286 :     itsPBs=pbims;
     383         286 :     itsImagePBcors=restoredpbcorims;
     384             : 
     385         286 :     itsNTerms = itsResiduals.nelements();
     386         286 :     itsMiscInfo=Record();
     387             : 
     388         286 :     AlwaysAssert( itsPsfs.nelements() == 2*itsNTerms-1 , AipsError ); 
     389             :     //    AlwaysAssert( itsPsfs.nelements()>0 && itsPsfs[0] , AipsError );
     390             :     //    AlwaysAssert( itsSumWts.nelements()>0 && itsSumWts[0] , AipsError );
     391             : 
     392         286 :     itsForwardGrids.resize( itsNTerms );
     393         286 :     itsBackwardGrids.resize( 2 * itsNTerms - 1 );
     394             : 
     395         286 :     itsObjectName = objectname;
     396         286 :     itsMiscInfo = miscinfo;
     397             : 
     398         286 :     itsNFacets = nfacets;
     399         286 :     itsFacetId = facet;
     400         286 :     itsNChanChunks = nchanchunks;
     401         286 :     itsChanId = chan;
     402         286 :     itsNPolChunks = npolchunks;
     403         286 :     itsPolId = pol;
     404             : 
     405         286 :     itsParentImageShape = imshape; 
     406         286 :     itsImageShape = imshape;
     407             :     /////    itsImageShape = IPosition(4,0,0,0,0);
     408             : 
     409         286 :     itsCoordSys = csys; // Hopefully this doesn't change for a reference image
     410         286 :     itsImageName = imagename;
     411             : 
     412             :         
     413             :     //-----------------------
     414         286 :     init(); // Connect parent pointers to the images.
     415             :     //-----------------------
     416             : 
     417             :     // Set these to null, to be set later upon first access.
     418             :     // Setting to null will hopefully set all elements of each array, to NULL.
     419         286 :     itsPsfs=std::shared_ptr<ImageInterface<Float> >();  
     420         286 :     itsModels=std::shared_ptr<ImageInterface<Float> >();
     421         286 :     itsResiduals=std::shared_ptr<ImageInterface<Float> >();
     422         286 :     itsWeights=std::shared_ptr<ImageInterface<Float> >();
     423         286 :     itsImages=std::shared_ptr<ImageInterface<Float> >();
     424         286 :     itsSumWts=std::shared_ptr<ImageInterface<Float> >();
     425         286 :     itsPBs=std::shared_ptr<ImageInterface<Float> >();
     426             : 
     427         286 :     itsMask.reset( );
     428             : 
     429         286 :     validate();
     430             : 
     431         286 :   }
     432             : 
     433             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     434             : 
     435             :   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     436             :   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     437             :   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     438             : 
     439         203 :   uInt SIImageStoreMultiTerm::getNTaylorTerms(Bool dopsf)
     440             :   {
     441         203 :     return dopsf ? (2*itsNTerms-1) : itsNTerms;
     442             :    }
     443             : 
     444             :   // Check if images that are asked-for are ready and all have the same shape.
     445             :   /*
     446             :   Bool SIImageStoreMultiTerm::checkValidity(const Bool ipsf, const Bool iresidual, 
     447             :                                             const Bool iweight, const Bool imodel, const Bool irestored, 
     448             :                                             const Bool imask,const Bool isumwt,
     449             :                                             const Bool ialpha, const Bool ibeta)
     450             :   {
     451             : 
     452             :     //    cout << "In MT::checkValidity imask is " << imask << endl;
     453             : 
     454             :     Bool valid = true;
     455             : 
     456             :     for(uInt tix=0; tix<2*itsNTerms-1; tix++)
     457             :       {
     458             :         
     459             :         if(ipsf==true)
     460             :           { psf(tix); 
     461             :             valid = valid & ( itsPsfs[tix] && itsPsfs[tix]->shape()==itsImageShape ); }
     462             :         if(iweight==true)
     463             :           { weight(tix);  
     464             :             valid = valid & ( itsWeights[tix] && itsWeights[tix]->shape()==itsImageShape ); }
     465             : 
     466             :         if(isumwt==true) {
     467             :             IPosition useShape(itsImageShape);
     468             :             useShape[0]=itsNFacets; useShape[1]=itsNFacets;
     469             :             sumwt(tix);  
     470             :             valid = valid & ( itsSumWts[tix] && itsSumWts[tix]->shape()==useShape ); 
     471             :           }
     472             :         
     473             :         if( tix< itsNTerms )
     474             :           {
     475             :             if(iresidual==true)
     476             :               { residual(tix);  
     477             :                 valid = valid & ( itsResiduals[tix] && itsResiduals[tix]->shape()==itsImageShape ); }
     478             :             if(imodel==true)
     479             :               { model(tix);
     480             :                 valid = valid & ( itsModels[tix] && itsModels[tix]->shape()==itsImageShape); }
     481             :             if(irestored==true)
     482             :               { image(tix);
     483             :                 valid = valid & ( itsImages[tix] && itsImages[tix]->shape()==itsImageShape); }
     484             :           }
     485             :       }
     486             :     
     487             :     if(imask==true)
     488             :       { mask(); valid = valid & ( itsMask && itsMask->shape()==itsImageShape); 
     489             :         //      cout << " Mask null ? " << (bool) itsMask << endl;
     490             :       }
     491             :     if(ialpha==true)
     492             :       { alpha();  valid = valid & ( itsAlpha && itsAlpha->shape()==itsImageShape ); }
     493             :     if(ibeta==true)
     494             :       { beta();  valid = valid & ( itsBeta && itsBeta->shape()==itsImageShape ); }
     495             : 
     496             :     return valid;
     497             :     
     498             :   }
     499             :   */
     500             : 
     501             :   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     502             :   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     503             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     504             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     505             : 
     506        1608 :   SIImageStoreMultiTerm::~SIImageStoreMultiTerm() 
     507             :   {
     508        1608 :   }
     509             : 
     510             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     511             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     512             : 
     513        2110 :   Bool SIImageStoreMultiTerm::releaseLocks() 
     514             :   {
     515        4220 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","releaseLocks",WHERE) );
     516             : 
     517        8326 :     for(uInt tix=0; tix<2*itsNTerms-1; tix++)
     518             :       {
     519        6216 :         if( itsPsfs[tix] ) releaseImage( itsPsfs[tix] );
     520        6216 :         if( itsWeights[tix] ) releaseImage( itsWeights[tix] );
     521        6216 :         if( itsSumWts[tix] ) releaseImage( itsSumWts[tix] );
     522        6216 :         if( tix < itsNTerms )
     523             :           {
     524        4163 :             if( itsModels[tix] ) releaseImage( itsModels[tix] );
     525        4163 :             if( itsResiduals[tix] ) releaseImage( itsResiduals[tix] );
     526        4163 :             if( itsImages[tix] ) releaseImage( itsImages[tix] );
     527        4163 :             if( itsPBs[tix] ) releaseImage( itsPBs[tix] );
     528        4163 :             if( itsImagePBcors[tix] ) releaseImage( itsImagePBcors[tix] );
     529             :           }
     530             :       }
     531        2110 :     if( itsMask ) releaseImage( itsMask );
     532        2110 :     if( itsAlpha ) releaseImage( itsAlpha );
     533        2110 :     if( itsBeta ) releaseImage( itsBeta );
     534        2110 :     if( itsAlphaError ) releaseImage( itsAlphaError );
     535        2110 :     if( itsAlphaPBcor ) releaseImage( itsAlphaPBcor );
     536        2110 :     if( itsBetaPBcor ) releaseImage( itsBetaPBcor );
     537        2110 :     if( itsGridWt ) releaseImage( itsGridWt );
     538             :     
     539        4220 :     return true; // do something more intelligent here.
     540             :   }
     541             : 
     542           0 :   Bool SIImageStoreMultiTerm::releaseComplexGrids() 
     543             :   {
     544           0 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","releaseComplexGrids",WHERE) );
     545             : 
     546           0 :     for(uInt tix=0; tix<2*itsNTerms-1; tix++)
     547             :       {
     548           0 :         if( itsBackwardGrids[tix] ) releaseImage( itsBackwardGrids[tix] );
     549           0 :         if( tix < itsNTerms )
     550             :           {
     551           0 :             if( itsForwardGrids[tix] ) releaseImage( itsForwardGrids[tix] );
     552             :           }
     553             :       }
     554           0 :     return True; // do something more intelligent here.
     555             :   }
     556             : 
     557             : 
     558         594 :   Double SIImageStoreMultiTerm::getReferenceFrequency()
     559             :   {
     560             :     Double theRefFreq;
     561             : 
     562         594 :     Vector<Double> refpix = (itsCoordSys.spectralCoordinate()).referencePixel();
     563         594 :     AlwaysAssert( refpix.nelements()>0, AipsError );
     564         594 :     (itsCoordSys.spectralCoordinate()).toWorld( theRefFreq, refpix[0] );
     565             :     //    cout << "Reading ref freq as : " << theRefFreq << endl;
     566        1188 :     return theRefFreq;
     567             :   }
     568             : 
     569             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     570             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     571           0 :   Vector<String> SIImageStoreMultiTerm::getModelImageName()
     572             :   {
     573           0 :     Vector<String> mods(itsNTerms);
     574           0 :     for(uInt tix=0;tix<itsNTerms;tix++)
     575           0 :       {mods[tix]=itsImageName + imageExts(MODEL)+".tt"+String::toString(tix);}
     576           0 :     return mods;
     577             :   }
     578             : 
     579          12 :   void SIImageStoreMultiTerm::setModelImage( const Vector<String> &modelnames )
     580             :   {
     581          36 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","setModelImage",WHERE) );
     582             : 
     583          12 :     if( modelnames.nelements() > itsNTerms ) 
     584           0 :       { throw(AipsError("We currently cannot support more than nterms images as the starting model. "));
     585             :       }
     586             : 
     587          12 :     if( modelnames.nelements() > 0 && modelnames.nelements() <= itsNTerms )
     588             :       {
     589          30 :         for(uInt tix=0;tix<modelnames.nelements();tix++)
     590             :           {
     591          19 :             setModelImageOne( modelnames[tix], tix );
     592             :           }
     593             :       }
     594             : 
     595          11 :   }
     596             : 
     597             :   /*
     598             :   void SIImageStoreMultiTerm::setModelImage( String modelname )
     599             :   {
     600             :     LogIO os( LogOrigin("SIImageStoreMultiTerm","setModelImage",WHERE) );
     601             : 
     602             :     for(uInt tix=0;tix<itsNTerms;tix++)
     603             :       {
     604             :         
     605             :         Directory immodel( modelname+String(".model.tt")+String::toString(tix) );
     606             :         if( !immodel.exists() ) 
     607             :           {
     608             :             os << "Starting model image does not exist for term : " << tix << LogIO::POST;
     609             :           }
     610             :         else
     611             :           {
     612             :             std::shared_ptr<PagedImage<Float> > newmodel( new PagedImage<Float>( modelname+String(".model.tt")+String::toString(tix) ) );
     613             :             // Check shapes, coordsys with those of other images.  If different, try to re-grid here.
     614             :             
     615             :             if( newmodel->shape() != model(tix)->shape() )
     616             :               {
     617             :                 os << "Regridding input model to target coordinate system for term " << tix << LogIO::POST;
     618             :                 regridToModelImage( *newmodel , tix);
     619             :                 // For now, throw an exception.
     620             :                 //throw( AipsError( "Input model image "+modelname+".model.tt"+String::toString(tix)+" is not the same shape as that defined for output in "+ itsImageName + ".model" ) );
     621             :               }
     622             :             else
     623             :               {
     624             :                 os << "Setting " << modelname << " as model for term " << tix << LogIO::POST;
     625             :                 // Then, add its contents to itsModel.
     626             :                 //itsModel->put( itsModel->get() + model->get() );
     627             :                 /////( model(tix) )->put( newmodel->get() );
     628             :                 model(tix)->copyData( LatticeExpr<Float> (*newmodel) );
     629             :               }
     630             :           }
     631             :       }//nterms
     632             :   }
     633             :   */ 
     634             : 
     635             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     636             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
     637             : 
     638        3404 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::psf(uInt term)
     639             :   {
     640        3404 :     AlwaysAssert( itsPsfs.nelements() > term, AipsError );
     641        3408 :     accessImage( itsPsfs[term], itsParentPsfs[term], imageExts(PSF)+".tt"+String::toString(term) );
     642        3402 :     return itsPsfs[term];
     643             :   }
     644        7533 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::residual(uInt term)
     645             :   {
     646        7537 :     accessImage( itsResiduals[term], itsParentResiduals[term], imageExts(RESIDUAL)+".tt"+String::toString(term) );
     647             :     //    Record mi = itsResiduals[term]->miscInfo(); ostringstream oss;mi.print(oss);cout<<"MiscInfo(res) " << term << " : " << oss.str() << endl;
     648             : 
     649        7531 :     return itsResiduals[term];
     650             :   }
     651        1167 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::weight(uInt term)
     652             :   {
     653        1167 :     accessImage( itsWeights[term], itsParentWeights[term], imageExts(WEIGHT)+".tt"+String::toString(term) );
     654        1167 :     return itsWeights[term];
     655             :   }
     656        5616 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::sumwt(uInt term)
     657             :   {
     658        5616 :     accessImage( itsSumWts[term], itsParentSumWts[term], imageExts(SUMWT)+".tt"+String::toString(term) );
     659             : 
     660             :     
     661        5616 :     if( itsNFacets>1 || itsNChanChunks>1 || itsNPolChunks>1 ) 
     662         276 :       {itsUseWeight = getUseWeightImage( *itsParentSumWts[0] );}
     663        5616 :       setUseWeightImage( *(itsSumWts[term]) , itsUseWeight); // Sets a flag in the SumWt image. 
     664             : 
     665        5616 :     return itsSumWts[term];
     666             :   }
     667        3671 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::model(uInt term)
     668             :   {
     669             : 
     670        3677 :     accessImage( itsModels[term], itsParentModels[term], imageExts(MODEL)+".tt"+String::toString(term) );
     671             : 
     672        3669 :     itsModels[term]->setUnits("Jy/pixel");
     673        3669 :     return itsModels[term];
     674             :   }
     675             : 
     676        3488 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::image(uInt term)
     677             :   {
     678             : 
     679        3488 :     accessImage( itsImages[term], itsParentImages[term], imageExts(IMAGE)+".tt"+String::toString(term) );
     680        3488 :     itsImages[term]->setUnits("Jy/beam");
     681        3488 :     return itsImages[term];
     682             :   }
     683             : 
     684        1325 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::pb(uInt term)
     685             :   {
     686             : 
     687        1329 :     accessImage( itsPBs[term], itsParentPBs[term], imageExts(PB)+".tt"+String::toString(term) );
     688        1323 :     return itsPBs[term];
     689             :   }
     690             : 
     691           0 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::imagepbcor(uInt term)
     692             :   {
     693             : 
     694           0 :     accessImage( itsImagePBcors[term], itsParentImagePBcors[term], imageExts(IMAGE)+".tt"+String::toString(term)+ ".pbcor" );
     695           0 :     itsImagePBcors[term]->setUnits("Jy/beam");
     696           0 :     return itsImagePBcors[term];
     697             :   }
     698             : 
     699         616 :     std::shared_ptr<ImageInterface<Complex> > SIImageStoreMultiTerm::forwardGrid(uInt term){
     700         616 :     if( itsForwardGrids[term] )// && (itsForwardGrids[term]->shape() == itsImageShape))
     701         506 :       return itsForwardGrids[term];
     702         220 :     Vector<Int> whichStokes(0);
     703         220 :     IPosition cimageShape;
     704         110 :     cimageShape=itsImageShape;
     705         110 :     CoordinateSystem cimageCoord = StokesImageUtil::CStokesCoord( itsCoordSys,
     706         220 :                                                                   whichStokes, itsDataPolRep);
     707         110 :     cimageCoord.setObsInfo(itsCoordSys.obsInfo());
     708         110 :     cimageShape(2)=whichStokes.nelements();
     709         110 :     itsForwardGrids[term].reset(new TempImage<Complex>(TiledShape(cimageShape, tileShape()), cimageCoord, memoryBeforeLattice()));
     710         110 :     return itsForwardGrids[term];
     711             :   }
     712        1346 :   std::shared_ptr<ImageInterface<Complex> > SIImageStoreMultiTerm::backwardGrid(uInt term){
     713             : 
     714        1346 :           if( itsBackwardGrids[term] && (itsBackwardGrids[term]->shape() == itsImageShape))
     715        1001 :                   return itsBackwardGrids[term];
     716             :           //      cout << "MT : Making backward grid of shape : " << itsImageShape << endl;
     717         690 :     Vector<Int> whichStokes(0);
     718         690 :     IPosition cimageShape;
     719         345 :     cimageShape=itsImageShape;
     720         345 :     CoordinateSystem cimageCoord = StokesImageUtil::CStokesCoord( itsCoordSys,
     721         690 :                                                                   whichStokes, itsDataPolRep);
     722         345 :     cimageCoord.setObsInfo(itsCoordSys.obsInfo());
     723         345 :     cimageShape(2)=whichStokes.nelements();
     724         345 :     itsBackwardGrids[term].reset(new TempImage<Complex>(TiledShape(cimageShape, tileShape()), cimageCoord, memoryBeforeLattice()));
     725         345 :     return itsBackwardGrids[term];
     726             :     }
     727             : 
     728         452 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::alpha()
     729             :   {
     730         452 :     if( itsAlpha && itsAlpha->shape() == itsImageShape ) { return itsAlpha; }
     731             :     //    checkRef( itsAlpha , "alpha" );
     732         113 :     itsAlpha = openImage( itsImageName+String(".alpha"), false );
     733             :     //    itsAlpha->setUnits("Alpha");
     734         113 :     return itsAlpha;
     735             :   }
     736             : 
     737           0 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::beta()
     738             :   {
     739           0 :     if( itsBeta && itsBeta->shape() == itsImageShape ) { return itsBeta; }
     740             :     //    checkRef( itsBeta , "beta" );
     741           0 :     itsBeta = openImage( itsImageName+String(".beta"), false );
     742             :     //    itsBeta->setUnits("Beta");
     743           0 :     return itsBeta;
     744             :   }
     745             : 
     746         678 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::alphaerror()
     747             :   {
     748         678 :     if( itsAlphaError && itsAlphaError->shape() == itsImageShape ) { return itsAlphaError; }
     749             :     //    checkRef( itsAlpha , "alpha" );
     750         113 :     itsAlphaError = openImage( itsImageName+String(".alpha.error"), false );
     751             :     //    itsAlpha->setUnits("Alpha");
     752         113 :     return itsAlphaError;
     753             :   }
     754             : 
     755           0 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::alphapbcor()
     756             :   {
     757           0 :     if( itsAlphaPBcor && itsAlphaPBcor->shape() == itsImageShape ) { return itsAlphaPBcor; }
     758             :     //    checkRef( itsAlphaPBcor , "alpha" );
     759           0 :     itsAlphaPBcor = openImage( itsImageName+String(".alpha.pbcor"), False );
     760             :     //    itsAlphaPBcor->setUnits("Alpha");
     761           0 :     return itsAlphaPBcor;
     762             :   }
     763             : 
     764           0 :   std::shared_ptr<ImageInterface<Float> > SIImageStoreMultiTerm::betapbcor()
     765             :   {
     766           0 :     if( itsBetaPBcor && itsBetaPBcor->shape() == itsImageShape ) { return itsBetaPBcor; }
     767             :     //    checkRef( itsBetaPBcor , "beta" );
     768           0 :     itsBetaPBcor = openImage( itsImageName+String(".beta.pbcor"), False );
     769             :     //    itsBetaPBcor->setUnits("Beta");
     770           0 :     return itsBetaPBcor;
     771             :   }
     772             : 
     773             : 
     774             : 
     775             :     // TODO : Move to an image-wrapper class ? Same function exists in SynthesisDeconvolver.
     776       17133 :   Bool SIImageStoreMultiTerm::doesImageExist(String imagename)
     777             :   {
     778       51399 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","doesImageExist",WHERE) );
     779       34266 :     Directory image( imagename );
     780       34266 :     return image.exists();
     781             :   }
     782             : 
     783             : 
     784           0 :   void SIImageStoreMultiTerm::resetImages( Bool resetpsf, Bool resetresidual, Bool resetweight )
     785             :   {
     786           0 :     for(uInt tix=0;tix<2*itsNTerms-1;tix++)
     787             :       {
     788           0 :         if( resetpsf ) psf(tix)->set(0.0);
     789             : 
     790           0 :         if( tix < itsNTerms ) {
     791           0 :           if( resetresidual ) {
     792             :             //removeMask( residual(tix) );
     793           0 :             residual(tix)->set(0.0);
     794             :           } 
     795             :         }
     796           0 :         if( resetweight && itsWeights[tix] ) weight(tix)->set(0.0);
     797           0 :         if( resetweight ) sumwt(tix)->set(0.0);
     798             :       }//nterms
     799           0 :   }
     800             :   
     801           0 :   void SIImageStoreMultiTerm::addImages( std::shared_ptr<SIImageStore> imagestoadd,
     802             :                                          Bool addpsf, Bool addresidual, Bool addweight, Bool adddensity)
     803             :   {
     804           0 :     for(uInt tix=0;tix<2*itsNTerms-1;tix++)
     805             :       {
     806             :         
     807           0 :         if(addpsf)
     808             :           {
     809           0 :             LatticeExpr<Float> adderPsf( *(psf(tix)) + *(imagestoadd->psf(tix)) ); 
     810           0 :             psf(tix)->copyData(adderPsf);    
     811             :           }
     812           0 :         if(addweight)
     813             :           {
     814             : 
     815           0 :             if(getUseWeightImage( *(imagestoadd->sumwt(tix)) ) ) // Access and add weight only if it is needed.
     816             :               {
     817           0 :                 LatticeExpr<Float> adderWeight( *(weight(tix)) + *(imagestoadd->weight(tix)) ); 
     818           0 :                 weight(tix)->copyData(adderWeight);
     819             :               }
     820             : 
     821           0 :             LatticeExpr<Float> adderSumWt( *(sumwt(tix)) + *(imagestoadd->sumwt(tix)) ); 
     822           0 :             sumwt(tix)->copyData(adderSumWt);
     823           0 :             setUseWeightImage( *sumwt(tix),  getUseWeightImage(*(imagestoadd->sumwt(tix)) ) );
     824             :           }
     825             : 
     826           0 :         if(tix < itsNTerms && addresidual)
     827             :           {
     828           0 :             LatticeExpr<Float> adderRes( *(residual(tix)) + *(imagestoadd->residual(tix)) ); 
     829           0 :             residual(tix)->copyData(adderRes);
     830             :           }
     831             : 
     832           0 :         if( tix==0 && adddensity )
     833             :           {
     834           0 :             LatticeExpr<Float> adderDensity( *(gridwt()) + *(imagestoadd->gridwt()) ); 
     835           0 :             gridwt()->copyData(adderDensity);
     836             :           }
     837             : 
     838             :       }
     839           0 :   }
     840             : 
     841         105 :   void SIImageStoreMultiTerm::dividePSFByWeight(const Float /*pblimit*/)
     842             :   {
     843         315 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","dividePSFByWeight",WHERE) );
     844             : 
     845             :     ////    for(uInt tix=0;tix<2*itsNTerms-1;tix++)
     846         414 :     for(Int tix=2*itsNTerms-1-1;tix>-1;tix--) // AAH go backwards so that zeroth term is normalized last..... sigh sigh sigh.
     847             :       {
     848             : 
     849             :         //cout << "npsfs : " << itsPsfs.nelements() << " and tix : " << tix << endl;
     850             : 
     851         309 :         normPSF(tix);
     852             :         
     853         309 :         if ( itsUseWeight) {
     854         118 :           divideImageByWeightVal( *weight(tix) ); 
     855             :         }
     856             :         
     857             :       }     
     858         105 :    }
     859             : 
     860         105 :  void SIImageStoreMultiTerm::normalizePrimaryBeam(const Float pblimit)
     861             :   {
     862         315 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","normalizePrimaryBeam",WHERE) );
     863         105 :     if ( itsUseWeight) {
     864             :       
     865          40 :       makePBFromWeight(pblimit);
     866             :     }
     867          65 :     else { makePBImage(pblimit); }
     868             :     //    calcSensitivity();
     869         105 :   }
     870             : 
     871             : 
     872             :   // Make another for the PSF too.
     873         180 :   void SIImageStoreMultiTerm::divideResidualByWeight(Float pblimit, const String normtype)
     874             :   {
     875         540 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","divideResidualByWeight",WHERE) );
     876             : 
     877         180 :     if( itsUseWeight )  
     878             :     {
     879          64 :         itsPBScaleFactor = getPbMax();
     880             :       }
     881             : 
     882         535 :     for(uInt tix=0;tix<itsNTerms;tix++)
     883             :       {
     884             : 
     885         355 :         divideImageByWeightVal( *residual(tix) );
     886             : 
     887             :         //      if(doesImageExist(itsImageName+String(".weight.tt0"))  )
     888         355 :         if( itsUseWeight )
     889             :         {
     890         127 :             LatticeExpr<Float> ratio;
     891         127 :             Float scalepb = fabs(pblimit) * itsPBScaleFactor * itsPBScaleFactor ;
     892         127 :             if( normtype=="flatnoise"){
     893         357 :               LatticeExpr<Float> deno = LatticeExpr<Float> ( sqrt( abs(*(weight(0)) ) ) * itsPBScaleFactor );
     894         119 :               os << LogIO::NORMAL1 << "Dividing " << itsImageName+String(".residual.tt")+String::toString(tix) ;
     895         119 :               os << " by [ sqrt(weightimage) * " << itsPBScaleFactor ;
     896         119 :               os << " ] to get flat noise with unit pb peak."<< LogIO::POST;
     897         357 :               LatticeExpr<Float> mask( iif( (deno) > scalepb , 1.0, 0.0 ) );
     898         238 :               LatticeExpr<Float> maskinv( iif( (deno) > scalepb , 0.0, 1.0 ) );
     899         119 :               ratio=LatticeExpr<Float> ( ( (*(residual(tix))) * mask ) / ( deno + maskinv ) );
     900             :             }
     901           8 :             else if(normtype=="pbsquare"){
     902           8 :               Float deno =  itsPBScaleFactor*itsPBScaleFactor ;
     903           8 :               os << LogIO::NORMAL1 << "Dividing " << itsImageName+String(".residual.tt")+String::toString(tix) ;
     904           8 :               os  << deno ;
     905           8 :               os << " ] to get optimal sig/noise with unit pb peak."<< LogIO::POST;
     906             :               
     907           8 :               ratio=LatticeExpr<Float> ( ( *(residual(tix)) ) / ( deno ) );
     908             :               
     909             : 
     910             : 
     911             :             }
     912           0 :             else if( normtype=="flatsky") {
     913           0 :                LatticeExpr<Float> deno( *(weight(0)) );
     914           0 :               os << LogIO::NORMAL1 << "Dividing " << itsImageName+String(".residual.tt")+String::toString(tix) ;
     915           0 :               os << " by [ weight ] to get flat sky"<< LogIO::POST;
     916           0 :               LatticeExpr<Float> mask( iif( (deno) > scalepb , 1.0, 0.0 ) );
     917           0 :               LatticeExpr<Float> maskinv( iif( (deno) > scalepb , 0.0, 1.0 ) );
     918           0 :               ratio=LatticeExpr<Float> ( ( (*(residual(tix))) * mask ) / ( deno + maskinv ) );
     919             :             }
     920             :             else{
     921           0 :                         throw(AipsError("Don't know how to proceed with normtype "+normtype));
     922             :                 }
     923             :             
     924             :             
     925             :             
     926         127 :             residual(tix)->copyData(ratio);
     927             :           }
     928             : 
     929         355 :         if( (residual(tix)->getDefaultMask()=="") && hasPB()  && pblimit >= 0.0 )
     930         177 :           {copyMask(pb(),residual(tix));}
     931             : 
     932         355 :         if( pblimit <0.0 && (residual(tix)->getDefaultMask()).matches("mask0") ) removeMask( residual(tix) );
     933             : 
     934             :       }
     935         180 :   }
     936             : 
     937         178 :   void SIImageStoreMultiTerm::divideModelByWeight(Float pblimit, const String normtype)
     938             :   {
     939         356 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","divideModelByWeight",WHERE) );
     940             : 
     941         356 :         if(     itsUseWeight // only when needed
     942         178 :         && weight() )// i.e. only when possible. For an initial starting model, don't need wt anyway.
     943             :       {
     944             : 
     945          64 :         if( normtype=="flatsky") {
     946           0 :           Array<Float> arrmod;
     947           0 :           model(0)->get( arrmod, true );
     948             : 
     949           0 :           os << "Model is already flat sky with peak flux : " << max(arrmod);
     950           0 :           os << ". No need to divide before prediction" << LogIO::POST;
     951             :           
     952           0 :           return;
     953             :           }
     954             : 
     955          64 :           itsPBScaleFactor = getPbMax();
     956             : 
     957         191 :         for(uInt tix=0;tix<itsNTerms;tix++)
     958         254 :           { LatticeExpr<Float> deno;
     959         127 :             if(normtype=="flatnoise"){
     960         119 :               os << LogIO::NORMAL1 << "Dividing " << itsImageName+String(".model")+String::toString(tix);
     961         119 :               os << " by [ sqrt(weight) / " << itsPBScaleFactor ;
     962         119 :               os <<" ] to get to flat sky model before prediction" << LogIO::POST;
     963             :             
     964         119 :               deno = LatticeExpr<Float> ( sqrt( abs(*(weight(0))) ) / itsPBScaleFactor );
     965             :             }
     966           8 :             else if(normtype=="pbsquare"){
     967           8 :               os << LogIO::NORMAL1 << "Dividing " << itsImageName+String(".model")+String::toString(tix);
     968           8 :               os << " by [ (weight) / " << itsPBScaleFactor*itsPBScaleFactor ;
     969           8 :               os <<" ] to get an optimal sig/noise  model before prediction" << LogIO::POST;
     970             :             
     971           8 :               deno = LatticeExpr<Float> (  abs(*(weight(0)))  / (itsPBScaleFactor*itsPBScaleFactor) );
     972             :             }
     973         381 :             LatticeExpr<Float> mask( iif( (deno) > fabs(pblimit) , 1.0, 0.0 ) );
     974         381 :             LatticeExpr<Float> maskinv( iif( (deno) > fabs(pblimit) , 0.0, 1.0 ) );
     975         381 :             LatticeExpr<Float> ratio( ( (*(model(tix))) * mask ) / ( deno + maskinv ) );
     976             : 
     977         127 :             itsModels[tix]->copyData(ratio);
     978             :           }    
     979             :       }
     980             :   }
     981             : 
     982             : 
     983         178 :   void SIImageStoreMultiTerm::multiplyModelByWeight(Float pblimit, const String normtype)
     984             :   {
     985         356 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","multiplyModelByWeight",WHERE) );
     986             : 
     987             :     
     988         356 :     if(        itsUseWeight // only when needed
     989         178 :         && weight() )// i.e. only when possible. For an initial starting model, don't need wt anyway.
     990             :       {
     991             : 
     992          64 :         if( normtype=="flatsky") {
     993           0 :           os << "Model is already flat sky. No need to multiply back after prediction" << LogIO::POST;
     994           0 :           return;
     995             :           }
     996             : 
     997          64 :           itsPBScaleFactor = getPbMax();
     998             : 
     999         191 :         for(uInt tix=0;tix<itsNTerms;tix++)
    1000             :           {
    1001         254 :             LatticeExpr<Float> deno;
    1002         127 :             if( normtype=="flatnoise") {
    1003         119 :               os << LogIO::NORMAL1 << "Multiplying " << itsImageName+String(".model")+String::toString(tix);
    1004         119 :               os << " by [ sqrt(weight) / " << itsPBScaleFactor;
    1005         119 :               os <<  " ] to take model back to flat noise with unit pb peak." << LogIO::POST;
    1006             :           
    1007         119 :               deno=LatticeExpr<Float> ( sqrt( abs(*(weight(0)) ) ) / itsPBScaleFactor );
    1008             :             }
    1009           8 :             else if ( normtype=="pbsquare"){
    1010           8 :               os << LogIO::NORMAL1 << "Multiplying " << itsImageName+String(".model")+String::toString(tix);
    1011           8 :               os << " by [ weight / " << itsPBScaleFactor*itsPBScaleFactor;
    1012           8 :               os <<  " ] to take model back to optima sig/noise with unit pb peak." << LogIO::POST;
    1013             :           
    1014           8 :               deno=LatticeExpr<Float> (  abs(*(weight(0))  ) / (itsPBScaleFactor*itsPBScaleFactor) );
    1015             :             }
    1016             :             else{
    1017           0 :               throw(AipsError("No idea of what to do for  "+normtype));
    1018             :             }
    1019             : 
    1020         381 :           LatticeExpr<Float> mask( iif( (deno) > fabs(pblimit) , 1.0, 0.0 ) );
    1021         381 :           LatticeExpr<Float> maskinv( iif( (deno) > fabs(pblimit) , 0.0, 1.0 ) );
    1022         381 :           LatticeExpr<Float> ratio( ( (*(model(tix))) * mask ) * ( deno + maskinv ) );
    1023             : 
    1024         127 :             itsModels[tix]->copyData(ratio);
    1025             :           }    
    1026             :       }
    1027             :   }
    1028             : 
    1029             : 
    1030         125 :   void SIImageStoreMultiTerm::restore(GaussianBeam& rbeam, String& usebeam, uInt /*term*/, Float psfcutoff)
    1031             :   {
    1032             : 
    1033         250 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","restore",WHERE) );
    1034             : 
    1035         372 :     for(uInt tix=0; tix<itsNTerms; tix++)
    1036             :       {
    1037         247 :         SIImageStore::restore(rbeam, usebeam, tix, psfcutoff);
    1038             :       } 
    1039             :    
    1040         125 :     calculateAlphaBeta("image");
    1041             :  
    1042         125 :   }// restore
    1043             : 
    1044         125 :   void SIImageStoreMultiTerm::calculateAlphaBeta(String imtype)
    1045             :   {
    1046         375 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","calculateAlphaBeta",WHERE) );
    1047             :     try
    1048             :       {
    1049             : 
    1050             :         // Check if this is Stokes I.
    1051         125 :         Bool isOnlyStokesI=True;
    1052             : 
    1053         250 :         Vector<Int> stokes (  (itsParentCoordSys.stokesCoordinate()).stokes() );
    1054         125 :         AlwaysAssert( stokes.nelements()>0 , AipsError);
    1055         125 :         if( stokes.nelements()>1 || stokes[0]!=1 ) isOnlyStokesI=False;
    1056             : 
    1057         125 :         if( ! isOnlyStokesI )
    1058           9 :           { os << "Alpha and Beta images will not be computed for images that contain anything other than stokes I in them." << LogIO::POST; }
    1059             : 
    1060             :         //Calculate alpha, beta
    1061         125 :             if( itsNTerms > 1 && isOnlyStokesI)
    1062             :               {
    1063             :                 // Calculate alpha and beta
    1064         339 :                 LatticeExprNode leMaxRes = max( *( residual(0) ) );
    1065         113 :                 Float maxres = leMaxRes.getFloat();
    1066         113 :                 Float specthreshold = maxres/10.0;  //////////// do something better here..... 
    1067             :                 
    1068         113 :                 os << "Calculating spectral parameters for Intensity > peakresidual/10 = " << specthreshold << " Jy/beam" << LogIO::POST;
    1069             : 
    1070             :                 /////////////////////////////////////////////////////////
    1071             :                 /////// Calculate alpha
    1072         113 :                 if(imtype=="image")
    1073             :                   {
    1074         339 :                     LatticeExpr<Float> mask1(iif(((*(image(0))))>(specthreshold),1.0,0.0));
    1075         339 :                     LatticeExpr<Float> mask0(iif(((*(image(0))))>(specthreshold),0.0,1.0));
    1076         339 :                     LatticeExpr<Float> alphacalc( (((*(image(1))))*mask1)/(((*(image(0))))+(mask0)) );
    1077         113 :                     alpha()->copyData(alphacalc);
    1078             :                     
    1079         226 :                     ImageInfo ii = image(0)->imageInfo();
    1080             :                     // Set the restoring beam for alpha
    1081         113 :                     alpha()->setImageInfo(ii);
    1082             :                     //alpha()->table().unmarkForDelete();
    1083             :                     
    1084             :                     // Make a mask for the alpha image
    1085         339 :                     LatticeExpr<Bool> lemask(iif(((*(image(0))) > specthreshold) , True, False));
    1086         113 :                     removeMask( alpha() );
    1087         113 :                     createMask( lemask, (alpha()) );
    1088             : 
    1089             :                     /////// Calculate alpha error
    1090         113 :                     alphaerror()->set(0.0);
    1091             : 
    1092         339 :                     LatticeExpr<Float> alphacalcerror( abs(alphacalc) * sqrt( ( (*residual(0)*mask1)/(*image(0)+mask0) )*( (*residual(0)*mask1)/(*image(0)+mask0) ) + ( (*residual(1)*mask1)/(*image(1)+mask0) )*( (*residual(1)*mask1)/(*image(1)+mask0) )  ) );
    1093         113 :                     alphaerror()->copyData(alphacalcerror);
    1094         113 :                     alphaerror()->setImageInfo(ii);
    1095         113 :                     removeMask(alphaerror());
    1096         113 :                     createMask(lemask, alphaerror());
    1097             :                     //              alphaerror()->table().unmarkForDelete();      
    1098         113 :                     os << "Written Spectral Index Error Image : " << alphaerror()->name() << LogIO::POST;
    1099             : 
    1100         113 :                 if(itsNTerms>2) // calculate beta too.
    1101             :                   {
    1102           0 :                         beta()->set(0.0);
    1103           0 :                         LatticeExpr<Float> betacalc( (*image(2)*mask1)/((*image(0))+(mask0))-0.5*(*alpha())*((*alpha())-1.0) );
    1104           0 :                         beta()->copyData(betacalc);
    1105           0 :                         beta()->setImageInfo(ii);
    1106             :                         //imbeta.setUnits(Unit("Spectral Curvature"));
    1107           0 :                         removeMask(beta());
    1108           0 :                         createMask(lemask, beta());
    1109           0 :                         os << "Written Spectral Curvature Image : " << beta()->name() << LogIO::POST;
    1110             :                   }
    1111             : 
    1112             :                   }
    1113             :                 else
    1114             :                   {
    1115           0 :                     LatticeExpr<Float> mask1(iif(((*(imagepbcor(0))))>(specthreshold),1.0,0.0));
    1116           0 :                     LatticeExpr<Float> mask0(iif(((*(imagepbcor(0))))>(specthreshold),0.0,1.0));
    1117           0 :                     LatticeExpr<Float> alphacalc( (((*(imagepbcor(1))))*mask1)/(((*(imagepbcor(0))))+(mask0)) );
    1118           0 :                     alphapbcor()->copyData(alphacalc);
    1119             :                     
    1120           0 :                     ImageInfo ii = image(0)->imageInfo();
    1121             :                     // Set the restoring beam for alpha
    1122           0 :                     alphapbcor()->setImageInfo(ii);
    1123             :                     //alpha()->table().unmarkForDelete();
    1124             :                     
    1125             :                     // Make a mask for the alpha image
    1126           0 :                     LatticeExpr<Bool> lemask(iif(((*(imagepbcor(0))) > specthreshold) , True, False));
    1127           0 :                     removeMask( alphapbcor() );
    1128           0 :                     createMask( lemask, (alphapbcor()) );
    1129             : 
    1130             :                 /////////////////////////////////////////////////////////
    1131           0 :                 if(itsNTerms>2) // calculate beta too.
    1132             :                   {
    1133           0 :                         betapbcor()->set(0.0);
    1134           0 :                         LatticeExpr<Float> betacalc( (*imagepbcor(2)*mask1)/((*imagepbcor(0))+(mask0))-0.5*(*alphapbcor())*((*alphapbcor())-1.0) );
    1135           0 :                         betapbcor()->copyData(betacalc);
    1136           0 :                         betapbcor()->setImageInfo(ii);
    1137             :                         //imbeta.setUnits(Unit("Spectral Curvature"));
    1138           0 :                         removeMask(betapbcor());
    1139           0 :                         createMask(lemask, betapbcor());
    1140           0 :                         os << "Written Spectral Curvature Image : " << betapbcor()->name() << LogIO::POST;
    1141             :                   }
    1142             :                 
    1143             :                   }// pbcor
    1144             : 
    1145             :               }//if nterms>1
    1146             :       }
    1147           0 :     catch(AipsError &x)
    1148             :       {
    1149           0 :         throw( AipsError("Error in computing Alpha (and Beta) : " + x.getMesg() ) );
    1150             :       }
    1151             : 
    1152         125 :   }// calculateAlphaBeta
    1153             : 
    1154           1 :   void SIImageStoreMultiTerm::pbcor()
    1155             :   {
    1156             : 
    1157           2 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","pbcorPlane",WHERE) );
    1158             : 
    1159             :     /// Temp Code to prevent this approximate PBCOR from happening for EVLA data
    1160             :     if(1)
    1161             :       {
    1162           1 :         String telescope = itsCoordSys.obsInfo().telescope();
    1163           1 :         if ( telescope != "ALMA" )
    1164             :           {
    1165           1 :             os << LogIO::WARN << "Wideband (multi-term) PB correction is not yet available via tclean in the 4.7 release. Please use the widebandpbcor task instead. "<< LogIO::POST;
    1166           1 :             return;
    1167             :           }
    1168             :         else
    1169             :           {
    1170           0 :             os << LogIO::WARN << "Wideband (multi-term) PB Correction is currently only an approximation. It assumes no PB frequency dependence. This code has been added for the 4.7 release to support the current ALMA pipeline, which does not apply corrections for the frequency dependence of the primary beam across small fractional bandwidths. Please look at the help for the 'pbcor' parameter and use the widebandpbcor task if needed. " <<LogIO::POST;
    1171             :           }
    1172             : 
    1173             :         
    1174             :       }
    1175             : 
    1176             : 
    1177             :     // message saying that it's only stokes I for now...
    1178             : 
    1179           0 :     for(uInt tix=0; tix<itsNTerms; tix++)
    1180             :       {
    1181           0 :         SIImageStore::pbcor(tix);
    1182             :       } 
    1183             : 
    1184           0 :     calculateAlphaBeta("pbcor");
    1185             : 
    1186             :   }
    1187             : 
    1188         105 :   void SIImageStoreMultiTerm::calcSensitivity()
    1189             :   {
    1190         315 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","calcSensitivity",WHERE) );
    1191             : 
    1192             :     // Construct Hessian.
    1193             :     
    1194         210 :     Matrix<Float> hess(IPosition(2,itsNTerms,itsNTerms));
    1195         312 :     for(uInt tay1=0;tay1<itsNTerms;tay1++)
    1196         618 :       for(uInt tay2=0;tay2<itsNTerms;tay2++)
    1197             :         {
    1198             :           //uInt taymin = (tay1<=tay2)? tay1 : tay2;
    1199             :           //uInt taymax = (tay1>=tay2)? tay1 : tay2;
    1200             :           //uInt ind = (taymax*(taymax+1)/2)+taymin;
    1201             : 
    1202         411 :           uInt ind = tay1+tay2;
    1203         411 :           AlwaysAssert( ind < 2*itsNTerms-1, AipsError );
    1204             : 
    1205         411 :           Array<Float> lsumwt;
    1206         411 :           sumwt( ind )->get( lsumwt, false );
    1207             :           //      cout << "lsumwt shape : " << lsumwt.shape() << endl;
    1208         411 :           AlwaysAssert( lsumwt.shape().nelements()==4, AipsError );
    1209         411 :           AlwaysAssert( lsumwt.shape()[0]>0, AipsError );
    1210             : 
    1211             :           //      hess(tay1,tay2) = lsumwt(IPosition(1,0)); //Always pick sumwt from first facet only.
    1212         411 :           hess(tay1,tay2) = lsumwt(IPosition(4,0,0,0,0)); //Always pick sumwt from first facet only.
    1213             :         }
    1214             : 
    1215         105 :     os << "Multi-Term Hessian Matrix : " << hess << LogIO::POST;
    1216             : 
    1217             :     // Invert Hessian. 
    1218             :     try
    1219             :       {
    1220         105 :         Float deter=0.0;
    1221         210 :         Matrix<Float> invhess;
    1222         105 :         invertSymPosDef(invhess,deter,hess);
    1223         105 :         os << "Multi-Term Covariance Matrix : " << invhess << LogIO::POST;
    1224             : 
    1225             :         // Just print the sqrt of the diagonal elements. 
    1226             :         
    1227         312 :         for(uInt tix=0;tix<itsNTerms;tix++)
    1228             :           {
    1229         207 :             os << "[" << itsImageName << "][Taylor"<< tix << "] Theoretical sensitivity (Jy/bm):" ;
    1230         207 :             if( invhess(tix,tix) > 0.0 ) { os << sqrt(invhess(tix,tix)) << LogIO::POST; }
    1231           0 :             else { os << "none" << LogIO::POST; }
    1232             :           }
    1233             :       }
    1234           0 :     catch(AipsError &x)
    1235             :       {
    1236           0 :         os << LogIO::WARN << "Cannot invert Hessian Matrix : " << x.getMesg()  << " || Calculating approximate sensitivity " << LogIO::POST;
    1237             :         
    1238             :         // Approximate : 1/h^2
    1239           0 :         for(uInt tix=0;tix<itsNTerms;tix++)
    1240             :           {
    1241           0 :             Array<Float> lsumwt;
    1242           0 :             AlwaysAssert( 2*tix < 2*itsNTerms-1, AipsError );
    1243           0 :             sumwt(2*tix)->get( lsumwt , false ); 
    1244             :             
    1245           0 :             IPosition shp( lsumwt.shape() );
    1246             :             //cout << "Sumwt shape : " << shp << " : " << lsumwt << endl;
    1247             :             //AlwaysAssert( shp.nelements()==4 , AipsError );
    1248             :             
    1249           0 :             os << "[" << itsImageName << "][Taylor"<< tix << "] Approx Theoretical sensitivity (Jy/bm):" ;
    1250             :             
    1251           0 :             IPosition it(4,0,0,0,0);
    1252           0 :             for ( it[0]=0; it[0]<shp[0]; it[0]++)
    1253           0 :               for ( it[1]=0; it[1]<shp[1]; it[1]++)
    1254           0 :                 for ( it[2]=0; it[2]<shp[2]; it[2]++)
    1255           0 :                   for ( it[3]=0; it[3]<shp[3]; it[3]++)
    1256             :                     {
    1257           0 :                       if( shp[0]>1 ){os << "f"<< it[0]+(it[1]*shp[0]) << ":" ;}
    1258           0 :                       if( lsumwt( it )  > 1e-07 ) 
    1259             :                         { 
    1260           0 :                           os << 1.0/(sqrt(lsumwt(it))) << " " ;
    1261             :                         }
    1262             :                       else
    1263             :                         {
    1264           0 :                           os << "none" << " ";
    1265             :                         }
    1266             :                     }
    1267             :             
    1268           0 :             os << LogIO::POST;
    1269             :           }
    1270             :       }
    1271             : 
    1272         105 :     calcFractionalBandwidth();
    1273         105 :   }
    1274             :  
    1275         228 :   Double SIImageStoreMultiTerm::calcFractionalBandwidth()
    1276             :   {
    1277             : 
    1278         456 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","calcFractionalBandwidth",WHERE) );
    1279             : 
    1280         228 :     Double fbw=1.0;
    1281             : 
    1282         912 :     for(uInt i=0; i<itsCoordSys.nCoordinates(); i++)
    1283             :     {
    1284         684 :       if( itsCoordSys.type(i) == Coordinate::SPECTRAL )
    1285             :         {
    1286         456 :           SpectralCoordinate speccoord(itsCoordSys.spectralCoordinate(i));
    1287         228 :           Double startfreq=0.0,startpixel=-0.5;
    1288         228 :           Double endfreq=0.0,endpixel=+0.5;
    1289         228 :           speccoord.toWorld(startfreq,startpixel);
    1290         228 :           speccoord.toWorld(endfreq,endpixel);
    1291         228 :           Double midfreq = (endfreq+startfreq)/2.0;
    1292         228 :           fbw = ((endfreq - startfreq)/midfreq) * 100.0;
    1293         228 :           os << "MFS frequency range : " << startfreq/1.0e+9 << " GHz -> " << endfreq/1.0e+9 << "GHz."; 
    1294         228 :           os << "Fractional Bandwidth : " << fbw << " %.";
    1295         228 :           os << "Reference Frequency for Taylor Expansion : "<< getReferenceFrequency()/1.0e+9 << "GHz." << LogIO::POST;
    1296             :         }
    1297             :     }
    1298         456 :     return fbw;
    1299             :   }
    1300             : 
    1301             :  
    1302             :   // Check for non-zero model (this is different from getting model flux, for derived SIIMMT)
    1303         427 :   Bool SIImageStoreMultiTerm::isModelEmpty()
    1304             :   {
    1305             :     /// There MUST be a more efficient way to do this !!!!!  I hope. 
    1306             :     /// Maybe save this info and change it anytime model() is accessed.... 
    1307         427 :     Bool emptymodel=true;
    1308        1273 :     for(uInt tix=0;tix<itsNTerms;tix++)
    1309             :       {
    1310             :         //if( fabs( getModelFlux(tix) ) > 1e-08  ) emptymodel=false;
    1311        1540 :         if( doesImageExist(itsImageName+String(".model.tt")+String::toString(tix)) && 
    1312        1174 :             fabs( getModelFlux(tix) ) > 1e-08  ) emptymodel=false;
    1313             :       } 
    1314         427 :     return  emptymodel;
    1315             :   }
    1316             : 
    1317           0 :   void SIImageStoreMultiTerm::printImageStats()
    1318             :   {
    1319           0 :     LogIO os( LogOrigin("SIImageStoreMultiTerm","printImageStats",WHERE) );
    1320             :     // FIXME minresmask needs to be initialized here, or else compiler complains
    1321           0 :     Float minresmask = 0, maxresmask, minres, maxres;
    1322           0 :     ArrayLattice<Bool> pixelmask(residual()->getMask());
    1323             : 
    1324             :     //    findMinMax( residual()->get(), mask()->get(), minres, maxres, minresmask, maxresmask );
    1325             : 
    1326           0 :     if (hasMask())
    1327             :       {
    1328             : //      findMinMaxLattice(*residual(), *mask() , maxres,maxresmask, minres, minresmask);
    1329           0 :         findMinMaxLattice(*residual(), *mask() , pixelmask, maxres,maxresmask, minres, minresmask);
    1330             :       }
    1331             :     else
    1332             :       {
    1333           0 :         LatticeExpr<Float> reswithpixmask(iif(pixelmask, *residual(), 0));
    1334             :         //LatticeExprNode pres( max( *residual() ) );
    1335           0 :         LatticeExprNode pres( max( reswithpixmask ) );
    1336           0 :         maxres = pres.getFloat();
    1337             :         //LatticeExprNode pres2( min( *residual() ) );
    1338           0 :         LatticeExprNode pres2( min( reswithpixmask ) );
    1339           0 :         minres = pres2.getFloat();
    1340             :       }
    1341             : 
    1342           0 :     os << "[" << itsImageName << "]" ;
    1343           0 :     os << " Peak residual (max,min) " ;
    1344           0 :     if( minresmask!=0.0 || maxresmask!=0.0 )
    1345           0 :       { os << "within mask : (" << maxresmask << "," << minresmask << ") "; }
    1346           0 :     os << "over full image : (" << maxres << "," << minres << ")" << LogIO::POST;
    1347             : 
    1348           0 :     os << "[" << itsImageName << "] Total Model Flux : " ;
    1349           0 :     for(uInt tix=0;tix<itsNTerms;tix++)
    1350           0 :       {os << getModelFlux(tix) << "(tt" << String::toString(tix) << ")"; }
    1351           0 :     os<<LogIO::POST;
    1352             : 
    1353           0 :   }
    1354             : 
    1355         286 :   std::shared_ptr<SIImageStore> SIImageStoreMultiTerm::getSubImageStore(const Int facet, const Int nfacets, 
    1356             :                                                           const Int chan, const Int nchanchunks, 
    1357             :                                                           const Int pol, const Int npolchunks)
    1358             :   {
    1359             :       std::shared_ptr<SIImageStore> multiTermStore =
    1360         286 :           std::make_shared<SIImageStoreMultiTerm>(itsModels, itsResiduals, itsPsfs, itsWeights, itsImages, itsSumWts, itsPBs, itsImagePBcors, itsMask, itsAlpha, itsBeta, itsAlphaError,itsAlphaPBcor, itsBetaPBcor,  itsCoordSys, itsParentImageShape, itsImageName, itsObjectName, itsMiscInfo, facet, nfacets, chan, nchanchunks, pol, npolchunks);
    1361         286 :       return multiTermStore;
    1362             :   }
    1363             : 
    1364             : 
    1365             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
    1366             : 
    1367             : //
    1368             :   //-------------------------------------------------------------
    1369             :   // Initialize the internals of the object.  Perhaps other such
    1370             :   // initializations in the constructors can be moved here too.
    1371             :   //
    1372        1005 :   void SIImageStoreMultiTerm::init()
    1373             :   {
    1374        1005 :     imageExts.resize(MAX_IMAGE_IDS);
    1375             :     
    1376        1005 :     imageExts(MASK)=".mask";
    1377        1005 :     imageExts(PSF)=".psf";
    1378        1005 :     imageExts(MODEL)=".model";
    1379        1005 :     imageExts(RESIDUAL)=".residual";
    1380        1005 :     imageExts(WEIGHT)=".weight";
    1381        1005 :     imageExts(IMAGE)=".image";
    1382        1005 :     imageExts(SUMWT)=".sumwt";
    1383        1005 :     imageExts(GRIDWT)=".gridwt";
    1384        1005 :     imageExts(PB)=".pb";
    1385        1005 :     imageExts(FORWARDGRID)=".forward";
    1386        1005 :     imageExts(BACKWARDGRID)=".backward";
    1387             :     //    imageExts(IMAGEPBCOR)=".image.pbcor";
    1388             : 
    1389        1005 :     itsParentPsfs.resize(itsPsfs.nelements());
    1390        1005 :     itsParentModels.resize(itsModels.nelements());
    1391        1005 :     itsParentResiduals.resize(itsResiduals.nelements());
    1392        1005 :     itsParentWeights.resize(itsWeights.nelements());
    1393        1005 :     itsParentImages.resize(itsImages.nelements());
    1394        1005 :     itsParentSumWts.resize(itsSumWts.nelements());
    1395        1005 :     itsParentImagePBcors.resize(itsImagePBcors.nelements());
    1396        1005 :     itsParentPBs.resize(itsPBs.nelements());
    1397             :    
    1398        1005 :     itsParentPsfs = itsPsfs;
    1399        1005 :     itsParentModels=itsModels;
    1400        1005 :     itsParentResiduals=itsResiduals;
    1401        1005 :     itsParentWeights=itsWeights;
    1402        1005 :     itsParentImages=itsImages;
    1403        1005 :     itsParentSumWts=itsSumWts;
    1404        1005 :     itsParentImagePBcors=itsImagePBcors;
    1405        1005 :     itsParentPBs=itsPBs;
    1406             : 
    1407        1005 :     itsParentMask=itsMask;
    1408             : 
    1409        1005 :     itsParentImageShape = itsImageShape;
    1410        1005 :     itsParentCoordSys = itsCoordSys;
    1411        1005 :     if( itsNFacets>1 || itsNChanChunks>1 || itsNPolChunks>1 ) { itsImageShape=IPosition(4,0,0,0,0); }
    1412             : 
    1413        1005 :     itsOpened=0;
    1414             : 
    1415        1005 :   }
    1416             : 
    1417             :   /*
    1418             :   Bool SIImageStoreMultiTerm::getUseWeightImage()
    1419             :   {  if( itsParentSumWts.nelements()==0 || ! itsParentSumWts[0] ) 
    1420             :       {return false;} 
    1421             :     else
    1422             :       {
    1423             :         Bool ret = SIImageStore::getUseWeightImage( *(itsParentSumWts[0]) );
    1424             :         return ret;
    1425             :       }
    1426             :   }
    1427             :   */
    1428             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
    1429             :   //////////////////////////////////////////////////////////////////////////////////////////////////////
    1430             : 
    1431             : } //# NAMESPACE CASA - END
    1432             : 

Generated by: LCOV version 1.16