LCOV - code coverage report
Current view: top level - imageanalysis/ImageAnalysis - SubImageFactory.tcc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 128 0.0 %
Date: 2024-12-11 20:54:31 Functions: 0 22 0.0 %

          Line data    Source code
       1             : //# Copyright (C) 1998,1999,2000,2001,2003
       2             : //# Associated Universities, Inc. Washington DC, USA.
       3             : //#
       4             : //# This library is free software; you can redistribute it and/or modify it
       5             : //# under the terms of the GNU Library General Public License as published by
       6             : //# the Free Software Foundation; either version 2 of the License, or (at your
       7             : //# option) any later version.
       8             : //#
       9             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      10             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      11             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      12             : //# License for more details.
      13             : //#
      14             : //# You should have received a copy of the GNU Library General Public License
      15             : //# along with this library; if not, write to the Free Software Foundation,
      16             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      17             : //#
      18             : //# Correspondence concerning AIPS++ should be addressed as follows:
      19             : //#        Internet email: casa-feedback@nrao.edu.
      20             : //#        Postal address: AIPS++ Project Office
      21             : //#                        National Radio Astronomy Observatory
      22             : //#                        520 Edgemont Road
      23             : //#                        Charlottesville, VA 22903-2475 USA
      24             : //#
      25             : 
      26             : #include <imageanalysis/ImageAnalysis/SubImageFactory.h>
      27             : 
      28             : #include <casacore/casa/BasicSL/String.h>
      29             : #include <casacore/tables/LogTables/NewFile.h>
      30             : #include <casacore/images/Images/ExtendImage.h>
      31             : #include <casacore/images/Images/ImageExpr.h>
      32             : #include <casacore/images/Images/ImageUtilities.h>
      33             : #include <casacore/images/Images/SubImage.h>
      34             : #include <casacore/images/Images/PagedImage.h>
      35             : #include <casacore/images/Regions/WCLELMask.h>
      36             : #include <casacore/lattices/LRegions/LCMask.h>
      37             : #include <casacore/lattices/Lattices/LatticeUtilities.h>
      38             : 
      39             : #include <imageanalysis/ImageAnalysis/ImageMask.h>
      40             : #include <imageanalysis/ImageAnalysis/ImageMaskAttacher.h>
      41             : #include <imageanalysis/ImageAnalysis/ImageMaskHandler.h>
      42             : 
      43             : // debug
      44             : #include <components/ComponentModels/C11Timer.h>
      45             : 
      46             : namespace casa {
      47             : 
      48           0 : template<class T> std::shared_ptr<casacore::SubImage<T> > SubImageFactory<T>::createSubImageRW(
      49             :     casacore::CountedPtr<casacore::ImageRegion>& outRegion, casacore::CountedPtr<casacore::ImageRegion>& outMask,
      50             :     casacore::ImageInterface<T>& inImage, const casacore::Record& region,
      51             :     const casacore::String& mask, casacore::LogIO *const &os,
      52             :     const casacore::AxesSpecifier& axesSpecifier,
      53             :     casacore::Bool extendMask, casacore::Bool preserveAxesOrder
      54             : ) {
      55           0 :     if (! mask.empty()) {
      56           0 :         _getMask(outMask, mask, extendMask, inImage.shape(), inImage.coordinates());
      57             :     }
      58           0 :     std::shared_ptr<casacore::SubImage<T> > subImage;
      59             :     // We can get away with no region processing if the region record
      60             :     // is empty and the user is not dropping degenerate axes
      61           0 :     if (region.nfields() == 0 && axesSpecifier.keep()) {
      62           0 :         subImage.reset(
      63           0 :             ! outMask
      64           0 :             ? new casacore::SubImage<T>(inImage, true, axesSpecifier, preserveAxesOrder)
      65           0 :             : new casacore::SubImage<T>(
      66           0 :                 inImage, *outMask,
      67             :                 true, axesSpecifier, preserveAxesOrder
      68             :             )
      69             :         );
      70             :     }
      71             :     else {
      72           0 :         outRegion = casacore::ImageRegion::fromRecord(
      73             :             os, inImage.coordinates(),
      74           0 :             inImage.shape(), region
      75             :         );
      76           0 :         if (! outMask) {
      77           0 :             subImage.reset(
      78           0 :                 new casacore::SubImage<T>(
      79           0 :                     inImage, *outRegion,
      80             :                     true, axesSpecifier,
      81             :                     preserveAxesOrder
      82             :                 )
      83             :             );
      84             :         }
      85             :         else {
      86             :             // on the first pass, we need to keep all axes, the second
      87             :             // casacore::SubImage construction after this one will properly account
      88             :             // for the axes specifier
      89           0 :             casacore::SubImage<T> subImage0(
      90           0 :                 inImage, *outMask, true,
      91           0 :                 casacore::AxesSpecifier(), preserveAxesOrder
      92             :             );
      93           0 :             subImage.reset(
      94           0 :                 new casacore::SubImage<T>(
      95           0 :                     subImage0, *outRegion,
      96             :                     true, axesSpecifier,
      97             :                     preserveAxesOrder
      98             :                 )
      99             :             );
     100           0 :         }
     101             :     }
     102           0 :     return subImage;
     103           0 : }
     104             : 
     105           0 : template<class T> std::shared_ptr<casacore::SubImage<T> > SubImageFactory<T>::createSubImageRW(
     106             :     casacore::ImageInterface<T>& inImage, const casacore::Record& region,
     107             :     const casacore::String& mask, casacore::LogIO *const &os,
     108             :     const casacore::AxesSpecifier& axesSpecifier,
     109             :     casacore::Bool extendMask, casacore::Bool preserveAxesOrder
     110             : ) {
     111           0 :     casacore::CountedPtr<casacore::ImageRegion> pRegion;
     112           0 :     casacore::CountedPtr<casacore::ImageRegion> pMask;
     113             :     return createSubImageRW(
     114             :         pRegion, pMask, inImage, region,
     115             :         mask, os, axesSpecifier,
     116             :         extendMask, preserveAxesOrder
     117           0 :     );
     118           0 : }
     119             : 
     120           0 : template<class T> std::shared_ptr<const casacore::SubImage<T> > SubImageFactory<T>::createSubImageRO(
     121             :     casacore::CountedPtr<casacore::ImageRegion>& outRegion, casacore::CountedPtr<casacore::ImageRegion>& outMask,
     122             :     const casacore::ImageInterface<T>& inImage, const casacore::Record& region,
     123             :     const casacore::String& mask, casacore::LogIO *const &os,
     124             :     const casacore::AxesSpecifier& axesSpecifier,
     125             :     casacore::Bool extendMask, casacore::Bool preserveAxesOrder
     126             : ) {
     127           0 :     if (! mask.empty()) {
     128           0 :         _getMask(outMask, mask, extendMask, inImage.shape(), inImage.coordinates());
     129             :     }
     130           0 :     std::shared_ptr<casacore::SubImage<T> > subImage;
     131             :     // We can get away with no region processing if the region record
     132             :     // is empty and the user is not dropping degenerate axes
     133           0 :     if (region.nfields() == 0 && axesSpecifier.keep()) {
     134           0 :         subImage.reset(
     135           0 :             ! outMask
     136           0 :             ? new casacore::SubImage<T>(inImage, axesSpecifier, preserveAxesOrder)
     137           0 :             : new casacore::SubImage<T>(
     138           0 :                 inImage, *outMask,
     139             :                 axesSpecifier, preserveAxesOrder
     140             :             )
     141             :         );
     142             :     }
     143             :     else {
     144           0 :         outRegion = casacore::ImageRegion::fromRecord(
     145             :             os, inImage.coordinates(),
     146           0 :             inImage.shape(), region
     147             :         );
     148           0 :         if (! outMask) {
     149           0 :             subImage.reset(
     150           0 :                 new casacore::SubImage<T>(
     151           0 :                     inImage, *outRegion,
     152             :                     axesSpecifier,
     153             :                     preserveAxesOrder
     154             :                 )
     155             :             );
     156             :         }
     157             :         else {
     158             :             // on the first pass, we need to keep all axes, the second
     159             :             // casacore::SubImage construction after this one will properly account
     160             :             // for the axes specifier
     161           0 :             casacore::SubImage<T> subImage0(
     162           0 :                 inImage, *outMask,
     163           0 :                 casacore::AxesSpecifier(),
     164             :                 preserveAxesOrder
     165             :             );
     166           0 :             subImage.reset(
     167           0 :                 new casacore::SubImage<T>(
     168           0 :                     subImage0, *outRegion,
     169             :                     axesSpecifier,
     170             :                     preserveAxesOrder
     171             :                 )
     172             :             );
     173           0 :         }
     174             :     }
     175           0 :     return subImage;
     176           0 : }
     177             : 
     178           0 : template<class T> std::shared_ptr<const casacore::SubImage<T> > SubImageFactory<T>::createSubImageRO(
     179             :     const casacore::ImageInterface<T>& inImage, const casacore::Record& region,
     180             :     const casacore::String& mask, casacore::LogIO *const &os,
     181             :     const casacore::AxesSpecifier& axesSpecifier,
     182             :     casacore::Bool extendMask, casacore::Bool preserveAxesOrder
     183             : ) {
     184           0 :     casacore::CountedPtr<casacore::ImageRegion> pRegion;
     185           0 :     casacore::CountedPtr<casacore::ImageRegion> pMask;
     186             :     return createSubImageRO(
     187             :         pRegion, pMask, inImage, region,
     188             :         mask, os, axesSpecifier,
     189             :         extendMask, preserveAxesOrder
     190           0 :     );
     191           0 : }
     192             : 
     193           0 : template<class T> SPIIT SubImageFactory<T>::createImage(
     194             :     const casacore::ImageInterface<T>& image,
     195             :     const casacore::String& outfile, const casacore::Record& region,
     196             :     const casacore::String& mask, casacore::Bool dropDegenerateAxes,
     197             :     casacore::Bool overwrite, casacore::Bool list, casacore::Bool extendMask, casacore::Bool attachMask,
     198             :     const casacore::Lattice<T> *const data
     199             : ) {
     200             :     return createImage(
     201           0 :         image, outfile, region, mask, casacore::AxesSpecifier(! dropDegenerateAxes),
     202             :         overwrite, list, extendMask, attachMask, data
     203           0 :     );
     204             : }
     205             : 
     206           0 : template<class T> SPIIT SubImageFactory<T>::createImage(
     207             :     const casacore::ImageInterface<T>& image,
     208             :     const casacore::String& outfile, const casacore::Record& region,
     209             :     const casacore::String& mask, const casacore::AxesSpecifier& axesSpec,
     210             :     casacore::Bool overwrite, casacore::Bool list, casacore::Bool extendMask, casacore::Bool attachMask,
     211             :     const casacore::Lattice<T> *const data
     212             : ) {
     213           0 :     casacore::LogIO log;
     214           0 :     log << casacore::LogOrigin("SubImageFactory", __func__);
     215             :     // Copy a portion of the image
     216             :     // Verify output file
     217           0 :     if (! overwrite && ! outfile.empty()) {
     218           0 :         casacore::NewFile validfile;
     219           0 :         casacore::String errmsg;
     220           0 :         if(! validfile.valueOK(outfile, errmsg)) {
     221             :             // CAS-8715 users want a nicer error message in this case
     222           0 :             if (casacore::File(outfile).exists()) {
     223           0 :                 errmsg = outfile + " already exists";
     224             :             }
     225           0 :             ThrowCc(errmsg);
     226             :         }
     227           0 :     }
     228           0 :     std::shared_ptr<const casacore::SubImage<T> > x = createSubImageRO(
     229           0 :         image, region, mask, list ? &log : 0,
     230             :         axesSpec, extendMask, true
     231             :     );
     232           0 :     SPIIT outImage;
     233           0 :     if (outfile.empty()) {
     234           0 :         outImage.reset(
     235           0 :             new casacore::TempImage<T>(x->shape(), x->coordinates())
     236             :         );
     237             :     }
     238             :     else {
     239           0 :         outImage.reset(
     240           0 :             new casacore::PagedImage<T>(
     241           0 :                 x->shape(), x->coordinates(), outfile
     242             :             )
     243             :         );
     244           0 :         if (list) {
     245             :             log << casacore::LogIO::NORMAL << "Creating image '" << outfile
     246           0 :                 << "' of shape " << outImage->shape() << casacore::LogIO::POST;
     247             :         }
     248             :     }
     249           0 :     casacore::ImageUtilities::copyMiscellaneous(*outImage, *x);
     250           0 :     if (attachMask || ! ImageMask::isAllMaskTrue(*x)) {
     251             :         // if we don't already have a mask, but the user has specified that one needs to
     252             :         // be present, attach it. This needs to be done prior to the copyDataAndMask() call
     253             :         // because in that implementation, the image to which the mask is to be copied must
     254             :         // have already have a mask; that call does not create one if it does not exist.
     255           0 :         casacore::String maskName = "";
     256           0 :         ImageMaskAttacher::makeMask(*outImage, maskName, false, true, log, list);
     257           0 :         if (data) {
     258           0 :             ImageMaskHandler<T> imh(outImage);
     259           0 :             imh.copy(*x);
     260           0 :         }
     261           0 :     }
     262           0 :     if (data) {
     263           0 :         outImage->copyData(*data);
     264             :     }
     265             :     else {
     266           0 :         casacore::LatticeUtilities::copyDataAndMask(log, *outImage, *x);
     267             :     }
     268           0 :     outImage->flush();
     269           0 :     return outImage;
     270           0 : }
     271             : 
     272           0 : template<class T> void SubImageFactory<T>::_getMask(
     273             :     casacore::CountedPtr<casacore::ImageRegion>& outMask, const casacore::String& mask,
     274             :     casacore::Bool extendMask, const casacore::IPosition& imageShape,
     275             :     const casacore::CoordinateSystem& csys
     276             : ) {
     277           0 :     casacore::String mymask = mask;
     278           0 :     for (casacore::uInt i=0; i<2; i++) {
     279             :         try {
     280           0 :             outMask = casacore::ImageRegion::fromLatticeExpression(mymask);
     281           0 :             break;
     282             :         }
     283           0 :         catch (const casacore::AipsError& x) {
     284           0 :             if (i == 0) {
     285             :                 // not an LEL expression, perhaps it's a clean mask image name
     286           0 :                 mymask += ">=0.5";
     287           0 :                 continue;
     288             :             }
     289           0 :             ThrowCc("Input mask specification is incorrect: " + x.getMesg());
     290             :         }
     291             :     }
     292           0 :     if (outMask && outMask->asWCRegion().type() == "WCLELMask") {
     293           0 :         const casacore::ImageExpr<casacore::Bool> *myExpression = dynamic_cast<const casacore::WCLELMask*>(
     294           0 :             outMask->asWCRegionPtr()
     295           0 :         )->getImageExpr();
     296           0 :         if (
     297             :                 myExpression
     298           0 :                 && ! myExpression->shape().isEqual(imageShape)
     299             :         ) {
     300           0 :             if (! extendMask) {
     301           0 :                 ostringstream os;
     302           0 :                 os << "The input image shape (" << imageShape << ") and mask shape ("
     303           0 :                     << myExpression->shape() << ") are different, and it was specified "
     304             :                     "that the mask should not be extended, so the mask cannot be applied to the "
     305             :                     "(sub)image. Specifying that the mask should be extended may resolve the issue";
     306           0 :                 ThrowCc(os.str());
     307           0 :             }
     308             :             try {
     309           0 :                 casacore::ExtendImage<casacore::Bool> exIm(*myExpression, imageShape, csys);
     310           0 :                 outMask = new casacore::ImageRegion(casacore::LCMask(exIm));
     311           0 :             }
     312           0 :             catch ( const std::exception &x ) {
     313           0 :                 ThrowCc( String("Unable to extend mask: ") + x.what() );
     314             :             }
     315             :         }
     316             :     }
     317           0 : }
     318             : 
     319             : }

Generated by: LCOV version 1.16