casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LCRegion.h
Go to the documentation of this file.
00001 //# LCRegion.h: Abstract base class to define a region of interest in lattice coordinates
00002 //# Copyright (C) 1998,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: LCRegion.h 20505 2009-01-19 14:37:24Z gervandiepen $
00027 
00028 #ifndef LATTICES_LCREGION_H
00029 #define LATTICES_LCREGION_H
00030 
00031 //# Includes
00032 #include <lattices/Lattices/Lattice.h>
00033 #include <casa/Arrays/IPosition.h>
00034 #include <casa/Arrays/Slicer.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 //# Forward Declarations
00039 class TableRecord;
00040 class RecordInterface;
00041 
00042 
00043 // <summary>
00044 // Abstract base class to define a region of interest in lattice coordinates.
00045 // </summary>
00046 
00047 // <use visibility=export>
00048 
00049 // <reviewed reviewer="" date="" tests="">
00050 // </reviewed>
00051 
00052 // <prerequisite>
00053 //   <li> <linkto class=Slicer>Slicer</linkto>
00054 // </prerequisite>
00055 
00056 // <synopsis> 
00057 // The LCRegion class is the abstract base class for various types
00058 // of LCRegion's (e.g. <linkto class=LCEllipsoid>LCEllipsoid</linkto>,
00059 // <linkto class=LCBox>LCBox</linkto>).
00060 // It contains the minimal bounding box of the region and, if needed,
00061 // a mask with the same shape as the bounding box. A mask element
00062 // is true if the element is inside the box.
00063 // <p>
00064 // Each LCRegion object must be able to convert itself to and from a record.
00065 // In that way they can be made persistent (in for example a Table).
00066 // <p>
00067 // The LCRegion can be used in several Lattices and Images classes and
00068 // functions to limit the area to operate on.
00069 // </synopsis> 
00070 
00071 // <example>
00072 // <srcblock>
00073 // </srcblock>
00074 // </example>
00075 
00076 // <motivation>
00077 // The Slicer class is too limited as a region, because it can only
00078 // describe a rectangular region. Specialized classes are needed to
00079 // describe arbitrary regions. They need a base class to combine them.
00080 // </motivation>
00081 
00082 //# <todo asof="1997/11/11">
00083 //# <li>
00084 //# </todo>
00085 
00086 class LCRegion : public Lattice<Bool>
00087 {
00088 public:
00089     LCRegion();
00090 
00091     // Construct with the lattice shape only.
00092     LCRegion (const IPosition& latticeShape);
00093 
00094     // Copy constructor (copy semantics).
00095     LCRegion (const LCRegion& other);
00096 
00097     virtual ~LCRegion();
00098 
00099     // Equality 
00100     virtual Bool operator== (const LCRegion& other) const;
00101 
00102     // Non-equality.  Be careful, do not use this anywhere in the derived
00103     // class structure.  You must use, e.g.,
00104     // <src>if (! LCRegion::operator== (...))</src>
00105     // rather than <src>if (LCRegion::operator!= (...))</src> as the
00106     // latter will invoke an infinite loop.  It is ok to use when applying
00107     // to a concrete class object.
00108     Bool operator!= (const LCRegion& other) const;
00109 
00110     // Make a copy of the derived object.
00111     // <group>
00112     virtual Lattice<Bool>* clone() const;
00113     virtual LCRegion* cloneRegion() const = 0;
00114     // </group>
00115 
00116     // Handle deletion of the region by deleting possible tables.
00117     // The default implementation does nothing.
00118     virtual void handleDelete();
00119 
00120     // Handle renaming the region by renaming possible tables.
00121     // The default implementation does nothing.
00122     virtual void handleRename (const String& newName, Bool overwrite);
00123 
00124     // Region type.  Returns className() of derived class.
00125     virtual String type() const = 0;
00126 
00127     // Get or set the comment.
00128     // <group>
00129     const String& comment() const;
00130     void setComment (const String& comment);
00131     // </group>
00132 
00133     // Does the region have a mask?
00134     virtual Bool hasMask() const = 0;
00135 
00136     // Construct another LCRegion (for e.g. another lattice) by moving
00137     // this one. It recalculates the bounding box and mask.
00138     // A positive translation value indicates "to right".
00139     // <group>
00140     LCRegion* translate (const IPosition& translateVector) const;
00141     LCRegion* translate (const IPosition& translateVector,
00142                          const IPosition& newLatticeShape) const;
00143     LCRegion* translate (const Vector<Float>& translateVector) const;
00144     LCRegion* translate (const Vector<Float>& translateVector,
00145                          const IPosition& newLatticeShape) const;
00146     // </group>
00147 
00148     // Give the full lattice shape.
00149     const IPosition& latticeShape() const;
00150 
00151     // Give the bounding box.
00152     const Slicer& boundingBox() const;
00153 
00154     // Expand a slicer or position in the region to the full lattice.
00155     // This converts the positions in the region to positions
00156     // in the entire lattice.
00157     // <group>
00158     Slicer expand (const Slicer& slicer) const;
00159     IPosition expand (const IPosition& index) const;
00160     // </group>
00161 
00162     // Convert the (derived) object to a record.
00163     // The record can be used to make the object persistent.
00164     // The <src>tableName</src> argument can be used by derived
00165     // classes (e.g. LCPagedMask) to put very large objects.
00166     virtual TableRecord toRecord (const String& tableName) const = 0;
00167 
00168     // Convert correct object from a record.
00169     static LCRegion* fromRecord (const TableRecord&,
00170                                  const String& tableName);
00171 
00172     // Return the dimensionality of the region.
00173     virtual uInt ndim() const;
00174 
00175     // Return the shape of the region (i.e. of its bounding box).
00176     virtual IPosition shape() const;
00177 
00178     // Usually the lattice (i.e. the region mask) is not writable.
00179     virtual Bool isWritable() const;
00180 
00181     // Regions can usually not be put; i.e. no putSlice, etc. can be
00182     // done on their masks.
00183     // Hence LCRegion throws by default an exception for the
00184     // following functions.
00185     // <group>
00186     virtual void doPutSlice (const Array<Bool>& sourceBuffer,
00187                              const IPosition& where,
00188                              const IPosition& stride);
00189     virtual void set (const Bool& value);
00190     virtual void apply (Bool (*function)(Bool));
00191     virtual void apply (Bool (*function)(const Bool&));
00192     virtual void apply (const Functional<Bool,Bool>& function);
00193     virtual void putAt (const Bool& value, const IPosition& where);
00194     virtual void copyData (const Lattice<Bool>& from);
00195     // </group>
00196 
00197 protected:
00198     // Assignment (copy semantics) is only useful for derived classes.
00199     LCRegion& operator= (const LCRegion& other);
00200 
00201     // Sometimes it is inconvenient for a derived class to set the bounding
00202     // box in the constructor. So it can be set explicitly.
00203     // It fills in the possibly undefined Slicer values.
00204     // It may even be needed to set the lattice shape.
00205     // <group>
00206     void setBoundingBox (const Slicer& boundingBox);
00207     void setShapeAndBoundingBox (const IPosition& latticeShape,
00208                                  const Slicer& boundingBox);
00209     // </group>
00210 
00211     // Do the actual translate in a derived class.
00212     virtual LCRegion* doTranslate (const Vector<Float>& translateVector,
00213                                    const IPosition& newLatticeShape) const = 0;
00214 
00215     // Define the type and class name in the record.
00216     void defineRecordFields (RecordInterface& record,
00217                              const String& className) const;
00218 
00219 private:
00220     IPosition itsShape;
00221     Slicer    itsBoundingBox;
00222     String    itsComment;
00223 };
00224 
00225 
00226 inline const Slicer& LCRegion::boundingBox() const
00227 {
00228     return itsBoundingBox;
00229 }
00230 inline const IPosition& LCRegion::latticeShape() const
00231 {
00232     return itsShape;
00233 }
00234 inline LCRegion* LCRegion::translate (const IPosition& translateVector) const
00235 {
00236     return translate (translateVector, itsShape);
00237 }
00238 inline LCRegion* LCRegion::translate (const Vector<Float>& translateVector)
00239                                                                         const
00240 {
00241     return translate (translateVector, itsShape);
00242 }
00243 inline const String& LCRegion::comment() const
00244 {
00245     return itsComment;
00246 }
00247 inline void LCRegion::setComment (const String& comment)
00248 {
00249     itsComment = comment;
00250 }
00251 
00252 inline Bool LCRegion::operator!= (const LCRegion& other) const
00253 //
00254 // Watch out !  You must not, in the derived class structure,
00255 // invoke LCRegion::operator!=  If you do,  you will be stuck 
00256 // in a time warp, as this will just fetch the 
00257 // operator== of the concrete class and you start all over again.
00258 // You must use always use !LCRegion::operator==.  It is ok in application
00259 // code using the concrete class to say
00260 // if (x != y) where x and y are, say, LCBoxes.
00261 {
00262    return (!operator==(other));
00263 }
00264 
00265 
00266 
00267 
00268 } //# NAMESPACE CASA - END
00269 
00270 #endif