/*  @file pmWarpMap.h
 *  @brief Warp Map Manipulation functions
 * 
 *  @author Paul Price, IfA
 *  @author Eugene Magnier, IfA
 * 
 *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2007-01-24 01:05:41 $
 *  Copyright 2005-2006 Institute for Astronomy, University of Hawaii
 */

#ifndef PM_WARP_MAP_H
#define PM_WARP_MAP_H

/// @addtogroup Sky
/// @{

// a single pmWarpMap converts coordinates from one image to a second image
// the linear model is only valid over a limited range of pixels
typedef struct
{
    double Xo, Xx, Xy;                  // Transformation coefficients for x
    double Yo, Yx, Yy;                  // Transformation coefficients for y
    int xo, yo;                         // Origin
}
pmWarpMap;

// the pmWarpMapGrid carries a collection of pmWarpMag structures representing the
// local value of the pmWarpMap at different locations in the image.
typedef struct
{
    pmWarpMap ***maps;                  // 2D image of pointers to maps
    int nXpts, nYpts;                   // number of x,y samples in the grid
    int nXpix, nYpix;                   // x,y spacing in src image pixels of grid samples
    int xMin,  yMin;                    // coordinate of first grid sample
}
pmWarpMapGrid;

/// Allocator
pmWarpMap *pmWarpMapAlloc(void);

/// Allocator
pmWarpMapGrid *pmWarpMapGridAlloc(int Nx, // Number of grid points in x
                                  int Ny // Number of grid points in y
                                 );


// Operations follow


// construct a grid with superpixel spacing of nXpix, nYpix
pmWarpMapGrid *pmWarpMapGridFromImage(pmSkyCell *dest, // Destination sky cell
                                      const pmReadout *src, // Source readout
                                      int nXpix, // Number of pixels in x
                                      int nYpix // Number of pixels in y
                                     );

bool pmWarpMapGridSetGrid(pmWarpMapGrid *grid,
                          int ix, int iy,
                          int *gridX,
                          int *gridY
                         );

bool pmWarpMapGridNextGrid(pmWarpMapGrid *grid,
                           int gridX,
                           int gridY,
                           int *nextX,
                           int *nextY
                          );

// measure the max error accumulated in appling one grid point to its neighbors
double pmWarpMapGridMaxError(const pmWarpMapGrid *grid
                            );

bool pmWarpMapApply(double *outX,
                    double *outY,
                    const pmWarpMap *map,
                    double inX,
                    double inY);

// determine the map for the given pixel from src to dest. pixel is in src coords
bool pmWarpMapSetLocalModel(pmWarpMap *map,
                            const pmSkyCell *dest,
                            const pmReadout *src,
                            int ix, int iy
                           );
/// @}
#endif
