LCOV - code coverage report
Current view: top level - synthesis/ImagerObjects - SynthesisNormalizer.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 315 0.0 %
Date: 2024-10-09 13:55:54 Functions: 0 21 0.0 %

          Line data    Source code
       1             : //# SynthesisNormalizer.cc: Implementation of Gather/Scatter for parallel major cycles
       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/lattices/Lattices/LatticeLocker.h>
      48             : #include <casacore/images/Images/TempImage.h>
      49             : #include <casacore/images/Images/SubImage.h>
      50             : #include <casacore/images/Regions/ImageRegion.h>
      51             : 
      52             : #include <synthesis/ImagerObjects/SynthesisNormalizer.h>
      53             : 
      54             : #include <sys/types.h>
      55             : #include <unistd.h>
      56             : using namespace std;
      57             : 
      58             : using namespace casacore;
      59             : namespace casa { //# NAMESPACE CASA - BEGIN
      60             :   
      61           0 :   SynthesisNormalizer::SynthesisNormalizer() : 
      62           0 :                                        itsImages(std::shared_ptr<SIImageStore>()),
      63           0 :                                        itsPartImages(Vector<std::shared_ptr<SIImageStore> >()),
      64           0 :                                        itsImageName(""),
      65           0 :                                        itsPartImageNames(Vector<String>(0)),
      66           0 :                                        itsPBLimit(0.2),
      67           0 :                                        itsMapperType("default"),
      68           0 :                                        itsNTaylorTerms(1),
      69           0 :                                        itsNFacets(1)
      70             :   {
      71           0 :     itsFacetImageStores.resize(0);
      72           0 :     itsPBLimit = 0.35;
      73           0 :   }
      74             :   
      75           0 :   SynthesisNormalizer::~SynthesisNormalizer() 
      76             :   {
      77           0 :     LogIO os( LogOrigin("SynthesisNormalizer","destructor",WHERE) );
      78           0 :     os << LogIO::DEBUG1 << "SynthesisNormalizer destroyed" << LogIO::POST;
      79           0 :     SynthesisUtilMethods::getResource("End SynthesisNormalizer");
      80             : 
      81           0 :   }
      82             :   
      83             :   
      84           0 :   void SynthesisNormalizer::setupNormalizer(Record normpars)
      85             :   {
      86           0 :     LogIO os( LogOrigin("SynthesisNormalizer","setupNormalizer",WHERE) );
      87             : 
      88             :     try
      89             :       {
      90           0 :         if( normpars.isDefined("psfcutoff") )  // A single string
      91             :         {
      92           0 :             normpars.get( RecordFieldId("psfcutoff") , itsPsfcutoff  );
      93             :         }else
      94             :         {
      95           0 :           itsPsfcutoff=0.35;
      96             :         }
      97             :           
      98             :           
      99             : 
     100           0 :       if( normpars.isDefined("imagename") )  // A single string
     101           0 :         { itsImageName = normpars.asString( RecordFieldId("imagename")); }
     102             :       else
     103           0 :         {throw( AipsError("imagename not specified")); }
     104             : 
     105           0 :       if( normpars.isDefined("partimagenames") )  // A vector of strings
     106           0 :         { normpars.get( RecordFieldId("partimagenames") , itsPartImageNames ); }
     107             :       else
     108           0 :         { itsPartImageNames.resize(0); }
     109             : 
     110           0 :       if( normpars.isDefined("pblimit") )
     111             :         {
     112           0 :           normpars.get( RecordFieldId("pblimit") , itsPBLimit );
     113             :         }
     114             :       else
     115           0 :         { itsPBLimit = 0.2; }
     116             : 
     117           0 :       if( normpars.isDefined("normtype") )  // A single string
     118           0 :         { itsNormType = normpars.asString( RecordFieldId("normtype")); }
     119             :       else
     120           0 :         { itsNormType = "flatnoise";} // flatnoise, flatsky
     121             : 
     122             :       //      cout << "Chosen normtype : " << itsNormType << endl;
     123             : 
     124             :       // For multi-term choices. Try to eliminate, after making imstores hold aux descriptive info.
     125             :       /*
     126             :       if( normpars.isDefined("mtype") )  // A single string
     127             :         { itsMapperType = normpars.asString( RecordFieldId("mtype")); }
     128             :       else
     129             :         { itsMapperType = "default";}
     130             :       */
     131             : 
     132           0 :       if( normpars.isDefined("deconvolver") )  // A single string
     133           0 :         { String dec = normpars.asString( RecordFieldId("deconvolver")); 
     134           0 :           if (dec == "mtmfs") { itsMapperType="multiterm"; }
     135           0 :           else itsMapperType="default";
     136           0 :         }
     137             :       else
     138           0 :         { itsMapperType = "default";}
     139             : 
     140           0 :       if( normpars.isDefined("nterms") )  // A single int
     141           0 :         { itsNTaylorTerms = normpars.asuInt( RecordFieldId("nterms")); }
     142             :       else
     143           0 :         { itsNTaylorTerms = 1;}
     144             : 
     145           0 :       if( normpars.isDefined("facets") )  // A single int
     146           0 :         { itsNFacets = normpars.asuInt( RecordFieldId("facets")); }
     147             :       else
     148           0 :         { itsNFacets = 1;}
     149             : 
     150           0 :       if( normpars.isDefined("restoringbeam") ) 
     151             :         { 
     152           0 :           if (normpars.dataType("restoringbeam")==TpString) {
     153           0 :             itsUseBeam = normpars.asString( RecordFieldId("restoringbeam") ); }          
     154             :           else 
     155           0 :             { itsUseBeam = "";} 
     156             :         }
     157             :       }
     158           0 :     catch(AipsError &x)
     159             :       {
     160           0 :         throw( AipsError("Error in reading gather/scatter parameters: "+x.getMesg()) );
     161           0 :       }
     162             :     
     163           0 :   }//end of setupParSync
     164             : 
     165             : 
     166           0 :   void SynthesisNormalizer::gatherImages(Bool dopsf, Bool doresidual, Bool dodensity)
     167             :   {
     168             :     //    cout << " partimagenames :" << itsPartImageNames << endl;
     169             : 
     170           0 :     Bool needToGatherImages = setupImagesOnDisk();
     171             : 
     172           0 :     if( needToGatherImages )
     173             :       {
     174           0 :         LogIO os( LogOrigin("SynthesisNormalizer", "gatherImages",WHERE) );
     175             : 
     176           0 :         AlwaysAssert( itsPartImages.nelements()>0 , AipsError );
     177             :         //Bool doresidual = !dopsf;
     178           0 :         Bool doweight = dopsf ; //|| ( doresidual && ! itsImages->hasSensitivity() );
     179             :         //      Bool doweight = dopsf || ( doresidual && itsImages->getUseWeightImage(*(itsPartImages[0]->residual())) );
     180             :         
     181           0 :         os << "Gather "<< (doresidual?"residual":"") << ( (dopsf&&doresidual)?",":"")  
     182           0 :            << (dopsf?"psf":"") << ( (dopsf&&doweight)?",":"")  
     183             :            << (doweight?"weight":"")<< " images : " << itsPartImageNames 
     184           0 :            << " onto :" << itsImageName << LogIO::POST;
     185             :         
     186             :         // Add intelligence to modify all only the first time, but later, only residual;
     187           0 :         itsImages->resetImages( /*psf*/dopsf, /*residual*/doresidual, /*weight*/doweight ); 
     188             :         
     189           0 :         for( uInt part=0;part<itsPartImages.nelements();part++)
     190             :           {
     191           0 :             itsImages->addImages( itsPartImages[part], /*psf*/dopsf, /*residual*/doresidual, /*weight*/doweight, /*griddedwt*/dodensity );
     192           0 :             itsPartImages[part]->releaseLocks();
     193             :           }
     194             : 
     195           0 :       }// end of image gathering.
     196             :     
     197             :     // Normalize by the weight image.
     198             :     //    divideResidualByWeight();
     199           0 :     itsImages->releaseLocks();
     200             :     
     201           0 :   }// end of gatherImages
     202             : 
     203           0 :   void SynthesisNormalizer::gatherPB()
     204             :   {
     205           0 :     if( itsPartImageNames.nelements()>0 )
     206             :       {
     207             : 
     208             :         try
     209             :           {
     210           0 :             itsPartImages[0] = makeImageStore( itsPartImageNames[0] );
     211             :           }
     212           0 :         catch(AipsError &x)
     213             :           {
     214           0 :             throw(AipsError("Cannot construct ImageStore for "+itsPartImageNames[0]+". "+x.what()));
     215           0 :           }
     216             : 
     217             :         try{
     218           0 :             LatticeExpr<Float> thepb( *(itsPartImages[0]->pb()) );
     219           0 :             LatticeLocker lock1(*(itsImages->pb()), FileLocker::Write);
     220           0 :             itsImages->pb()->copyData(thepb);
     221             : 
     222           0 :           }
     223           0 :         catch(AipsError &x)
     224             :           {
     225           0 :             throw(AipsError("Cannot copy the PB : "+x.getMesg()));
     226           0 :           }
     227             : 
     228             :       }
     229           0 :   }
     230             : 
     231           0 :   void SynthesisNormalizer::scatterModel()
     232             :   {
     233             : 
     234           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "scatterModel",WHERE) );
     235             : 
     236           0 :     setupImagesOnDisk(); // To open up and initialize itsPartImages.
     237             : 
     238             :     //    os << "In ScatterModel : " << itsPartImages.nelements() << " for " << itsPartImageNames << LogIO::POST;
     239             :     
     240           0 :     if( itsPartImages.nelements() > 0 ) // && itsImages->doesImageExist(modelName) )
     241             :       {
     242           0 :         os << "Send the model from : " << itsImageName << " to all nodes :" << itsPartImageNames << LogIO::POST;
     243             :         
     244             :         // Make the list of model images. This list is of length >1 only for multi-term runs.
     245             :         // Vector<String> modelNames( itsImages->getNTaylorTerms() );
     246             :         // if( modelNames.nelements() ==1 ) modelNames[0] = itsImages->getName()+".model";
     247             :         // if( modelNames.nelements() > 1 ) 
     248             :         //   {
     249             :         //     for( uInt nt=0;nt<itsImages->getNTaylorTerms();nt++)
     250             :         //       modelNames[nt] = itsImages->getName()+".model.tt" + String::toString(nt);
     251             :         //   }
     252             : 
     253             : 
     254           0 :         Vector<String> modelNames( itsImages->getNTaylorTerms() );
     255           0 :         if( itsImages->getType()=="default" ) modelNames[0] = itsImages->getName()+".model";
     256           0 :         if( itsImages->getType()=="multiterm" ) 
     257             :           {
     258           0 :             for( uInt nt=0;nt<itsImages->getNTaylorTerms();nt++)
     259           0 :               modelNames[nt] = itsImages->getName()+".model.tt" + String::toString(nt);
     260             :           }
     261             :         
     262             :         
     263             :         
     264           0 :         for( uInt part=0;part<itsPartImages.nelements();part++)
     265             :           {
     266           0 :             itsPartImages[part]->setModelImage( modelNames );
     267           0 :             itsPartImages[part]->releaseLocks();
     268             :           }
     269           0 :         itsImages->releaseLocks();
     270           0 :       }
     271             :     
     272           0 :   }// end of scatterModel
     273             :   
     274           0 :   void SynthesisNormalizer::scatterWeightDensity()
     275             :   {
     276             : 
     277           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "scatterWeightDensity",WHERE) );
     278             : 
     279           0 :     setupImagesOnDisk(); // To open up and initialize itsPartImages.
     280             : 
     281             :     //    os << "In ScatterModel : " << itsPartImages.nelements() << " for " << itsPartImageNames << LogIO::POST;
     282             : 
     283           0 :     if( itsPartImages.nelements() > 0 )
     284             :       {
     285           0 :         os << "Send the gridded weight from : " << itsImageName << " to all nodes :" << itsPartImageNames << LogIO::POST;
     286             :         
     287           0 :         for( uInt part=0;part<itsPartImages.nelements();part++)
     288             :           {
     289           0 :             itsPartImages[part]->setWeightDensity( itsImages );
     290           0 :             itsPartImages[part]->releaseLocks();
     291             :           }
     292           0 :         itsImages->releaseLocks();
     293             :       }
     294           0 :   }// end of gatherImages
     295             : 
     296             :   
     297             : 
     298           0 :   void SynthesisNormalizer::divideResidualByWeight()
     299             :   {
     300           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "divideResidualByWeight",WHERE) );
     301             : 
     302           0 :     if( itsNFacets==1) {
     303           0 :       itsImages->divideResidualByWeight( itsPBLimit, itsNormType );
     304             :     }
     305             :     else {
     306           0 :       for ( uInt facet=0; facet<itsNFacets*itsNFacets; facet++ )
     307           0 :         { itsFacetImageStores[facet]->divideResidualByWeight( itsPBLimit , itsNormType ); }
     308             :     }
     309           0 :     itsImages->releaseLocks();
     310             :     
     311           0 :   }
     312             :   
     313           0 :   void SynthesisNormalizer::divideResidualByWeightSD()
     314             :   {
     315           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "divideResidualByWeightSD",WHERE) );
     316             : 
     317           0 :     if( itsNFacets==1) {
     318           0 :       itsImages->divideResidualByWeightSD( itsPBLimit );
     319             :     }
     320             :     else {
     321           0 :       for ( uInt facet=0; facet<itsNFacets*itsNFacets; facet++ )
     322           0 :         { itsFacetImageStores[facet]->divideResidualByWeightSD( itsPBLimit ); }
     323             :     }
     324           0 :     itsImages->releaseLocks();
     325             : 
     326           0 :   }
     327           0 :   void SynthesisNormalizer::makePSFBeamset(){
     328           0 :     LogIO os(LogOrigin("SynthesisNormalizer", "dividePSFByWeight", WHERE));
     329             :     try{
     330           0 :       if(!itsImages){
     331           0 :         itsImages = makeImageStore( itsImageName, false );
     332             :       }
     333             : 
     334             :     }
     335           0 :     catch(AipsError& x){
     336             : 
     337           0 :       throw(AipsError("Programmers error no psf is made on disk and  trying to fit"));
     338           0 :     }
     339           0 :     itsImages->makeImageBeamSet(itsPsfcutoff);
     340           0 :     itsImages->releaseLocks();
     341           0 :   }
     342           0 :   void SynthesisNormalizer::dividePSFByWeight()
     343             :   {
     344           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "dividePSFByWeight",WHERE) );
     345             :     {
     346             :      
     347           0 :       LatticeLocker lock1 (*(itsImages->psf()), FileLocker::Write);
     348             :     
     349           0 :       if( itsNFacets==1) {
     350           0 :         itsImages->dividePSFByWeight(itsPBLimit);
     351             :       }
     352             :       else {
     353             :         // Since PSFs are normed just by their max, this sequence is OK.
     354           0 :         setPsfFromOneFacet();
     355           0 :         itsImages->dividePSFByWeight(itsPBLimit);
     356             :       }
     357           0 :     }// release of lock1 otherwise releaselock below will cause it to core
     358             :     //dump as the psf pointer goes dangling
     359             :       // Check PSF quality by fitting beams
     360             :     {
     361           0 :       itsImages->calcSensitivity();
     362             :     
     363           0 :       itsImages->makeImageBeamSet(itsPsfcutoff);
     364           0 :       Bool verbose(False);
     365           0 :       if (itsUseBeam=="common") verbose=True;
     366           0 :       itsImages->printBeamSet(verbose);
     367             :     }
     368           0 :     itsImages->releaseLocks();
     369             : 
     370           0 :   }
     371             : 
     372           0 :   void SynthesisNormalizer::normalizePrimaryBeam()
     373             :   {
     374           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "normalizePrimaryBeam",WHERE) );
     375             : 
     376           0 :     if( itsImages==NULL ) { itsImages = makeImageStore( itsImageName ); }
     377             : 
     378           0 :     gatherPB();
     379             : 
     380             :     // Irrespective of facets.
     381           0 :     itsImages->normalizePrimaryBeam(itsPBLimit);
     382           0 :   }
     383             : 
     384             : 
     385           0 :   void SynthesisNormalizer::divideModelByWeight()
     386             :   {
     387           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "divideModelByWeight",WHERE) );
     388           0 :     if( ! itsImages ) 
     389             :       {
     390             :         //os << LogIO::WARN << "No imagestore yet. Trying to construct, so that the starting model can be divided by wt if needed...." << LogIO::POST;
     391             :         
     392             :         try
     393             :           {
     394           0 :             itsImages = makeImageStore( itsImageName );
     395             :           }
     396           0 :         catch(AipsError &x)
     397             :           {
     398           0 :             throw(AipsError("Cannot construct ImageStore for "+itsImageName+". "+x.what()));
     399           0 :           }
     400             :         //      return;
     401             :       }
     402           0 :     if( itsNFacets==1) {
     403           0 :       itsImages->divideModelByWeight( itsPBLimit, itsNormType );
     404             :     }
     405             :     else {
     406           0 :       for ( uInt facet=0; facet<itsNFacets*itsNFacets; facet++ )
     407           0 :         { itsFacetImageStores[facet]->divideModelByWeight( itsPBLimit, itsNormType ); }
     408             :     }
     409           0 :  }
     410             : 
     411           0 :   void SynthesisNormalizer::multiplyModelByWeight()
     412             :   {
     413             :     //    LogIO os( LogOrigin("SynthesisNormalizer", "multiplyModelByWeight",WHERE) );
     414           0 :     if( itsNFacets==1) {
     415           0 :       itsImages->multiplyModelByWeight( itsPBLimit , itsNormType );
     416             :     }
     417             :     else {
     418           0 :       for ( uInt facet=0; facet<itsNFacets*itsNFacets; facet++ )
     419           0 :         { itsFacetImageStores[facet]->multiplyModelByWeight( itsPBLimit , itsNormType); }
     420             :     }
     421           0 :  }
     422             : 
     423             : 
     424           0 :   std::shared_ptr<SIImageStore> SynthesisNormalizer::getImageStore()
     425             :   {
     426           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "getImageStore", WHERE) );
     427           0 :     return itsImages;
     428           0 :   }
     429             : 
     430           0 :   void SynthesisNormalizer::setImageStore( SIImageStore* imstore )
     431             :   {
     432           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "setImageStore", WHERE) );
     433           0 :     itsImages.reset( imstore );
     434           0 :   }
     435             : 
     436           0 :   void SynthesisNormalizer::setImageStore( std::shared_ptr<SIImageStore>& imstore )
     437             :   {
     438           0 :     LogIO os( LogOrigin("SynthesisNormalizer", "setImageStore", WHERE) );
     439           0 :     itsImages= imstore ;
     440             :     
     441           0 :   }
     442             : 
     443             :   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     444             :   ////    Internal Functions start here.  These are not visible to the tool layer.
     445             :   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     446             : 
     447             : 
     448           0 :   Bool SynthesisNormalizer::setupImagesOnDisk() 
     449             :   {
     450           0 :     LogIO os( LogOrigin("SynthesisNormalizer","setupImagesOnDisk",WHERE) );
     451             : 
     452           0 :     Bool needToGatherImages=false;
     453             : 
     454           0 :     String err("");
     455             : 
     456             :     // Check if full images exist, and open them if possible.
     457           0 :     Bool foundFullImage=false;
     458             :     try
     459             :       {
     460           0 :         itsImages = makeImageStore( itsImageName );
     461           0 :         foundFullImage = true;
     462             :       }
     463           0 :     catch(AipsError &x)
     464             :       {
     465             :         //throw( AipsError("Error in constructing a Deconvolver : "+x.getMesg()) );
     466           0 :         err = err += String(x.getMesg()) + "\n";
     467           0 :         foundFullImage = false;
     468           0 :       }
     469             : 
     470           0 :     os << LogIO::DEBUG2 << " Found full images : " << foundFullImage << LogIO::POST;
     471             : 
     472             :     // Check if part images exist
     473           0 :     Bool foundPartImages = itsPartImageNames.nelements()>0 ? true : false ;
     474           0 :     itsPartImages.resize( itsPartImageNames.nelements() );
     475             : 
     476           0 :     for ( uInt part=0; part < itsPartImageNames.nelements() ; part++ )
     477             :       {
     478             :         try
     479             :           {
     480           0 :             itsPartImages[part] = makeImageStore ( itsPartImageNames[part] );
     481           0 :             foundPartImages |= true;
     482             :           }
     483           0 :         catch(AipsError &x)
     484             :           {
     485             :             //throw( AipsError("Error in constructing a Deconvolver : "+x.getMesg()) );
     486           0 :             err = err += String(x.getMesg()) + "\n";
     487           0 :             foundPartImages = false;
     488           0 :           }
     489             :       }
     490             : 
     491           0 :     os << LogIO::DEBUG2 << " Found part images : " << foundPartImages << LogIO::POST;
     492             : 
     493           0 :     if( foundPartImages == false) 
     494             :       { 
     495           0 :         if( foundFullImage == true && itsPartImageNames.nelements()>0 )
     496             :           {
     497             :             // Pick the coordsys, etc from fullImage, and construct new/fresh partial images. 
     498           0 :             os << LogIO::DEBUG2 << "Found full image, but no partial images. Make partImStores for : " << itsPartImageNames << LogIO::POST;
     499             :             
     500           0 :             String imopen = itsImages->getName()+".residual"+((itsMapperType=="multiterm")?".tt0":"");
     501           0 :             Directory imdir( imopen );
     502           0 :             if( ! imdir.exists() )
     503             :               {
     504           0 :                 imopen = itsImages->getName()+".psf"+((itsMapperType=="multiterm")?".tt0":"");
     505           0 :                 Directory imdir2( imopen );
     506           0 :                 if( ! imdir2.exists() )
     507           0 :                   throw(AipsError("Cannot find partial image psf or residual for  " +itsImages->getName() +err));
     508           0 :               }
     509             : 
     510           0 :             PagedImage<Float> temppart(imopen);
     511             : 
     512           0 :             Bool useweightimage = itsImages->getUseWeightImage( *(itsImages->sumwt()) );
     513           0 :             for( uInt part=0; part<itsPartImageNames.nelements(); part++ )
     514             :               {
     515           0 :                 itsPartImages[part] = makeImageStore (itsPartImageNames[part], temppart,
     516           0 :                                                       useweightimage);
     517             :               }
     518           0 :             foundPartImages = True;
     519           0 :           }
     520             :         else
     521             :           {
     522           0 :             itsPartImages.resize(0); 
     523           0 :             foundPartImages = False;
     524             :           }
     525             :       }
     526             :     else // Check that all have the same shape.
     527             :       {
     528           0 :         AlwaysAssert( itsPartImages.nelements() > 0 , AipsError );
     529           0 :         IPosition tempshape = itsPartImages[0]->getShape();
     530           0 :         for( uInt part=1; part<itsPartImages.nelements(); part++ )
     531             :           {
     532           0 :             if( tempshape != itsPartImages[part]->getShape() )
     533             :               {
     534           0 :                 throw( AipsError("Shapes of partial images to be combined, do not match" + err) );
     535             :               }
     536             :           }
     537           0 :       }
     538             : 
     539             : 
     540             :     // Make sure all images exist and are consistent with each other. At the end, itsImages should be valid
     541           0 :     if( foundPartImages == true ) // Partial Images exist. Check that 'full' exists, and do the gather. 
     542             :       {
     543           0 :         if ( foundFullImage == true ) // Full image exists. Just check that shapes match with parts.
     544             :           {
     545           0 :             os << LogIO::DEBUG2 << "Partial and Full images exist. Checking if part images have the same shape as the full image : ";
     546           0 :             IPosition fullshape = itsImages->getShape();
     547             :             
     548           0 :             for ( uInt part=0; part < itsPartImages.nelements() ; part++ )
     549             :               {
     550           0 :                 IPosition partshape = itsPartImages[part]->getShape();
     551           0 :                 if( partshape != fullshape )
     552             :                   {
     553           0 :                     os << LogIO::DEBUG2<< "NO" << LogIO::POST;
     554           0 :                     throw( AipsError("Shapes of the partial and full images on disk do not match. Cannot gather" + err) );
     555             :                   }
     556           0 :               }
     557           0 :             os << LogIO::DEBUG2 << "Yes" << LogIO::POST;
     558             : 
     559           0 :           }
     560             :         else // Full image does not exist. Need to make it, using the shape and coords of part[0]
     561             :           {
     562           0 :             os << LogIO::DEBUG2 << "Only partial images exist. Need to make full images" << LogIO::POST;
     563             : 
     564           0 :             AlwaysAssert( itsPartImages.nelements() > 0, AipsError );
     565             : 
     566             :             // Find an image to open and pick csys,shape from.
     567           0 :             String imopen = itsPartImageNames[0]+".residual"+((itsMapperType=="multiterm")?".tt0":"");
     568           0 :             Directory imdir( imopen );
     569           0 :             if( ! imdir.exists() )
     570             :               {
     571           0 :                 imopen = itsPartImageNames[0]+".psf"+((itsMapperType=="multiterm")?".tt0":"");
     572           0 :                 Directory imdir2( imopen );
     573           0 :                 if( ! imdir2.exists() )
     574             :                   {
     575           0 :                     imopen = itsPartImageNames[0]+".gridwt";
     576           0 :                     Directory imdir3( imopen );
     577           0 :                     if( ! imdir3.exists() )
     578           0 :                       throw(AipsError("Cannot find partial image psf or residual or gridwt for  " + itsPartImageNames[0]+err));
     579           0 :                   }
     580             : 
     581           0 :               }
     582             : 
     583           0 :             PagedImage<Float> temppart( imopen );
     584             : 
     585           0 :             Bool useweightimage = itsPartImages[0]->getUseWeightImage( *(itsPartImages[0]->sumwt()) );
     586           0 :             itsImages = makeImageStore (itsImageName, temppart, useweightimage);
     587           0 :             foundFullImage = true;
     588           0 :           }
     589             : 
     590             :         // By now, all partial images and the full images exist on disk, and have the same shape.
     591           0 :         needToGatherImages=true;
     592             : 
     593             :       }
     594             :     else // No partial images supplied. Operating only with full images.
     595             :       {
     596           0 :         if ( foundFullImage == true ) 
     597             :           {
     598           0 :             os << LogIO::DEBUG2 << "Full images exist : " << itsImageName << LogIO::POST;
     599             :           }
     600             :         else // No full image on disk either. Error.
     601             :           {
     602           0 :             throw( AipsError("No images named " + itsImageName + " found on disk. No partial images found either."+err) );
     603             :           }
     604             :       }
     605             : 
     606             :     // Remove ? 
     607           0 :     itsImages->psf();
     608           0 :     itsImages->validate();
     609             : 
     610             :     // Set up facet Imstores..... if needed
     611           0 :     if( itsNFacets>1 )
     612             :       {
     613             :         
     614             :         // First, make sure that full images have been allocated before trying to make references.....
     615             :         //        if( ! itsImages->checkValidity(true/*psf*/, true/*res*/,true/*wgt*/,true/*model*/,false/*image*/,false/*mask*/,true/*sumwt*/ ) ) 
     616             :         //          { throw(AipsError("Internal Error : Invalid ImageStore for " + itsImages->getName())); }
     617             : 
     618             :         //        Array<Float> ttt;
     619             :         //        (itsImages->sumwt())->get(ttt);
     620             :         //        cout << "SUMWT full : " << ttt <<  endl;
     621             :         
     622           0 :         itsFacetImageStores.resize( itsNFacets*itsNFacets );
     623           0 :         for( uInt facet=0; facet<itsNFacets*itsNFacets; ++facet )
     624             :           {
     625           0 :             itsFacetImageStores[facet] = itsImages->getSubImageStore(facet, itsNFacets);
     626             : 
     627             :             //Array<Float> qqq;
     628             :             //itsFacetImageStores[facet]->sumwt()->get(qqq);
     629             :             //            cout << "SUMWTs for " << facet << " : " << qqq << endl;
     630             : 
     631             :           }
     632             :       }
     633           0 :   os << LogIO::DEBUG2 << "Need to Gather ? " << needToGatherImages << LogIO::POST;
     634           0 :   itsImages->releaseLocks();
     635           0 :   return needToGatherImages;
     636           0 :   }// end of setupImagesOnDisk
     637             : 
     638             : 
     639           0 :   std::shared_ptr<SIImageStore> SynthesisNormalizer::makeImageStore(const String &imagename , const bool useweightimage)
     640             :   {
     641             :     //The constructors use ignoresumwt  so use the !useweightimage
     642           0 :     if( itsMapperType == "multiterm" )
     643           0 :       { return std::shared_ptr<SIImageStore>(new SIImageStoreMultiTerm( imagename, itsNTaylorTerms, true, !useweightimage ));   }
     644             :     else
     645           0 :       { return std::shared_ptr<SIImageStore>(new SIImageStore( imagename, true /*ignorefacets*/, !useweightimage ));   }
     646             :     itsImages->releaseLocks();
     647             :   }
     648             : 
     649             : 
     650             :  /**
     651             :   * build a new ImageStore, whether SIImageStore or SIImageStoreMultiTerm, borrowing
     652             :   * image information from one partial image.
     653             :   *
     654             :   * @param imagename image name for the new SIStorageManager
     655             :   * @param part partial image from which miscinfo, etc. data will be borrowed
     656             :   * @param useweightimage useweight option for the new SIStorageManager
     657             :   *
     658             :   * @return A new SIImageStore object for the image name given.
     659             :   */
     660           0 :   std::shared_ptr<SIImageStore> SynthesisNormalizer::makeImageStore(const String &imagename,
     661             :                                                                const PagedImage<Float> &part,
     662             :                                                                Bool useweightimage)
     663             :   {
     664             :     // borrow shape, coord, imageinfo and miscinfo
     665           0 :     auto shape = part.shape();
     666           0 :     auto csys = part.coordinates();
     667           0 :     auto objectname = part.imageInfo().objectName();
     668           0 :     auto miscinfo = part.miscInfo();
     669           0 :     if( itsMapperType == "multiterm" )
     670             :       {
     671             :         std::shared_ptr<SIImageStore> multiTermStore =
     672           0 :             std::make_shared<SIImageStoreMultiTerm>(imagename, csys, shape, objectname,
     673           0 :                                                     miscinfo, itsNFacets, false, itsNTaylorTerms, useweightimage );
     674           0 :         return multiTermStore;
     675           0 :       }
     676             :     else
     677             :       {
     678             :         return std::make_shared<SIImageStore>(imagename, csys, shape, objectname, miscinfo,
     679           0 :                                               false, useweightimage);
     680             :        }
     681           0 :   }
     682             : 
     683             :   //
     684             :   //---------------------------------------------------------------
     685             :   //
     686           0 :    void SynthesisNormalizer::setPsfFromOneFacet()
     687             :    {
     688             :        // Copy the PSF from one facet to the center of the full image, to use for the minor cycle
     689             :     //
     690             :     // This code segment will work for single and multi-term 
     691             :     // - for single term, the index will always be 0, and SIImageStore's access functions know this.
     692             :     // - for multi-term, the index will be the taylor index and SIImageStoreMultiTerm knows this.
     693             : 
     694             :      /// itsImages
     695             :      /// itsFacetImageStores
     696             : 
     697             :       {
     698           0 :         IPosition shape=(itsImages->psf(0))->shape();
     699           0 :         IPosition blc(4, 0, 0, 0, 0);
     700           0 :         IPosition trc=shape-1;
     701           0 :         for(uInt tix=0; tix<2 * itsImages->getNTaylorTerms() - 1; tix++)
     702             :           {
     703           0 :             TempImage<Float> onepsf((itsFacetImageStores[0]->psf(tix))->shape(), 
     704           0 :                                     (itsFacetImageStores[0]->psf(tix))->coordinates());
     705           0 :             onepsf.copyData(*(itsFacetImageStores[0]->psf(tix)));
     706             :             //now set the original to 0 as we have a copy of one facet psf
     707           0 :             (itsImages->psf(tix))->set(0.0);
     708           0 :             blc[0]=(shape[0]-(onepsf.shape()[0]))/2;
     709           0 :             trc[0]=onepsf.shape()[0]+blc[0]-1;
     710           0 :             blc[1]=(shape[1]-(onepsf.shape()[1]))/2;
     711           0 :             trc[1]=onepsf.shape()[1]+blc[1]-1;
     712           0 :             Slicer sl(blc, trc, Slicer::endIsLast);
     713           0 :             SubImage<Float> sub(*(itsImages->psf(tix)), sl, true);
     714           0 :             sub.copyData(onepsf);
     715           0 :           }
     716           0 :       }
     717             : 
     718             :       //      cout << "In setPsfFromOneFacet : sumwt : " << itsImages->sumwt()->get() << endl;
     719             :   
     720           0 :    }
     721             : 
     722             : 
     723             : 
     724             : } //# NAMESPACE CASA - END
     725             : 

Generated by: LCOV version 1.16