00001 /** @file psCoord.h 00002 * 00003 * @brief Contains basic coordinate transformation definitions and operations 00004 * 00005 * This file defines the basic types for astronomical coordinate 00006 * transformation 00007 * 00008 * @ingroup CoordinateTransform 00009 * 00010 * 00011 * @author GLG, MHPCC 00012 * 00013 * @version $Revision: 1.52 $ $Name: rel12 $ 00014 * @date $Date: 2006/06/30 02:20:06 $ 00015 * 00016 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii 00017 */ 00018 00019 #ifndef PS_COORD_H 00020 #define PS_COORD_H 00021 00022 #include "psType.h" 00023 #include "psImage.h" 00024 #include "psArray.h" 00025 #include "psList.h" 00026 #include "psPolynomial.h" 00027 #include "psPixels.h" 00028 #include "psRegion.h" 00029 //#include "psTime.h" 00030 00031 /// @addtogroup CoordinateTransform 00032 /// @{ 00033 00034 /** Euclidiean Coordinate System. 00035 * 00036 * Both detector and sky positions will be used extensively in the IPP. One 00037 * coordinate system to be used is linear coordinates which conform to 00038 * Euclidean geometry. 00039 * 00040 */ 00041 typedef struct 00042 { 00043 double x; ///< x position 00044 double y; ///< y position 00045 double xErr; ///< Error in x position 00046 double yErr; ///< Error in y position 00047 } 00048 psPlane; 00049 00050 /** Angular Coordinate System 00051 * 00052 * Both detector and sky positions will be used extensively in the IPP. One 00053 * coordinate system to be used is angular coordinates for which additional 00054 * care must often be taken in comparison to a euclidiean coordinate system. 00055 * 00056 */ 00057 typedef struct 00058 { 00059 double r; ///< RA 00060 double d; ///< Dec 00061 double rErr; ///< Error in RA 00062 double dErr; ///< Error in Dec 00063 } 00064 psSphere; 00065 00066 /** 3-Dimensional Euclidean Coordinate System 00067 * 00068 * Both detector and sky positions will be used extensively in the IPP. One 00069 * coordinate system to be used is cubic coordinates for which additional 00070 * care must often be taken in comparison to an angular coordinate system. 00071 * 00072 */ 00073 typedef struct 00074 { 00075 double x; ///< cos (DEC) cos (RA) 00076 double y; ///< cos (DEC) sin (RA) 00077 double z; ///< sin (DEC) 00078 double xErr; ///< Error in x 00079 double yErr; ///< Error in y 00080 double zErr; ///< Error in z 00081 } 00082 psCube; 00083 00084 /** 2D Polynomial Transform 00085 * 00086 * A transform between coordinate systems that consists simply of two 2D 00087 * polynomials to transform both components - the output coordinates depend 00088 * only on the input coordinates and no other quantities of objects at those 00089 * coordinates. 00090 * 00091 */ 00092 typedef struct 00093 { 00094 psPolynomial2D* x; ///< 2D polynomial transform of X coordinates 00095 psPolynomial2D* y; ///< 2D polynomial transform of Y coordinates 00096 } 00097 psPlaneTransform; 00098 00099 /** 4D Polynomial Transform 00100 * 00101 * A transform between coordinate systems that consists of two 4D polynomials 00102 * in which the output coordinates are also specified to be a function of the 00103 * magnitude and color of the object with the given coordinates. This type of 00104 * coordinate transformation is necessary to represent the (color-dependent) 00105 * optical distortions caused by the atmosphere and camera optics, and the 00106 * possibly effects of charge transfer inefficiency. 00107 * 00108 * The lowest two terms are the x and y axis of the target system. The higher 00109 * two terms may represent magnitude and color terms. 00110 */ 00111 typedef struct 00112 { 00113 psPolynomial4D* x; ///< 4D polynomial transform of X coordinates 00114 psPolynomial4D* y; ///< 4D polynomial transform of Y coordinates 00115 } 00116 psPlaneDistort; 00117 00118 /** Projection type for projection/deprojection 00119 * 00120 * @see psProject, psDeproject 00121 * 00122 */ 00123 typedef enum { 00124 PS_PROJ_TAN, ///< Tangent projection 00125 PS_PROJ_SIN, ///< Sine projection 00126 PS_PROJ_AIT, ///< Aitoff projection 00127 PS_PROJ_PAR, ///< Par projection 00128 // PS_PROJ_GLS, ///< GLS projection 00129 // PS_PROJ_CAR, ///< CAR projection 00130 // PS_PROJ_MER, ///< MER projection 00131 PS_PROJ_NTYPE ///< Number of types; must be last. 00132 } psProjectionType; 00133 00134 /** Parameter set for projection/deprojection 00135 * 00136 * @see psProject, psDeproject 00137 * 00138 */ 00139 typedef struct 00140 { 00141 double R; ///< Coordinates of projection center 00142 double D; ///< Coordinates of projection center 00143 double Xs; ///< plate-scale in X direction 00144 double Ys; ///< plate-scale in Y direction 00145 psProjectionType type; ///< Projection type 00146 } 00147 psProjection; 00148 00149 /** Allocates a psPlane 00150 * 00151 * @return psPlane* resulting plane structure. 00152 */ 00153 psPlane* psPlaneAlloc(void); 00154 00155 /** Allocates a psSphere 00156 * 00157 * @return psSphere* resulting sphere structure. 00158 */ 00159 psSphere* psSphereAlloc(void); 00160 00161 /** Allocates a psCube 00162 * 00163 * @return psCube* resulting cubic structure. 00164 */ 00165 psCube* psCubeAlloc(void); 00166 00167 /** Allocates a psPlaneTransform transform. 00168 * 00169 * @return psPlaneTransform* resulting plane transform 00170 */ 00171 00172 psPlaneTransform* psPlaneTransformAlloc( 00173 int order1, ///< The order of the x term in the transform. 00174 int order2 ///< The order of the y term in the transform. 00175 ); 00176 00177 /** Applies the psPlaneTransform transform to a specified coordinate 00178 * 00179 * @return psPlane* resulting coordinate based on transform 00180 */ 00181 psPlane* psPlaneTransformApply( 00182 psPlane* out, ///< a psPlane to recycle. If NULL, a new one is generated. 00183 const psPlaneTransform* transform, ///< the transform to apply 00184 const psPlane* coords ///< the coordinate to apply the transform above. 00185 ); 00186 00187 /** Allocates a psPlaneDistort transform. 00188 * 00189 * @return psPlaneDistort* resulting plane distort transform 00190 */ 00191 00192 psPlaneDistort* psPlaneDistortAlloc( 00193 int order1, ///< The order of the w term in the transform. 00194 int order2, ///< The order of the x term in the transform. 00195 int order3, ///< The order of the y term in the transform. 00196 int order4 ///< The order of the z term in the transform. 00197 ); 00198 00199 00200 /** Applies the psPlaneDistort transform to a specified coordinate 00201 * 00202 * @return psPlane* resulting coordinate based on transform 00203 */ 00204 psPlane* psPlaneDistortApply( 00205 psPlane* out, ///< a psPlane to recycle. If NULL, a new one is generated. 00206 const psPlaneDistort* distort, ///< the transform to apply 00207 const psPlane* coords, ///< the coordinate to apply the transform above. 00208 float mag, ///< third term -- maybe magnitude 00209 float color ///< forth term -- maybe color 00210 ); 00211 00212 /** Allocates memory for a psProjection structure 00213 * 00214 * @return psProjection* psProjection structure 00215 */ 00216 psProjection* psProjectionAlloc( 00217 double R, ///< Right-ascension of projection center. 00218 double D, ///< Declination of projection center. 00219 double Xs, ///< Scale in x-dimension 00220 double Ys, ///< Scale in y-dimension 00221 psProjectionType type 00222 ); 00223 00224 /** Checks the type of a particular pointer. 00225 * 00226 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00227 * 00228 * @return bool: True if the pointer matches a psPlane structure, false otherwise. 00229 */ 00230 bool psMemCheckPlane( 00231 psPtr ptr ///< the pointer whose type to check 00232 ); 00233 00234 /** Checks the type of a particular pointer. 00235 * 00236 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00237 * 00238 * @return bool: True if the pointer matches a psSphere structure, false otherwise. 00239 */ 00240 bool psMemCheckSphere( 00241 psPtr ptr ///< the pointer whose type to check 00242 ); 00243 00244 /** Checks the type of a particular pointer. 00245 * 00246 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00247 * 00248 * @return bool: True if the pointer matches a psCube structure, false otherwise. 00249 */ 00250 bool psMemCheckCube( 00251 psPtr ptr ///< the pointer whose type to check 00252 ); 00253 00254 /** Checks the type of a particular pointer. 00255 * 00256 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00257 * 00258 * @return bool: True if the pointer matches a psPlaneTransform structure, false otherwise. 00259 */ 00260 bool psMemCheckPlaneTransform( 00261 psPtr ptr ///< the pointer whose type to check 00262 ); 00263 00264 /** Checks the type of a particular pointer. 00265 * 00266 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00267 * 00268 * @return bool: True if the pointer matches a psPlaneDistort structure, false otherwise. 00269 */ 00270 bool psMemCheckPlaneDistort( 00271 psPtr ptr ///< the pointer whose type to check 00272 ); 00273 00274 /** Checks the type of a particular pointer. 00275 * 00276 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00277 * 00278 * @return bool: True if the pointer matches a psProjection structure, false otherwise. 00279 */ 00280 bool psMemCheckProjection( 00281 psPtr ptr ///< the pointer whose type to check 00282 ); 00283 00284 00285 /** Projects a spherical coordinate to a linear coordinate system 00286 * 00287 * @return psPlane* projected coordinate 00288 */ 00289 psPlane* psProject( 00290 const psSphere* coord, ///< coordinate to project 00291 const psProjection* projection ///< parameters of the projection 00292 ); 00293 00294 psPlane* p_psProject( 00295 psPlane *out, 00296 const psSphere* coord, ///< coordinate to project 00297 const psProjection* projection ///< parameters of the projection 00298 ); 00299 00300 /** Reverse projection of a linear coordinate to a spherical coordinate system 00301 * 00302 * @return psPlane* projected coordinate 00303 */ 00304 psSphere* psDeproject( 00305 const psPlane* coord, ///< coordinate to project 00306 const psProjection* projection ///< parameters of the projection 00307 ); 00308 00309 /** Private reverse projection of a linear coordinate to a spherical coordinate system 00310 * 00311 * @return psPlane* projected coordinate 00312 */ 00313 psSphere* p_psDeproject( 00314 psSphere *outSphere, 00315 const psPlane* coord, ///< coordinate to project 00316 const psProjection* projection ///< parameters of the projection 00317 ); 00318 00319 /** Takes a given transform and inverts it linearly if possible. 00320 * 00321 * @return psPlaneTransform 00322 * the linearly inverted transform 00323 */ 00324 psPlaneTransform *p_psPlaneTransformLinearInvert( 00325 psPlaneTransform *transform ///< transform to invert 00326 ); 00327 psPlaneTransform *p_psPlaneTransformLinearInvert_MHPCC( 00328 psPlaneTransform *transform ///< transform to invert 00329 ); 00330 00331 00332 /** Takes a transform and tests whether or not it is a linear projection. 00333 * 00334 * @return psS32 00335 * the order of the projection 00336 */ 00337 psBool p_psIsProjectionLinear( 00338 psPlaneTransform *transform ///< transform to test for linearity 00339 ); 00340 00341 00342 /** inverts a given transformation. 00343 * 00344 * It may assume that the input transformation is one-to-one, and that the 00345 * inverse transformation may be specified through using polynomials of the 00346 * same type and order as the forward transformation. In the event that the 00347 * input transformation is linear, an exact solution may be calculated; 00348 * otherwise nSamples samples in each axis, covering the region specified by 00349 * region shall be used as a grid to fit the best inverse transformation. The 00350 * function shall return NULL if it was unable to generate the inverse 00351 * transformation; otherwise it shall return the inverse transformation. In 00352 * the event that out is NULL, a new psPlaneTransform shall be allocated and 00353 * returned. 00354 * 00355 * @return psPlaneTransform* the resulting inverted transform 00356 */ 00357 psPlaneTransform* psPlaneTransformInvert( 00358 psPlaneTransform *out, ///< a transform to recycle, or NULL if one is to be created. 00359 const psPlaneTransform *in, ///< transform to invert 00360 psRegion region, ///< region to fit for non-linear transform inversion 00361 int nSamples ///< number of samples in each axis for fit 00362 ); 00363 00364 /** Creates a single transformation that has the effect of performing trans1 00365 * followed by trans2. 00366 * 00367 * psPlaneTransformCombine takes two transformations (trans1 and trans2) and 00368 * returns a single transformation that has the effect of performing trans1 00369 * followed by trans2. In the event that the input transformation is linear, 00370 * an exact solution may be calculated; otherwise nSamples samples in each 00371 * axis, covering the region specified by region shall be used as a grid to 00372 * fit the best inverse transformation. The function shall return NULL if it 00373 * was unable to generate the transformation; otherwise it shall return the 00374 * transformation. 00375 * 00376 * @return psPlaneTransform* resulting transformation 00377 */ 00378 psPlaneTransform* psPlaneTransformCombine( 00379 psPlaneTransform *out, ///< a transform to recycle, or NULL if one is to be created. 00380 const psPlaneTransform *trans1, ///< first transform to combine 00381 const psPlaneTransform *trans2, ///< first transform to combine 00382 psRegion region, ///< region to cover (for non-linear transforms) 00383 int nSamples ///< number of samples on each axis (for non-linear transforms) 00384 ); 00385 00386 00387 /** takes two arrays containing matched coordinates and returns the 00388 * best-fitting transformation. 00389 * 00390 * psPlaneTransformFit takes two arrays containing matched coordinates (i.e., 00391 * coordinates in the source array correspond to the coordinates in the dest 00392 * array) and returns the best-fitting transformation. The source and dest 00393 * will contain psCoords. In the event that the number of coordinates in each 00394 * is not identical, the function shall generate a warning, and extra 00395 * coordinates in the longer of the two shall be ignored. The trans transform 00396 * may not be NULL, since it specifies the desired order, polynomial type and 00397 * any polynomial terms to mask. nRejIter rejection iterations shall be 00398 * performed, wherein coordinates lying more than sigmaClip standard 00399 * deviations from the fit shall be rejected. 00400 * 00401 * @return bool TRUE if successful, otherwise FALSE. 00402 */ 00403 bool psPlaneTransformFit( 00404 psPlaneTransform *trans, ///< desired order, polynomial type, & polynomial mask terms 00405 const psArray *source, ///< coordinates matching those in dest 00406 const psArray *dest, ///< coordinates matching those in source 00407 int nRejIter, ///< number of rejection iterations to be performed 00408 float sigmaClip ///< coordinates above this number of standard deviations will be rejected 00409 ); 00410 //XXX: need to add doxygen comments on the parameters above. -rdd 00411 00412 /** Converts from a 3-dimensional coordinate system to an angular coordinate system. 00413 * 00414 * @return psSphere* The former psCube in terms of a psSphere. 00415 */ 00416 psSphere *psCubeToSphere( 00417 const psCube *cube ///< psCube to convert 00418 ); 00419 00420 /** Converts from an angular coordinate system to a 3-dimensional coordinate system. 00421 * 00422 * @return psCube* The former psSphere in terms of a psCube. 00423 */ 00424 psCube *psSphereToCube( 00425 const psSphere *sphere ///< psSphere to convert 00426 ); 00427 00428 00429 /** Calculates the derivative of the specified psPlaneTransform with respect to x and y. 00430 * 00431 * @return psPlane* The derivative. 00432 */ 00433 psPlane *psPlaneTransformDeriv( 00434 psPlane *out, 00435 const psPlaneTransform *transformation, 00436 const psPlane *coord 00437 ); 00438 00439 /** Generates a list of pixels in the output coordinate frame that overlap the input 00440 * pixels in the input coordinate frame through the specified transformation, inToOut. 00441 * 00442 * psPixelsTransform is more complicated than simply transforming the input pixels, 00443 * but requires the evaluation of the derivatives of the transformation in order to 00444 * obtain the list of all pixels in the output coordinate frame that possibly overlap 00445 * the pixel in the input coordinate frame. In the event that input or inToOut are 00446 * NULL, the function shall generate an error and return NULL. If out is non-NULL it 00447 * shall be modified and returned; otherwise a new psPixels shall be allocated and 00448 * returned. 00449 * 00450 * @return psPixels*: the list of overlapping pixels. 00451 */ 00452 psPixels *psPixelsTransform( 00453 psPixels *out, ///< output list of overlapping pixels 00454 const psPixels *input, ///< input list of pixels 00455 const psPlaneTransform *inToOut ///< specified transformation 00456 ); 00457 00458 #define PS_PRINT_PLANE_TRANSFORM(NAME) \ 00459 { \ 00460 printf("---------------------- Plane Transform ----------------------\n"); \ 00461 printf("x:\n"); \ 00462 PS_POLY_PRINT_2D(NAME->x); \ 00463 printf("y:\n"); \ 00464 PS_POLY_PRINT_2D(NAME->y); \ 00465 } \ 00466 00467 /// @} 00468 00469 #endif // #ifndef PS_COORD_H
1.4.4