casa
$Rev:20696$
|
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