casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Slice.h
Go to the documentation of this file.
00001 //# Slice.h: Define a (start,length,increment) along an axis
00002 //# Copyright (C) 1993,1994,1995,1997
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: Slice.h 21285 2012-11-14 15:36:59Z gervandiepen $
00027 
00028 #ifndef CASA_SLICE_H
00029 #define CASA_SLICE_H
00030 
00031 #include <casa/aips.h>
00032 #include <unistd.h>         //# for ssize_t
00033 
00034 #if defined(AIPS_DEBUG)
00035 #include <casa/Utilities/Assert.h>
00036 #endif
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 //# Forward Declarations.
00041 class Slicer;
00042 class IPosition;
00043 template<class T> class Vector;
00044 
00045 // <summary> define a (start,length,increment) along an axis </summary>
00046 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00047 // </reviewed>
00048 //
00049 // <synopsis>
00050 // A "slice" (aka Section) is a a regular sub-Array (and ultimately sub-Image)
00051 // that is defined by defining a (start,length,increment) for each axis in
00052 // the array. That is, the output array's axis is of size "length", and the
00053 // elements are sampled by stepping along the input array in strides of 
00054 // "increment".
00055 // <note role=warning> 
00056 //   The "length" is the length of the OUTPUT array, the output length
00057 //        is NOT divided by the increment/stride.
00058 // </note>
00059 // If increment is not defined, then it defaults to one. 
00060 // (Increment, if defined, must be >= 1). If length
00061 // is not defined, then it defaults to a length of one also (i.e. just the pixel
00062 // "start"). If start is also undefined, then all pixels along this axis are
00063 // chosen. This class deprecates the "_" (IndexRange) class, which had a failed
00064 // syntax and used (start,end,increment) which is generally less convenient.
00065 // Some simple examples follow:
00066 // <srcblock> 
00067 // Vector<Int> vi(100);          // Vector of length 100;
00068 // //...
00069 //                               // Copy odd values onto even values
00070 // vi(Slice(0,50,2)) = vi(Slice(1,50,2));
00071 // 
00072 // Matrix<float> mf(100,50), smallMf;
00073 // smallMf.reference(mf(Slice(0,10,10), Slice(0,5,10)));
00074 //                               // smallMF is now a "dezoomed" (every 10th pix)
00075 //                               // refference to mf. Of course we could also
00076 //                               // make it a copy by using assignment; e.g:
00077 //
00078 // smallMf.resize(0,0);          // Make it so it will "size to fit"
00079 // smallMf = mf(Slice(0,10,10), Slice(0,5,10));
00080 // </srcblock> 
00081 // As shown above, normally Slices will normally be used as temporaries,
00082 // but they may also be put into variables if desired (the default
00083 // copy constructors and assignment operators suffice for this class).
00084 //
00085 // While it will be unusual for a user to want this, a zero-length slice
00086 // is allowable.
00087 //
00088 // Another way to produce a slice from any of the Array classes is to use
00089 // SomeArray(blc,trc,inc) where blc,trc,inc are IPositions. This is described
00090 // in the documentation for Array<T>.
00091 // </synopsis>
00092 
00093 class Slice
00094 {
00095 public:
00096     // The entire range of indices on the axis is desired.
00097     Slice();
00098     // Create a Slice with a given start, length, and increment. The latter
00099     // two default to one if not given.
00100     Slice(size_t Start, size_t Length=1, size_t Inc=1);
00101     // Create a Slice with a given start, end or length, and increment.
00102     // If <src>endIsLength=False</src>, end is interpreted as length.
00103     Slice(size_t Start, size_t End, size_t Inc, Bool endIsLength);
00104     // Was the entire range of indices on this axis selected?
00105     Bool all() const;
00106     // Report the selected starting position. If all() is true,
00107     // start=len=inc=0 is set.
00108     size_t start() const;
00109     // Report the defined length. If all() is true, start=len=inc=0 is set.
00110     size_t length() const;
00111     // Report the defined increment. If all() is true, start=len=inc=0 is set.
00112     size_t inc() const;
00113     // Attempt to report the last element of the slice. If all() is
00114     // True, end() returns -1 (which is less than start(), which returns
00115     // zero  in that case).
00116     size_t end() const;
00117 
00118     // Check a vector of slices.
00119     // If a vector of an axis is empty or missing, it is replaced by a Slice
00120     // representing the entire axis.
00121     // It checks if the Slices do not exceed the array shape.
00122     // It returns the shape of the combined slices and fills the Slicer
00123     // for the first array part defined by the slices.
00124     static IPosition checkSlices (Vector<Vector<Slice> >& slices, Slicer& first,
00125                                   const IPosition& shape);
00126 
00127 private:
00128     //# Inc of <0 is used as a private flag to mean that the whole axis is
00129     //# selected. Users are given a uInt in their interface, so they cannot
00130     //# set it to this. Chose Inc rather than length since it's more likely
00131     //# that we'd need all bits of length than of inc. The "p" in the names
00132     //# stands for private to avoid it colliding with the accessor names.
00133     //# incp < 0 is chosen as the flag since the user can set inc to be zero
00134     //# although that is an error that can be caught if AIPS_DEBUG is defined).
00135     size_t  startp;
00136     ssize_t incp;
00137     size_t  lengthp;
00138 };
00139 
00140 inline Slice::Slice() : startp(0), incp(-1), lengthp(0)
00141 {
00142     // Nothing
00143 }
00144 
00145 inline
00146 Slice::Slice(size_t Start, size_t Length, size_t Inc)
00147   : startp(Start), incp(Inc), lengthp(Length)
00148 {
00149 #if defined(AIPS_DEBUG)
00150     DebugAssert(incp > 0, AipsError);
00151 #endif
00152 }
00153 
00154 inline
00155 Slice::Slice(size_t Start, size_t End, size_t Inc, Bool endIsLength)
00156   : startp(Start), incp(Inc), lengthp(endIsLength ? End : End+1-Start)
00157 {
00158 #if defined(AIPS_DEBUG)
00159     DebugAssert(End >= Start, AipsError);
00160     DebugAssert(incp > 0, AipsError);
00161 #endif
00162 }
00163 
00164 inline Bool Slice::all() const
00165 {
00166     return incp<0;
00167 }
00168 
00169 inline size_t Slice::start() const
00170 {
00171     return startp;
00172 }
00173 
00174 inline size_t Slice::length() const
00175 {
00176     return lengthp;
00177 }
00178 
00179 inline size_t Slice::inc() const
00180 {
00181     if (all()) {
00182         return 0;
00183     } else {
00184         return incp;
00185     }
00186 }
00187 
00188 inline size_t Slice::end() const
00189 {
00190     // return -1 if all()
00191     return startp + lengthp - 1;
00192 }
00193 
00194 
00195 } //# NAMESPACE CASA - END
00196 
00197 #endif