LCOV - code coverage report
Current view: top level - synthesis/ImagerObjects - SIImageStoreMultiTerm.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 482 658 73.3 %
Date: 2024-12-11 20:54:31 Functions: 37 46 80.4 %

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

Generated by: LCOV version 1.16