LCOV - code coverage report
Current view: top level - imageanalysis/ImageAnalysis - ImageTransposer.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 99 132 75.0 %
Date: 2024-12-11 20:54:31 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  * ImageReorderer.cc
       3             :  *
       4             :  *  Created on: May 7, 2010
       5             :  *      Author: dmehring
       6             :  */
       7             : 
       8             : #include <imageanalysis/ImageAnalysis/ImageTransposer.h>
       9             : 
      10             : #include <casacore/images/Images/ImageUtilities.h>
      11             : #include <casacore/images/Images/PagedImage.h>
      12             : #include <casacore/images/Images/TempImage.h>
      13             : 
      14             : #include <imageanalysis/ImageAnalysis/SubImageFactory.h>
      15             : 
      16             : using namespace casacore;
      17             : namespace casa {
      18             : 
      19             : const String ImageTransposer::_class = "ImageTransposer";
      20             : 
      21          19 : ImageTransposer::ImageTransposer(
      22             :         const SPCIIF image, const String& order, const String& outputImage
      23          19 : )
      24             :     : ImageTask<Float>(
      25             :         image, "", 0, "", "", "",
      26             :         "", outputImage, false
      27             :     ),
      28          19 :     _order(Vector<Int>(0)), _reverse(IPosition(0)) {
      29          38 :     LogOrigin origin(_class, String(__FUNCTION__) + "_1");
      30          19 :     *_getLog() << origin;
      31             :     //_construct();
      32          19 :     *_getLog() << origin;
      33          19 :     Regex intRegex("^(-?[0-9])+$");
      34          19 :     if (order.matches(intRegex)) {
      35          19 :         _order = _getOrder(order);
      36             :     }
      37             :     else {
      38           0 :         *_getLog() << "Incorrect order specification " << order
      39           0 :             << ". All characters must be digits." << LogIO::EXCEPTION;
      40             :     }
      41          31 : }
      42             : 
      43           9 : ImageTransposer::ImageTransposer(
      44             :         const SPCIIF image, const Vector<String> order,
      45             :     const String& outputImage
      46           9 : )
      47             : :  ImageTask<Float>(
      48             :         image, "", 0, "", "", "",
      49             :         "", outputImage, false
      50           9 :     ), _order(Vector<Int>()), _reverse(IPosition(0)) {
      51          18 :     LogOrigin origin(_class, String(__FUNCTION__) + "_2");
      52           9 :     *_getLog() << origin;
      53             :     //_construct();
      54           9 :     *_getLog() << origin;
      55           9 :     Vector<String> orderCopy = order;
      56           9 :     std::vector<Bool> rev(orderCopy.size());
      57           9 :     uInt nRev = 0;
      58             : 
      59          37 :     for (uInt i=0; i<orderCopy.size(); i++) {
      60          28 :         if (orderCopy[i].startsWith("-")) {
      61           0 :             orderCopy[i] = orderCopy[i].substr(1);
      62           0 :             rev[i] = true;
      63           0 :             nRev++;
      64             :         }
      65             :         else {
      66          28 :             rev[i] = false;
      67             :         }
      68             :     }
      69          13 :     _order = _getImage()->coordinates().getWorldAxesOrder(orderCopy, true);
      70           5 :     uInt n = 0;
      71           5 :     if (nRev > 0) {
      72           0 :         _reverse.resize(nRev);
      73           0 :         for (uInt i=0; i<orderCopy.size(); i++) {
      74           0 :             if (rev[i]) {
      75           0 :                 _reverse[n] = _order[i];
      76           0 :                 n++;
      77             :             }
      78             :         }
      79             :     }
      80           5 :     *_getLog() << "Old to new axis mapping is " << _order << LogIO::NORMAL;
      81          29 : }
      82             : 
      83           5 : ImageTransposer::ImageTransposer(
      84             :         const SPCIIF image, uInt order,
      85             :     const String& outputImage
      86           5 : )
      87             : :  ImageTask<Float>(
      88             :         image, "", 0, "", "", "",
      89             :         "", outputImage, false
      90           5 :     ), _order(Vector<Int>()), _reverse(IPosition(0)) {
      91          10 :     LogOrigin origin(_class, String(__FUNCTION__) + "_3");
      92           5 :     *_getLog() << origin;
      93             :     //_construct();
      94           5 :     *_getLog() << origin;
      95           5 :     _order = _getOrder(order);
      96          14 : }
      97             : 
      98          23 : SPIIF ImageTransposer::transpose() const {
      99          23 :     *_getLog() << LogOrigin(_class, __FUNCTION__);
     100             :     // get the image data
     101          23 :     Array<Float> dataCopy = _getImage()->get();
     102          23 :     CoordinateSystem newCsys = _getImage()->coordinates();
     103          23 :     IPosition shape = _getImage()->shape();
     104          23 :     if (_reverse.size() > 0) {
     105           0 :         Vector<Double> refPix = newCsys.referencePixel();
     106           0 :         Vector<Double> inc = newCsys.increment();
     107           0 :         for (
     108           0 :             IPosition::const_iterator iter=_reverse.begin();
     109           0 :             iter!=_reverse.end(); iter++
     110             :         ) {
     111           0 :             refPix[*iter] = shape[*iter] - 1 - refPix[*iter];
     112           0 :             inc[*iter] *= -1;
     113             :         }
     114           0 :         newCsys.setReferencePixel(refPix);
     115           0 :         newCsys.setIncrement(inc);
     116           0 :     }
     117          23 :     newCsys.transpose(_order, _order);
     118          23 :     IPosition newShape(_order.size());
     119         106 :     for (uInt i=0; i<newShape.size(); ++i) {
     120          83 :         newShape[i] = shape[_order[i]];
     121             :     }
     122             :     SPIIF output(
     123          23 :         new TempImage<Float>(TiledShape(newShape), newCsys)
     124          23 :     );
     125          23 :     if (_reverse.size() > 0) {
     126           0 :         dataCopy = reverseArray(dataCopy, _reverse);
     127             :     }
     128          23 :     output->put(reorderArray(dataCopy, _order));
     129          23 :     if (_getImage()->hasPixelMask()) {
     130             :         std::unique_ptr<Lattice<Bool> > maskLattice(
     131          12 :             _getImage()->pixelMask().clone()
     132          12 :         );
     133          12 :         Array<Bool> maskCopy = maskLattice->get();
     134          12 :         if (_reverse.size() > 0) {
     135           0 :             maskCopy = reverseArray(maskCopy, _reverse);
     136             :         }
     137          24 :         dynamic_cast<TempImage<Float> *>(output.get())->attachMask(
     138          24 :             ArrayLattice<Bool>(reorderArray(maskCopy, _order))
     139             :         );
     140          12 :     }
     141          23 :     ImageUtilities::copyMiscellaneous(*output, *this->_getImage());
     142          46 :     return this->_prepareOutputImage(*output);
     143          23 : }
     144             : 
     145          46 : ImageTransposer::~ImageTransposer() {}
     146             : 
     147          24 : Vector<Int> ImageTransposer::_getOrder(uInt order) const {
     148          24 :     *_getLog() << LogOrigin(_class, String(__func__));
     149          24 :     uInt naxes = _getImage()->ndim();
     150          24 :     uInt raxes = uInt(log10(order)) + 1;
     151          24 :     if (naxes != raxes) {
     152           7 :         istringstream is;
     153           7 :         is >> order;
     154           7 :         if (! String(is.str()).contains("0")) {
     155           7 :             raxes++;
     156             :         }
     157           7 :     }
     158          24 :     if (raxes != naxes) {
     159           6 :         *_getLog() << "Image has " << naxes << " axes but " << raxes
     160             :                 << " were given for reordering. Number of axes to reorder must match the number of image axes"
     161           2 :                 << LogIO::EXCEPTION;
     162             :     }
     163          22 :     if (raxes > 10) {
     164           0 :         *_getLog() << "Only images with less than 10 axes can currently be reordered. This image has "
     165           0 :                 << naxes << " axes" << LogIO::EXCEPTION;
     166             :     }
     167          22 :     Vector<Int> myorder(naxes);
     168          22 :     uInt mag = 1;
     169          79 :     for (uInt i=1; i<myorder.size(); i++) {
     170          57 :         mag *= 10;
     171             :     }
     172          22 :     uInt scratchOrder = order;
     173          97 :     for (uInt i=0; i<myorder.size(); i++) {
     174          79 :         uInt index = scratchOrder/mag;
     175          79 :         if (index >= naxes) {
     176           9 :             *_getLog() << "Image does not contain zero-based axis number " << index
     177             :                     << " but this was incorrectly specified in order parameter. "
     178             :                     << order << " All digits in the order parameter must be greater "
     179             :                     << "than or equal to zero and less than the number of image axes."
     180           3 :                     << LogIO::EXCEPTION;
     181             :         }
     182         173 :         for (uInt j=0; j<i; j++) {
     183          98 :             if ((Int)index == myorder[j]) {
     184           3 :                 *_getLog() << "Axis number " << index
     185             :                         << " specified multiple times in order parameter "
     186             :                         << order << " . It can only be specified once."
     187           1 :                         << LogIO::EXCEPTION;
     188             :             }
     189             :         }
     190          75 :         myorder[i] = index;
     191          75 :         scratchOrder -= index*mag;
     192          75 :         mag /= 10;
     193             :     }
     194          18 :     return myorder;
     195           4 : }
     196             : 
     197          19 : Vector<Int> ImageTransposer::_getOrder(const String& order) {
     198          19 :     String orderCopy = order;
     199          19 :     if (orderCopy.contains('-', 0)) {
     200           0 :         uInt maxn = orderCopy.freq('-') + 1;
     201           0 :         String *parts = new String[maxn];
     202           0 :         split(order, parts, maxn, '-');
     203             :         // disregard the first element because that won't have a -
     204           0 :         _reverse.resize(maxn - 1);
     205           0 :         orderCopy = parts[0];
     206           0 :         for (uInt i=1; i<maxn; i++) {
     207           0 :             _reverse[i-1] = String::toInt(parts[i].substr(0, 1));
     208           0 :             orderCopy += parts[i];
     209             :         }
     210           0 :         delete [] parts;
     211             : 
     212             :     }
     213          35 :     return _getOrder(String::toInt(orderCopy));
     214          19 : }
     215             : 
     216             : }

Generated by: LCOV version 1.16