casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
WCBox.h
Go to the documentation of this file.
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