LCOV - code coverage report
Current view: top level - imageanalysis/ImageAnalysis - ImageFactory.tcc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 31 71 43.7 %
Date: 2024-11-06 17:42:47 Functions: 2 12 16.7 %

          Line data    Source code
       1             : //# tSubImage.cc: Test program for class SubImage
       2             : //# Copyright (C) 1998,1999,2000,2001,2003
       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 <imageanalysis/ImageAnalysis/ImageFactory.h>
      29             : 
      30             : #include <casacore/casa/OS/Directory.h>
      31             : #include <casacore/casa/OS/RegularFile.h>
      32             : #include <casacore/casa/OS/SymLink.h>
      33             : #include <casacore/coordinates/Coordinates/CoordinateUtil.h>
      34             : #include <casacore/images/Images/PagedImage.h>
      35             : #include <casacore/images/Images/TempImage.h>
      36             : #include <casacore/tables/LogTables/NewFile.h>
      37             : #include <casacore/tables/Tables/TableUtil.h>
      38             : 
      39             : #include <imageanalysis/ImageAnalysis/ImageHistory.h>
      40             : #include <imageanalysis/ImageAnalysis/SubImageFactory.h>
      41             : 
      42             : namespace casa {
      43             : 
      44             : template <class T> void ImageFactory::remove(SPIIT& image, casacore::Bool verbose) {
      45             :         ThrowIf(
      46             :                 ! image, "Image cannot be null"
      47             :         );
      48             :         ThrowIf(
      49             :                 ! image->isPersistent(),
      50             :                 "This image tool is not associated with a "
      51             :                 "persistent disk file. It cannot be deleted"
      52             :         );
      53             :         auto fileName = image->name(false);
      54             :         ThrowIf(
      55             :                 fileName.empty(),
      56             :                 "Filename is empty or does not exist."
      57             :     );
      58             :         casacore::File f(fileName);
      59             :         ThrowIf(
      60             :                 ! f.exists(),
      61             :                 fileName + " does not exist."
      62             :         );
      63             : 
      64             :         // Destroy object before deleting image. This is why a reference
      65             :         // needs to be passed in.
      66             :         image.reset();
      67             : 
      68             :         // Now try and blow it away.  If it's open, tabledelete won't delete it.
      69             :         casacore::String message;
      70             :         casacore::LogIO log;
      71             :         if (casacore::TableUtil::canDeleteTable(message, fileName, true)) {
      72             :                 try {
      73             :                         casacore::TableUtil::deleteTable(fileName, true);
      74             :                         log << (verbose ? casacore::LogIO::NORMAL : casacore::LogIO::DEBUG1)
      75             :                 << "deleted table " << fileName << casacore::LogIO::POST;
      76             :                 }
      77             :                 catch (const casacore::AipsError& x) {
      78             :                         ThrowCc(
      79             :                                 "Failed to delete file " + fileName
      80             :                                 + " because " + x.getMesg()
      81             :                         );
      82             :                 };
      83             :         }
      84             :         else {
      85             :                 ThrowCc(
      86             :                         "Cannot delete file " + fileName
      87             :             + " because " + message
      88             :                 );
      89             :         }
      90             : }
      91             : 
      92             : template<class T>
      93             : std::shared_ptr<TempImage<std::complex<T>>> ImageFactory::makeComplexImage(
      94             :     SPCIIT realPart, SPCIIT imagPart
      95             : ) {
      96             :     auto shape = realPart->shape();
      97             :     ThrowIf(
      98             :         shape != imagPart->shape(),
      99             :         "Real and imaginary parts have different shapes"
     100             :     );
     101             :     std::shared_ptr<TempImage<std::complex<T>>> newImage(
     102             :         new TempImage<std::complex<T>>(shape, realPart->coordinates())
     103             :     );
     104             :     LatticeExpr<std::complex<T>> expr(
     105             :         casacore::formComplex(*realPart, *imagPart)
     106             :     );
     107             :     if (ImageMask::isAllMaskTrue(expr)) {
     108             :         newImage->copyData(expr);
     109             :     }
     110             :     else {
     111             :         newImage->attachMask(casacore::ArrayLattice<Bool>(shape));
     112             :         LogIO os;
     113             :         casacore::LatticeUtilities::copyDataAndMask(os, *newImage, expr, False);
     114             :     }
     115             :     ImageUtilities::copyMiscellaneous(*newImage, *realPart);
     116             :     return newImage;
     117             : }
     118             : 
     119             : template <class T>
     120             : std::shared_ptr<casacore::ImageInterface<std::complex<T>>> ImageFactory::makeComplex(
     121             :     SPCIIT realPart, SPCIIT imagPart, const String& outfile,
     122             :     const Record& region, Bool overwrite
     123             : ) {
     124             :     _checkOutfile(outfile, overwrite);
     125             :     const IPosition realShape = realPart->shape();
     126             :     const IPosition imagShape = imagPart->shape();
     127             :     ThrowIf(! realShape.isEqual(imagShape), "Image shapes are not identical");
     128             :     const auto& cSysReal = realPart->coordinates();
     129             :     const auto& cSysImag = imagPart->coordinates();
     130             :     ThrowIf(
     131             :         !cSysReal.near(cSysImag), "Image Coordinate systems are not conformant"
     132             :     );
     133             :     String mask;
     134             :     auto subRealImage = SubImageFactory<T>::createSubImageRO(
     135             :         *realPart, region, mask, nullptr
     136             :     );
     137             :     auto subImagImage = SubImageFactory<T>::createSubImageRO(
     138             :         *imagPart, region, mask, nullptr
     139             :     );
     140             :     auto complexImage = makeComplexImage(
     141             :         std::dynamic_pointer_cast<const casacore::ImageInterface<T>>(subRealImage),
     142             :         std::dynamic_pointer_cast<const casacore::ImageInterface<T>>(subImagImage)
     143             :     );
     144             :     return SubImageFactory<std::complex<T>>::createImage(
     145             :         *complexImage, outfile, Record(), "", AxesSpecifier(),
     146             :         overwrite, false, false
     147             :     );
     148             : }
     149             : 
     150           0 : template <class T> SPIIT ImageFactory::createImage(
     151             :     const casacore::String& outfile,
     152             :     const casacore::CoordinateSystem& cSys, const casacore::IPosition& shape,
     153             :     casacore::Bool log, casacore::Bool overwrite,
     154             :     const vector<std::pair<casacore::LogOrigin, casacore::String> > *const &msgs
     155             : ) {
     156           0 :     _checkOutfile(outfile, overwrite);
     157           0 :     ThrowIf(
     158             :         shape.nelements() != cSys.nPixelAxes(),
     159             :         "Supplied CoordinateSystem and image shape are inconsistent"
     160             :     );
     161           0 :     SPIIT image;
     162           0 :     if (outfile.empty()) {
     163           0 :         image.reset(new casacore::TempImage<T>(shape, cSys));
     164           0 :         ThrowIf(! image, "Failed to create TempImage");
     165             :     }
     166             :     else {
     167           0 :         image.reset(new casacore::PagedImage<T>(shape, cSys, outfile));
     168           0 :         ThrowIf(
     169             :             ! image,
     170             :             "Failed to create PagedImage"
     171             :         );
     172             :     }
     173           0 :     auto creationMsg = _imageCreationMessage(outfile, shape, whatType<T>());
     174           0 :     ImageHistory<T> hist(image);
     175           0 :     if (msgs) {
     176           0 :         hist.addHistory(*msgs);
     177             :     }
     178           0 :     LogOrigin lor("ImageFactory", __func__);
     179           0 :     hist.addHistory(lor, creationMsg);
     180           0 :     image->set(0.0);
     181           0 :     if (log) {
     182           0 :         LogIO mylog;
     183           0 :         mylog << LogOrigin("ImageFactory", __func__)
     184           0 :             << LogIO::NORMAL << creationMsg << LogIO::POST;
     185           0 :     }
     186           0 :     return image;
     187           0 : }
     188             : 
     189             : template<class T>
     190             : std::shared_ptr<casacore::TempImage<T>> ImageFactory::floatFromComplex(
     191             :     std::shared_ptr<const casacore::ImageInterface<std::complex<T>>> complexImage,
     192             :     ComplexToFloatFunction function
     193             : ) {
     194             :     std::shared_ptr<TempImage<T>> newImage(
     195             :         new TempImage<T>(
     196             :             TiledShape(complexImage->shape()),
     197             :             complexImage->coordinates()
     198             :         )
     199             :     );
     200             :     {
     201             :         // FIXME use lattice copies
     202             :         auto mymask = complexImage->getMask();
     203             :         if (complexImage->hasPixelMask()) {
     204             :             mymask = mymask && complexImage->pixelMask().get();
     205             :         }
     206             :         if (! allTrue(mymask)) {
     207             :             newImage->attachMask(ArrayLattice<Bool>(mymask));
     208             :         }
     209             :     }
     210             :     ImageUtilities::copyMiscellaneous(*newImage, *complexImage);
     211             :     switch (function) {
     212             :     case REAL:
     213             :         // FIXME use lattice copies
     214             :         newImage->put(real(complexImage->get()));
     215             :         break;
     216             :     case IMAG:
     217             :         // FIXME use lattice copies
     218             :         newImage->put(imag(complexImage->get()));
     219             :         break;
     220             :     default:
     221             :         ThrowCc("Logic Error: Unhandled function");
     222             :     }
     223             :     return newImage;
     224             : }
     225             : 
     226           0 : template <class T> SPIIT ImageFactory::fromShape(
     227             :         const casacore::String& outfile,
     228             :         const casacore::Vector<casacore::Int>& shapeV,
     229             :         const casacore::Record& coordinates, casacore::Bool linear,
     230             :         casacore::Bool overwrite, casacore::Bool verbose,
     231             :     const vector<std::pair<casacore::LogOrigin, casacore::String> > *const &msgs
     232             : ) {
     233           0 :         ThrowIf(
     234             :                 shapeV.nelements() == 0, "The shape must have more than zero elements"
     235             :         );
     236           0 :         ThrowIf(anyTrue(shapeV <= 0), "All elements of shape must be positive");
     237           0 :     casacore::CoordinateSystem mycsys;
     238           0 :         std::unique_ptr<casacore::CoordinateSystem> csysPtr;
     239           0 :         if (coordinates.empty()) {
     240           0 :                 mycsys = casacore::CoordinateUtil::makeCoordinateSystem(shapeV, linear);
     241           0 :                 _centerRefPix(mycsys, shapeV);
     242             :         }
     243             :         else {
     244           0 :                 csysPtr.reset(_makeCoordinateSystem(coordinates, shapeV));
     245           0 :         mycsys = *csysPtr;
     246             :         }
     247           0 :         return createImage<T>(outfile, mycsys, shapeV, verbose, overwrite, msgs);
     248           0 : }
     249             : 
     250             : template <class T> SPIIT ImageFactory::imageFromArray(
     251             :     const casacore::String& outfile, const casacore::Array<T>& pixels,
     252             :     const casacore::Record& csys, casacore::Bool linear,
     253             :     casacore::Bool overwrite, casacore::Bool verbose,
     254             :     const vector<std::pair<casacore::LogOrigin, casacore::String> > *const &msgs
     255             : ) {
     256             :         SPIIT myim = fromShape<T>(
     257             :                 outfile, pixels.shape().asVector(),
     258             :                 csys, linear, overwrite, verbose, msgs
     259             :         );
     260             :         myim->put(pixels);
     261             :         return myim;
     262             : }
     263             : 
     264          21 : template <class T> SPIIT ImageFactory::_fromRecord(
     265             :     const casacore::RecordInterface& rec, const casacore::String& name
     266             : ) {
     267          21 :     SPIIT image;
     268          21 :     casacore::String err;
     269          21 :     image.reset(new casacore::TempImage<T>());
     270          21 :     ThrowIf(
     271             :         ! image->fromRecord(err, rec),
     272             :         "Error converting image from record: " + err
     273             :     );
     274          20 :     if (! name.empty()) {
     275          60 :         image = SubImageFactory<T>::createImage(
     276          40 :             *image, name, casacore::Record(), "", false,
     277             :             true, false, false
     278             :         );
     279             :     }
     280          40 :     return image;
     281          22 : }
     282             : 
     283          19 : template <class T> ITUPLE ImageFactory::_rename(
     284             :         SPIIT& image, const casacore::String& name,
     285             :         const casacore::Bool overwrite
     286             : ) {
     287          19 :         casacore::LogIO mylog;
     288          19 :         mylog << casacore::LogOrigin(className(), __func__);
     289          19 :         ThrowIf (! image, "Image pointer cannot be null");
     290          19 :         ThrowIf(
     291             :                 ! image->isPersistent(),
     292             :                 "This image tool is not associated with a "
     293             :                 "persistent disk file. It cannot be renamed"
     294             :         );
     295          19 :         ThrowIf(
     296             :                 name.empty(), "new file name must be specified"
     297             :         );
     298          19 :         casacore::String oldName = image->name(false);
     299          19 :         ThrowIf(
     300             :                 oldName.empty(),
     301             :                 "Current file name is empty, cannot rename"
     302             :         );
     303          19 :         ThrowIf(
     304             :                 oldName == name,
     305             :                 "Specified output name is the same as the current image name"
     306             :         );
     307             :         // Let's see if it exists.  If it doesn't, then the user has deleted it
     308          19 :         casacore::File file(oldName);
     309          19 :         if (file.isSymLink()) {
     310           0 :                 file = casacore::File(casacore::SymLink(file).followSymLink());
     311             :         }
     312          19 :         ThrowIf(
     313             :                 ! file.exists(), "The image to be renamed no longer exists"
     314             :         );
     315          19 :         _checkOutfile(name, overwrite);
     316             :         // close image before renaming
     317          19 :         image.reset();
     318             :         // Now try and move it
     319          19 :         casacore::Bool follow(true);
     320          19 :         if (file.isRegular(follow)) {
     321           0 :                 casacore::RegularFile(file).move(name, overwrite);
     322             :         }
     323          19 :         else if (file.isDirectory(follow)) {
     324          19 :                 casacore::Directory(file).move(name, overwrite);
     325             :         }
     326           0 :         else if (file.isSymLink()) {
     327           0 :                 casacore::SymLink(file).copy(name, overwrite);
     328             :         }
     329             :         else {
     330           0 :                 ThrowCc("Failed to rename file " + oldName + " to " + name);
     331             :         }
     332             :         mylog << casacore::LogIO::NORMAL << "Successfully renamed file " << oldName
     333          19 :             << " to " << name << casacore::LogIO::POST;
     334          38 :         return fromFile(name);
     335             : 
     336          19 : }
     337             : 
     338             : 
     339             : }
     340             : 

Generated by: LCOV version 1.16