casa
$Rev:20696$
|
00001 //# WCBox.h: Class to define a box shaped WC region 00002 //# Copyright (C) 1998,1999,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 //# $Id: WCBox.h 20567 2009-04-09 23:12:39Z gervandiepen $ 00026 00027 00028 00029 #ifndef IMAGES_WCBOX_H 00030 #define IMAGES_WCBOX_H 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <coordinates/Coordinates/CoordinateSystem.h> 00035 #include <images/Regions/WCRegion.h> 00036 #include <lattices/Lattices/RegionType.h> 00037 #include <casa/Arrays/Vector.h> 00038 #include <casa/Quanta/Quantum.h> 00039 00040 namespace casa { //# NAMESPACE CASA - BEGIN 00041 00042 //# Forward Declarations 00043 class LCRegion; 00044 class TableRecord; 00045 class IPosition; 00046 00047 00048 // <summary> 00049 // Class to define a world coordinate box region of interest in an image. 00050 // </summary> 00051 // 00052 // <use visibility=export> 00053 // 00054 // <reviewed reviewer="" date="" tests=""> 00055 // </reviewed> 00056 // 00057 // <prerequisite> 00058 // <li> <linkto class=WCRegion>WCRegion</linkto> 00059 // <li> <linkto class=LCRegion>LCRegion</linkto> 00060 // <li> <linkto class=CoordinateSystem>CoordinateSystem</linkto> 00061 // </prerequisite> 00062 // 00063 // <synopsis> 00064 // The corners of the box are specified in world coordinates, but the 00065 // region enclosed by those corners is a box in lattice coordinates. 00066 // Thus, the volume enclosed does not follow world coordinate contours. 00067 // 00068 // All this class does, apart from constructing itself, is know 00069 // how to save itself to a <src>Record</src> and how to convert itself 00070 // to an <src>LCRegion</src>. The conversion allows you to apply 00071 // a <src>WCBox</src> constructed with one <src>CoordinateSystem</src> 00072 // to another <src>CoordinateSystem</src>. That is, you can apply a 00073 // <src>WCBox</src> from this image to that image. 00074 // 00075 // The flexibility of the <src>CoordinateSystem</src> class should 00076 // be kept in mind when using this class. Recall that a 00077 // <src>CoordinateSystem</src> has world and pixel axes, and 00078 // that these axes can be independently removed and independently 00079 // (re)ordered. 00080 // 00081 // During construction, the length of the world coordinate vectors may be 00082 // smaller than the number world axes in the supplied <src>CoordinateSystem</src>. 00083 // It is assumed that the units of the world coordinates are the same as those 00084 // encapsulated in the construction <src>CoordinateSystem</src> and in the same 00085 // order as specified (either intrinsically, or by the world axes 00086 // specification vectors). 00087 // 00088 // The following rules are followed during conversion to an <src>LCRegion</src>. 00089 // <ol> 00090 // <li> The number of elements in the supplied <src>latticeShape</src> must be equal 00091 // to the number of pixel axes in the supplied <src>CoordinateSystem</src>. 00092 // <li> The order of the pixel axes in the supplied <src>CoordinateSystem</src> 00093 // is assumed to be the order of the axes in the lattice for which the 00094 // supplied <src>latticeShape</src> is appropriate. 00095 // <li> The <src>CoordinateSystem</src> supplied to the <src>toLCRegion</src> 00096 // function does not have to be identical in structure to that from 00097 // which the <src>WCBox</src> was constructed. They can consist 00098 // of different numbers of world and pixel axes and be in different 00099 // orders. 00100 // <li> For every world axis in the supplied <src>CoordinateSystem</src> 00101 // that is also present (somewhere) in the construction <src>CoordinateSystem</src> 00102 // the blc/trc corresponding to that world axis will be 00103 // converted to pixels appropriate to the supplied <src>CoordinateSystem</src>. 00104 // The order of this pixel based blc/trc will be the order of the pixel axes of 00105 // the supplied <src>CoordinateSystem</src> 00106 // <li> For every world axis in the supplied <src>CoordinateSystem</src> 00107 // that is not present in the construction <src>CoordinateSystem</src>, 00108 // the supplied <src>latticeShape</src> value for the corresponding 00109 // pixel axis is used, setting <src>blc=0</src> and <src>trc=latticeShape-1</src> 00110 // for that axis. 00111 // <li> Once the pixel based blc/trc has been created, then, with 00112 // the supplied <src>latticeShape</src>, it is used to create the 00113 // <src>LCBox</src>, which is supplied as a pointer to the base 00114 // class <src>LCRegion</src>. 00115 // </ol> 00116 // 00117 // Note that when determining whether a world axis from one 00118 // <src>CoordinateSystem</src>is present on another, it is 00119 // considered to not be a match if two coordinates of the 00120 // same type (e.g. <src>DirectionCoordinate</src>) have different 00121 // specific types (e.g. J2000 and GALACTIC, or TOPO and LSR for 00122 // a <src>SpectralCoordinate</src>) 00123 // </synopsis> 00124 // 00125 // <example> 00126 // Let us give some examples with pseudo-code. 00127 // cSys is the construction CoordinateSystem 00128 // and cSys2 is the supplied CoordinateSystem. 00129 // We list their world axes in the square brackets. 00130 // The construction blc/trc values don't matter 00131 // as long as there cSys.nWorldAxes() of them. 00132 // Similarly, the values of shape don't matter 00133 // as long as there are cSys2.nPixelAxes() of them. 00134 // <srcblock> 00135 // cSys = [ra, dec, freq]; 00136 // cSys2 = [ra, dec]; 00137 // blc = [,,]; 00138 // trc = [,,]; 00139 // shape = [,]; 00140 // WCBox box(blc, trc, cSys); 00141 // LCRegion* pR = box.toLCRegion(cSys2, shape); 00142 // </srcblock> 00143 // The resultant LCBox will have corners converted 00144 // according to 00145 // <srcblock> 00146 // blcLC(0) <- blc(0); 00147 // blcLC(1) <- blc(1); 00148 // trcLC(0) <- trc(0); 00149 // trcLC(1) <- trc(1); 00150 // </srcblock> 00151 // 00152 // </example> 00153 // 00154 // <example> 00155 // <srcblock> 00156 // cSys = [ra, dec, freq]; 00157 // cSys2 = [freq, stokes]; 00158 // blc = [,,]; 00159 // trc = [,,]; 00160 // shape = [,]; 00161 // WCBox box(blc, trc, cSys); 00162 // LCRegion* pR = box.toLCRegion(cSys2, shape); 00163 // </srcblock> 00164 // 00165 // The resultant LCBox will have corners converted 00166 // according to 00167 // 00168 // <srcblock> 00169 // blcLC(0) <- blc(2); 00170 // blcLC(1) = 0; 00171 // trcLC(0) <- trc(2); 00172 // trcLC(1) = shape(1) - 1; 00173 // </srcblock> 00174 // 00175 // </example> 00176 // 00177 // <example> 00178 // <srcblock> 00179 // cSys = [ra, dec]; 00180 // cSys2 = [ra, dec, freq]; 00181 // blc = [,]; 00182 // trc = [,]; 00183 // shape = [,,]; 00184 // WCBox box(blc, trc, cSys); 00185 // LCRegion* pR = box.toLCRegion(cSys2, shape); 00186 // </srcblock> 00187 // 00188 // The resultant LCBox will have corners converted 00189 // according to 00190 // 00191 // <srcblock> 00192 // blcLC(0) <- blc(0); 00193 // blcLC(1) <- blc(1); 00194 // blcLC(2) = 0l 00195 // trcLC(0) <- trc(0); 00196 // trcLC(1) <- trc(1); 00197 // trcLC(2) = shape(2)-1; 00198 // </srcblock> 00199 // 00200 // </example> 00201 // 00202 // <example> 00203 // <srcblock> 00204 // cSys = [ra, dec, freq]; 00205 // cSys2 = [freq, ra, dec]; 00206 // blc = [,,]; 00207 // trc = [,,]; 00208 // shape = [,,]; 00209 // WCBox box(blc, trc, cSys); 00210 // LCRegion* pR = box.toLCRegion(cSys2, shape); 00211 // </srcblock> 00212 // 00213 // The resultant LCBox will have corners converted 00214 // according to 00215 // 00216 // <srcblock> 00217 // blcLC(0) <- blc(2); 00218 // blcLC(1) <- blc(0); 00219 // blcLC(2) <- blc(1); 00220 // trcLC(0) <- trc(2); 00221 // trcLC(1) <- trc(0); 00222 // trcLC(2) <- trc(1); 00223 // </srcblock> 00224 // 00225 // </example> 00226 // 00227 // <example> 00228 // In this example we make it a bit harder by 00229 // reordering the pixel axes too. The new order 00230 // of the pixel axes in terms of the original 00231 // order [0,1,2] is given after the world axes 00232 // 00233 // <srcblock> 00234 // cSys = [ra, dec, freq], [0, 1, 2]; 00235 // cSys2 = [freq, ra, dec, stokes], [3, 0, 2, 1]; 00236 // blc = [,,]; 00237 // trc = [,,]; 00238 // shape = [,,,]; 00239 // WCBox box(blc, trc, cSys); 00240 // LCRegion* pR = box.toLCRegion(cSys2, shape); 00241 // </srcblock> 00242 // 00243 // Take the first world axis of cSys2 as an example. 00244 // First, "freq" is found as the world axis number 00245 // 2 in cSys. Then, when it is converted to 00246 // a pixel coordinate, it will turn up as 00247 // the value on pixel axis 1. The supplied shape 00248 // must be appropriate to a [stokes, freq, dec, ra] lattice. 00249 // The resultant LCBox will therefore have corners 00250 // converted according to 00251 // 00252 // <srcblock> 00253 // blcLC(0) = 0 00254 // blcLC(1) <- blc(2); 00255 // blcLC(2) <- blc(1); 00256 // blcLC(3) <- blc(0); 00257 // 00258 // trcLC(0) = shape(0)-1; 00259 // trcLC(1) <- trc(2); 00260 // trcLC(2) <- trc(1); 00261 // trcLC(3) <- trc(0); 00262 // </srcblock> 00263 // </example> 00264 // 00265 // <motivation> 00266 // Users must be able to specify regions in world as well as lattice 00267 // coordinates. 00268 // </motivation> 00269 // 00270 // <note> 00271 // In all of the constructors, the order of the specified world 00272 // coordinates is that of the *PIXEL AXES* (not world axes) in the 00273 // <src>CoordinateSystem</src>. This is the natural order for a user to want 00274 // to specify them in. 00275 // </note> 00276 // 00277 // <note> 00278 // For the constructors specifying the world values as simple doubles, 00279 // it is *ASSUMED* that the units of those doubles are the same as 00280 // the native units of the <src>CoordinateSystem</src> for each axis. 00281 // </note> 00282 // 00283 // <note> 00284 // World coordinates may be specified as absolute or offset. If the 00285 // latter, they are offset with respect to the reference pixel of 00286 // the <src>CoordinateSystem</src>. 00287 // </note> 00288 // <todo asof="1998/05/20"> 00289 // <li> Implement offset coordinates 00290 // </todo> 00291 00292 class WCBox : public WCRegion 00293 { 00294 public: 00295 WCBox(); 00296 00297 // Construct from vectors of world coordinates 00298 // defining the box corners. It is assumed that the 00299 // order of the values is in the order of the pixel axes 00300 // in the given coordinate system. 00301 // <group> 00302 WCBox(const Vector<Quantum<Double> >& blc, 00303 const Vector<Quantum<Double> >& trc, 00304 const CoordinateSystem& cSys, 00305 const Vector<Int>& absRel); 00306 // </group> 00307 00308 // Construct from vectors of world coordinates 00309 // defining the box corners. You specify the pixel 00310 // axis order of the world values. 00311 // <group> 00312 WCBox(const Vector<Quantum<Double> >& blc, 00313 const Vector<Quantum<Double> >& trc, 00314 const IPosition& pixelAxes, 00315 const CoordinateSystem& cSys, 00316 const Vector<Int>& absRel); 00317 // </group> 00318 00319 // Construct from the bounding box of an <src>LCRegion</src>. 00320 WCBox(const LCRegion& region, 00321 const CoordinateSystem& cSys); 00322 00323 // Copy constructor (reference semantics [except for <src>CoordinateSystem</src>]) 00324 WCBox (const WCBox& other); 00325 00326 // Destructor 00327 virtual ~WCBox(); 00328 00329 // Assignment (copy semantics) 00330 WCBox& operator= (const WCBox& other); 00331 00332 // Comparison 00333 virtual Bool operator==(const WCRegion& other) const; 00334 00335 // Clone a WCBox object. 00336 virtual WCRegion* cloneRegion() const; 00337 00338 // WCBox can extend a region. 00339 virtual Bool canExtend() const; 00340 00341 // Make a new box from the given axesin this box. 00342 WCBox splitBox (const IPosition& axes) const; 00343 00344 // Convert to an LCRegion using the supplied <src>CoordinateSystem</src> 00345 // and shape. 00346 virtual LCRegion* doToLCRegion (const CoordinateSystem& cSys, 00347 const IPosition& latticeShape, 00348 const IPosition& pixelAxesMap, 00349 const IPosition& outOrder) const; 00350 00351 // Convert the WCBox object to a record. 00352 // The record can be used to make the object persistent. 00353 // The <src>tableName</src> argument can be used by derived 00354 // classes (e.g. LCPagedMask) to put very large objects. 00355 virtual TableRecord toRecord(const String& tableName) const; 00356 00357 // Convert to a WCBox from a record. 00358 static WCBox* fromRecord (const TableRecord& rec, 00359 const String& tableName); 00360 00361 // Returns WCBox 00362 static String className(); 00363 00364 // Return region type. Returns the class name 00365 virtual String type() const; 00366 00367 private: 00368 Vector<Quantum<Double> > itsBlc; 00369 Vector<Quantum<Double> > itsTrc; 00370 IPosition itsPixelAxes; 00371 CoordinateSystem itsCSys; 00372 Vector<Int> itsAbsRel; 00373 Bool itsNull; 00374 00375 00376 // Check units of quanta are consistent with CoordinateSystem 00377 void checkUnits (const IPosition& pixelAxes, 00378 const Vector<Quantum<Double> >& values, 00379 const CoordinateSystem& cSys); 00380 00381 // Convert relative pixels to absolute or fill in defaults 00382 void convertPixel(Double& pixel, 00383 const Quantum<Double>& value, 00384 const Int absRel, 00385 const Double refPix, 00386 const Int shape, 00387 const Bool isBlc) const; 00388 00389 }; 00390 00391 00392 00393 } //# NAMESPACE CASA - END 00394 00395 #endif