casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MaskedLatticeIterator.h
Go to the documentation of this file.
00001 //# MaskedLatticeIterator.h: Iterators for Masked Lattices: readonly
00002 //# Copyright (C) 2003
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: MaskedLatticeIterator.h 20229 2008-01-29 15:19:06Z gervandiepen $
00027 
00028 #ifndef LATTICES_MASKEDLATTICEITERATOR_H
00029 #define LATTICES_MASKEDLATTICEITERATOR_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <lattices/Lattices/MaskedLattice.h>
00034 #include <lattices/Lattices/LatticeIterator.h>
00035 #include <casa/Utilities/CountedPtr.h>
00036 
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 // <summary>
00041 // A readonly iterator for masked Lattices.
00042 // </summary>
00043 
00044 // <use visibility=export>
00045 
00046 // <reviewed reviewer="" date="" tests="tMaskedLatticeIterator.cc">
00047 // </reviewed>
00048 
00049 // <prerequisite>
00050 //   <li> <linkto class="MaskedLattice">MaskedLattice</linkto>
00051 //   <li> <linkto class="RO_LatticeIterator">RO_LatticeIterator</linkto>
00052 // </prerequisite>
00053 
00054 // <etymology>
00055 // The leading "RO" is shorthand for "readonly", which indicates that an
00056 // RO_MaskedLatticeIterator is used for traversing a masked lattice,
00057 // examining and possibly extracting its contents, but not for modifying it.
00058 // </etymology>
00059 
00060 // <synopsis> 
00061 // This class provides a convenient way to traverse any class derived from
00062 // MaskedLattice. It is derived from class
00063 // <linkto class=RO_LatticeIterator>RO_LatticeIterator</linkto>, so it
00064 // provides the same iterator capabilities.
00065 // On top of that it offers the function <src>getMask</src> to get the
00066 // contents of the mask at the current iterator position.
00067 //
00068 // In principle, iteration through a MaskedLattice can be done as:
00069 // <srcblock>
00070 // void someFunc (const MaskedLattice<Float>& lattice)
00071 // {
00072 //   RO_LatticeIterator<Float> iter(lattice);
00073 //   Array<Bool> mask;
00074 //   while (! iter.atEnd()) {
00075 //     const Array<Float>& array = iter.cursor();
00076 //     lattice.getMaskSlice (mask, iter.position(), array.shape());
00077 //     iter++;
00078 //   }
00079 // }
00080 // </srcblock>
00081 // Using a MaskedLatticeIterator makes getting the mask slightly more
00082 // convenient.
00083 // <srcblock>
00084 // void someFunc (const MaskedLattice<Float>& lattice)
00085 // {
00086 //   RO_MaskedLatticeIterator<Float> iter(lattice);
00087 //   Array<Bool> mask;
00088 //   while (! iter.atEnd()) {
00089 //     const Array<Float>& array = iter.cursor();
00090 //     iter.getMask (mask);
00091 //     iter++;
00092 //   }
00093 // }
00094 // </srcblock>
00095 // However, the most important reason to use MaskedLatticeIterator is
00096 // performance. If the underlying lattice is a LatticeExpr object,
00097 // the expression will be evaluated twice if a LatticeIterator object
00098 // is used. The reason is that the lattice in the LatticeIterator is
00099 // a different object from the lattice object used to get the mask.
00100 // Hence, the optimization put in LatticeExpr is not used.
00101 // When using a MaskedLatticeIterator the same lattice object is used
00102 // to get data and mask.
00103 // </synopsis>
00104 
00105 // <motivation>
00106 // The performance gain for LatticeExpr was the most important reason
00107 // to develop this class.
00108 // </motivation>
00109 
00110 //# <todo asof="2003/11/10">
00111 //#  <li>
00112 //# </todo>
00113 
00114 
00115 template<class T> class RO_MaskedLatticeIterator: public RO_LatticeIterator<T>
00116 {
00117   //# Make members of parent class known.
00118 public:
00119   using RO_LatticeIterator<T>::isNull;
00120   using RO_LatticeIterator<T>::position;
00121   using RO_LatticeIterator<T>::endPosition;
00122   using RO_LatticeIterator<T>::cursorShape;
00123 
00124 public:
00125   // The default constructor creates an empty object which is practically
00126   // unusable.
00127   // It can only be used as the source or target of an assignment. It can
00128   // also be used as the source for the copy constructor and the copy function.
00129   // Other functions do not check if the object is empty and will usually
00130   // give a segmentation fault.
00131   // The function isNull() can be used to test if the object is empty.
00132   RO_MaskedLatticeIterator();
00133 
00134   // Construct the Iterator with the supplied data.
00135   // It uses a TileStepper as the default iteration strategy.
00136   // useRef=True means that if possible the cursor arrays returned
00137   // reference the data in the underlying lattice. This is only possible
00138   // for ArrayLattice objects (or e.g. a SubLattice using it).
00139   explicit RO_MaskedLatticeIterator (const MaskedLattice<T>& data,
00140                                      Bool useRef=True);
00141 
00142   // Construct the Iterator with the supplied data, and iteration strategy
00143   RO_MaskedLatticeIterator (const MaskedLattice<T>& data,
00144                             const LatticeNavigator& method,
00145                             Bool useRef=True);
00146 
00147   // Construct the Iterator with the supplied data.
00148   // It uses a LatticeStepper with the supplied cursor shape as the
00149   // iteration strategy.
00150   RO_MaskedLatticeIterator (const MaskedLattice<T>& data,
00151                             const IPosition& cursorShape,
00152                             Bool useRef=True);
00153 
00154   // The copy constructor uses reference semantics (ie. NO real copy is made).
00155   // The function <src>copy</src> can be used to make a true copy.
00156   RO_MaskedLatticeIterator (const RO_MaskedLatticeIterator<T>& other);
00157  
00158   // Destructor (cleans up dangling references and releases memory)
00159   ~RO_MaskedLatticeIterator();
00160 
00161   // Assignment uses reference semantics (ie. NO real copy is made).
00162   // The function <src>copy</src> can be used to make a true copy.
00163   RO_MaskedLatticeIterator<T>& operator= (const RO_MaskedLatticeIterator<T>&);
00164 
00165   // Make a copy of the iterator object.
00166   // This means that an independent navigator object is created to
00167   // be able to iterate independently through the same MaskedLattice.
00168   // The position in the copied navigator is the same as the original.
00169   // The reset function has to be used to start at the beginning.
00170   // <br>Note that if the MaskedLattice uses a cache (e.g. PagedArray), the
00171   // cache is shared by the iterators.
00172   RO_MaskedLatticeIterator<T> copy() const;
00173 
00174   // Return the underlying MaskedLattice object.
00175   MaskedLattice<T>& lattice() const
00176     { return const_cast<MaskedLattice<T>&>(*itsMaskLattPtr); }
00177 
00178   // Is the underlying MaskedLattice really masked?
00179   Bool isMasked() const
00180     { return itsMaskLattPtr->isMasked(); }
00181 
00182   // Get the mask for the current position.
00183   // It returns the same flag as
00184   // <linkto class=MaskedLattice>MaskedLattice::getMaskSlice</linkto>.
00185   // <group>
00186   Bool getMask (COWPtr<Array<Bool> >&, Bool removeDegenerateAxes=False) const;
00187   Bool getMask (Array<Bool>&, Bool removeDegenerateAxes=False) const;
00188   Array<Bool> getMask (Bool removeDegenerateAxes=False) const;
00189   // </group>
00190 
00191 private:
00192   // Construct from a LatticeIterator (for copy function).
00193   RO_MaskedLatticeIterator (const RO_LatticeIterator<T>&,
00194                             const RO_MaskedLatticeIterator<T>&);
00195 
00196   // Fill the pointer with a pointer to the masked lattice.
00197   // This pointer is a casted copy of the lattice pointer in the base class.
00198   // In this way they share the same MaskedLattice object, which is needed
00199   // for optimal performance of e.g. LatticeExpr.
00200   // Otherwise getting data from the lattice and from the mask would
00201   // result in 2 evaluations of the expression.
00202   // However, the lattice can be a PagedArray (for example, for PagedImage).
00203   // In that case a clone of the original MaskedLattice is used.
00204   void fillPtr (const MaskedLattice<T>& mlattice);
00205 
00206   CountedPtr<MaskedLattice<T> > itsMaskLattPtr;
00207 };
00208 
00209 
00210 
00211 } //# NAMESPACE CASA - END
00212 
00213 #ifndef CASACORE_NO_AUTO_TEMPLATES
00214 #include <lattices/Lattices/MaskedLatticeIterator.tcc>
00215 #endif //# CASACORE_NO_AUTO_TEMPLATES
00216 #endif