LCOV - code coverage report
Current view: top level - imageanalysis/Annotations - RegionTextList.cc (source / functions) Hit Total Coverage
Test: casa_coverage.info Lines: 64 104 61.5 %
Date: 2023-10-25 08:47:59 Functions: 6 11 54.5 %

          Line data    Source code
       1             : //# AsciiRegionFile.cc
       2             : //# Copyright (C) 1998,1999,2000,2001
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library 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 Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: aips2-request@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             : 
      27             : #include <imageanalysis/Annotations/RegionTextList.h>
      28             : 
      29             : #include <casacore/casa/OS/File.h>
      30             : #include <imageanalysis/Annotations/AnnRegion.h>
      31             : #include <casacore/images/Regions/WCDifference.h>
      32             : #include <casacore/casa/BasicSL/STLIO.h>
      33             : 
      34             : using namespace casacore;
      35             : namespace casa {
      36             : 
      37           0 : RegionTextList::RegionTextList() {}
      38             : 
      39             : 
      40           0 : RegionTextList::RegionTextList(
      41             :     const CoordinateSystem& csys,
      42             :     const IPosition shape
      43           0 : ) : _csys(csys), _shape(shape), _canGetRegion(true) {}
      44             : 
      45          34 : RegionTextList::RegionTextList(
      46             :     const String& filename, const CoordinateSystem& csys,
      47             :     const IPosition shape,
      48             :     const String& prependRegion, const String& globalOverrideChans, const String& globalOverrrideStokes,
      49             :     const Int requireAtLeastThisVersion, Bool verbose, Bool requireImageRegion
      50          69 : ) : _csys(csys), _shape(shape), _canGetRegion(true) {
      51             :     RegionTextParser parser(
      52             :         filename, csys, shape, requireAtLeastThisVersion,
      53             :         prependRegion,
      54             :         globalOverrideChans, globalOverrrideStokes,
      55             :         verbose, requireImageRegion
      56          63 :     );
      57          58 :     const auto lines = parser.getLines();
      58         186 :     for (const auto& line: lines) {
      59         157 :         addLine(line);
      60             :     }
      61          29 : }
      62             : 
      63          39 : RegionTextList::RegionTextList(
      64             :     const CoordinateSystem& csys, const String& text,
      65             :     const IPosition shape, const String& prependRegion,
      66             :     const String& globalOverrideChans, const String& globalOverrrideStokes,
      67             :     Bool verbose, Bool requireImageRegion
      68          46 : ) : _csys(csys), _shape(shape), _canGetRegion(true) {
      69             :     RegionTextParser parser(
      70             :         csys, shape, text, prependRegion, globalOverrideChans,
      71             :         globalOverrrideStokes, verbose, requireImageRegion
      72          77 :     );
      73          76 :     const auto lines = parser.getLines();
      74          78 :     for (const auto& line: lines) {
      75          40 :         addLine(line);
      76             :     }
      77          38 : }
      78             : 
      79          67 : RegionTextList::~RegionTextList() {}
      80             : 
      81         197 : void RegionTextList::addLine(const AsciiAnnotationFileLine& line) {
      82         394 :     const auto x = line;
      83         197 :     _lines.resize(_lines.size()+1, true);
      84         197 :     _lines[_lines.size()-1] = x;
      85         197 :     if (x.getType() == AsciiAnnotationFileLine::ANNOTATION && _canGetRegion) {
      86         276 :         const auto annotation = x.getAnnotationBase();
      87         138 :         if (annotation->isRegion()) {
      88         138 :             const auto *region = dynamic_cast<const AnnRegion *>(annotation.get());
      89         138 :             if (! region->isAnnotationOnly()) {
      90         138 :                 auto wcregion = region->getRegion2();
      91         138 :                 if (region->isDifference() && _regions.size() == 0) {
      92           0 :                     Vector<Double> blc, trc;
      93           0 :                     _csys.toWorld(blc, IPosition(_csys.nPixelAxes(), 0));
      94           0 :                     _csys.toWorld(trc, _shape);
      95           0 :                     Vector<Quantity> qblc(blc.size()), qtrc(trc.size());
      96           0 :                     const auto wUnits = _csys.worldAxisUnits();
      97           0 :                     Vector<Int> absRel(blc.size(), RegionType::Abs);
      98           0 :                     for (uInt i=0; i<qblc.size(); i++) {
      99           0 :                         qblc[i] = Quantity(blc[i], wUnits[i]);
     100           0 :                         qtrc[i] = Quantity(blc[i], wUnits[i]);
     101             :                     }
     102           0 :                     _regions.push_back(
     103           0 :                         std::shared_ptr<const WCRegion>(
     104           0 :                             new WCBox(qblc, qtrc, _csys, absRel)
     105             :                         )
     106             :                     );
     107           0 :                     _union.push_back(true);
     108             :                 }
     109         138 :                 _regions.push_back(wcregion);
     110         138 :                 _union.push_back(! region->isDifference());
     111         138 :                 _composite = NULL;
     112             :             }
     113             :         }
     114             :     }
     115         197 : }
     116             : 
     117          67 : Record RegionTextList::regionAsRecord() const {
     118          67 :     ThrowIf(_regions.size() == 0, "No regions found");
     119          67 :     return getRegion()->toRecord("");
     120             : }
     121             : 
     122          67 : CountedPtr<const WCRegion> RegionTextList::getRegion() const {
     123          67 :     if (_composite) {
     124           0 :         return _composite;
     125             :     }
     126          67 :     ThrowIf(
     127             :         ! _canGetRegion,
     128             :         "Object constructed with too little information "
     129             :         "for forming composite region. Use another constructor."
     130             :     );
     131          67 :     if (_regions.size() == 0) {
     132           0 :         return nullptr;
     133             :     }
     134          67 :     if (_regions.size() == 1) {
     135          47 :         _composite = _regions[0];
     136          47 :         return _composite;
     137             :     }
     138          20 :     const auto end = _union.cend();
     139          20 :     const auto foundDifference = std::find(_union.cbegin(), end, false) != end;
     140          40 :     PtrBlock<const WCRegion *> unionRegions;
     141          20 :     if (! foundDifference) {
     142             :         // no complementary regions, just union the whole lot
     143          19 :         unionRegions.resize(_regions.size());
     144         108 :         for (uInt i=0; i<_regions.size(); ++i) {
     145          89 :             unionRegions[i] = _regions[i].get();
     146             :         }
     147          19 :         _composite.reset(new WCUnion(false, unionRegions));
     148          19 :         return _composite;
     149             :     }
     150           1 :     uInt count = 0;
     151           3 :     for (const auto isUnion: _union) {
     152           2 :         if (isUnion) {
     153           1 :             auto newSize = unionRegions.size() + 1;
     154           1 :             unionRegions.resize(newSize);
     155           1 :             unionRegions[newSize - 1] = _regions[count].get();
     156             :         }
     157             :         else {
     158           1 :             WCUnion myUnion(false, unionRegions);
     159           1 :             const WCDifference *myDiff = new WCDifference(myUnion, *_regions[count]);
     160             :             // _ptrMgr is used solely for pointer management, so that the pointers are
     161             :             // deleted when this object goes out of scope, because PtrBlocks do no
     162             :             // memory management
     163           1 :             _ptrMgr.push_back(std::shared_ptr<const WCDifference>(myDiff));
     164           1 :             unionRegions.resize(1, true);
     165           1 :             unionRegions[0] = myDiff;
     166             :         }
     167           2 :         ++count;
     168             :     }
     169           1 :     if (unionRegions.size() == 1) {
     170           1 :         _composite = _ptrMgr[_ptrMgr.size() - 1];
     171             :     }
     172             :     else {
     173           0 :         _composite.reset(new WCUnion(false, unionRegions));
     174             :     }
     175           1 :     return _composite;
     176             : }
     177             : 
     178           0 : uInt RegionTextList::nLines() const {
     179           0 :     return _lines.size();
     180             : }
     181             : 
     182           0 : AsciiAnnotationFileLine RegionTextList::lineAt(
     183             :     const uInt i
     184             : ) const {
     185           0 :     ThrowIf(i >= _lines.size(), "Index out of range");
     186           0 :     return _lines[i];
     187             : }
     188             : 
     189           0 : ostream& RegionTextList::print(ostream& os) const {
     190           0 :     const auto vString = String::toString(RegionTextParser::CURRENT_VERSION);
     191           0 :     os << "#CRTFv" + vString
     192           0 :         << " CASA Region Text Format version "
     193           0 :         << vString << endl;
     194           0 :     for (
     195           0 :         auto iter=_lines.cbegin();
     196           0 :         iter != _lines.cend(); iter++
     197             :     ) {
     198           0 :         if (
     199           0 :             iter == _lines.cbegin()
     200           0 :             && iter->getType() == AsciiAnnotationFileLine::COMMENT
     201           0 :             && iter->getComment().contains(
     202           0 :                 Regex(RegionTextParser::MAGIC.regexp() + "v[0-9]+")
     203             :             )
     204             :         ) {
     205             :             // skip writing header line if it already exists, we write
     206             :             // our own here to avoid clashes with previous spec versions
     207           0 :             continue;
     208             :         }
     209           0 :         os << *iter << endl;
     210             :     }
     211           0 :     return os;
     212             : }
     213             : 
     214             : }

Generated by: LCOV version 1.16