예제 #1
0
/***********************************************************************//**
 * @brief Pixel-to-spherical deprojection
 *
 * @param[in] nx X vector length.
 * @param[in] ny Y vector length (0=no replication).
 * @param[in] sxy Input vector step.
 * @param[in] spt Output vector step.
 * @param[in] x Vector of projected x coordinates.
 * @param[in] y Vector of projected y coordinates.
 * @param[out] phi Longitude of the projected point in native spherical
 *                 coordinates [deg].
 * @param[out] theta Latitude of the projected point in native spherical
 *                   coordinates [deg].
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * Deproject pixel (x,y) coordinates in the plane of projection to native
 * spherical coordinates (phi,theta).
 *
 * This method has been adapted from the wcslib function prj.c::tanx2s().
 * The interface follows very closely that of wcslib. In contrast to the
 * wcslib routine, however, the method assumes that the projection has been
 * setup previously (as this will be done by the constructor).
 ***************************************************************************/
void GWcsTAN::prj_x2s(int nx, int ny, int sxy, int spt, 
                      const double* x, const double* y,
                      double* phi, double* theta, int* stat) const
{
    // Initialize projection if required
    if (!m_prjset) {
        prj_set();
    }

    // Set value replication length mx,my
    int mx;
    int my;
    if (ny > 0) {
        mx = nx;
        my = ny;
    } 
    else {
        mx = 1;
        my = 1;
        ny = nx;
    }
    
    // Do x dependence
    const double* xp     = x;
    int           rowoff = 0;
    int           rowlen = nx * spt;
    for (int ix = 0; ix < nx; ++ix, rowoff += spt, xp += sxy) {
        double  xj   = *xp + m_x0;
        double* phip = phi + rowoff;
        for (int iy = 0; iy < my; ++iy, phip += rowlen) {
            *phip = xj;
        }
    }

    // Do y dependence
    const double* yp     = y;
    double*       phip   = phi;
    double*       thetap = theta;
    int*          statp  = stat;
    for (int iy = 0; iy < ny; ++iy, yp += sxy) {
        double yj  = *yp + m_y0;
        double yj2 = yj*yj;
        for (int ix = 0; ix < mx; ++ix, phip += spt, thetap += spt) {
            double xj = *phip;
            double r  = std::sqrt(xj*xj + yj2);
            if (r == 0.0) {
                *phip = 0.0;
            }
            else {
                *phip = gammalib::atan2d(xj, -yj);
            }
            *thetap    = gammalib::atan2d(m_r0, r);
            *(statp++) = 0;
        }
    }

    // Return
    return;
}
예제 #2
0
/***********************************************************************//**
 * @brief Generic spherical-to-pixel projection
 *
 * @param[in] nphi Longitude vector length.
 * @param[in] ntheta Latitude vector length (0=no replication).
 * @param[in] spt Input vector step.
 * @param[in] sxy Output vector step.
 * @param[in] phi Longitude vector of the projected point in native spherical
 *                coordinates [deg].
 * @param[in] theta Latitude vector of the projected point in native spherical
 *                  coordinates [deg].
 * @param[out] x Vector of projected x coordinates.
 * @param[out] y Vector of projected y coordinates.
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * Project native spherical coordinates (phi,theta) to pixel (x,y)
 * coordinates in the plane of projection.
 *
 * This method has been adapted from the wcslib function prj.c::sfls2x().
 * The interface follows very closely that of wcslib. In contrast to the
 * wcslib routine, however, the method assumes that the projection has been
 * setup previously (as this will be done by the constructor).
 ***************************************************************************/
void GWcsSFL::prj_s2x(int nphi, int ntheta, int spt, int sxy,
                      const double* phi, const double* theta,
                      double* x, double* y, int* stat) const
{
    // Initialize projection if required
    if (!m_prjset) {
        prj_set();
    }

    // Set value replication length mphi,mtheta
    int mphi;
    int mtheta;
    if (ntheta > 0) {
        mphi   = nphi;
        mtheta = ntheta;
    } 
    else {
        mphi   = 1;
        mtheta = 1;
        ntheta = nphi;
    }

    // Do phi dependence
    const double* phip   = phi;
    int           rowoff = 0;
    int           rowlen = nphi * sxy;
    for (int iphi = 0; iphi < nphi; ++iphi, rowoff += sxy, phip += spt) {
        double  xi = m_w[0] * (*phip);
        double* xp = x + rowoff;
        for (int itheta = 0; itheta < mtheta; ++itheta, xp += rowlen) {
            *xp = xi;
        }
    }

    // Do theta dependence
    const double* thetap = theta;
    double*       xp     = x;
    double*       yp     = y;
    int*          statp  = stat;
    for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) {
        double xi  = gammalib::cosd(*thetap);
        double eta = m_w[0] * (*thetap) - m_y0;
        for (int iphi = 0; iphi < mphi; ++iphi, xp += sxy, yp += sxy) {
            *xp = xi * (*xp) - m_x0;
            *yp = eta;
            *(statp++) = 0;
        }
    }
    
    // Return
    return;
}
예제 #3
0
/***********************************************************************//**
 * @brief Pixel-to-spherical deprojection
 *
 * @param[in] nx X vector length.
 * @param[in] ny Y vector length (0=no replication).
 * @param[in] sxy Input vector step.
 * @param[in] spt Output vector step.
 * @param[in] x Vector of projected x coordinates.
 * @param[in] y Vector of projected y coordinates.
 * @param[out] phi Longitude of the projected point in native spherical
 *                 coordinates [deg].
 * @param[out] theta Latitude of the projected point in native spherical
 *                   coordinates [deg].
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * Deproject pixel (x,y) coordinates in the plane of projection to native
 * spherical coordinates (phi,theta).
 *
 * This method has been adapted from the wcslib function prj.c::merx2s().
 * The interface follows very closely that of wcslib. In contrast to the
 * wcslib routine, however, the method assumes that the projection has been
 * setup previously (as this will be done by the constructor).
 ***************************************************************************/
void GWcsMER::prj_x2s(int nx, int ny, int sxy, int spt, 
                      const double* x, const double* y,
                      double* phi, double* theta, int* stat) const
{
    // Initialize projection if required
    if (!m_prjset) {
        prj_set();
    }

    // Set value replication length mx,my
    int mx;
    int my;
    if (ny > 0) {
        mx = nx;
        my = ny;
    } 
    else {
        mx = 1;
        my = 1;
        ny = nx;
    }
    
    // Do x dependence
    const double* xp     = x;
    int           rowoff = 0;
    int           rowlen = nx * spt;
    for (int ix = 0; ix < nx; ++ix, rowoff += spt, xp += sxy) {
        double  s    = m_w[1] * (*xp + m_x0);
        double* phip = phi + rowoff;
        for (int iy = 0; iy < my; ++iy, phip += rowlen) {
            *phip = s;
        }
    }

    // Do y dependence
    const double* yp     = y;
    double*       thetap = theta;
    int*          statp  = stat;
    for (int iy = 0; iy < ny; ++iy, yp += sxy) {
        double t = 2.0 * gammalib::atand(std::exp((*yp + m_y0)/m_r0)) - 90.0;
        for (int ix = 0; ix < mx; ++ix, thetap += spt) {
            *thetap    = t;
            *(statp++) = 0;
        }
    }

    // Return
    return;
}
예제 #4
0
/***********************************************************************//**
 * @brief Pixel-to-spherical deprojection
 *
 * @param[in] nx X vector length.
 * @param[in] ny Y vector length (0=no replication).
 * @param[in] sxy Input vector step.
 * @param[in] spt Output vector step.
 * @param[in] x Vector of projected x coordinates.
 * @param[in] y Vector of projected y coordinates.
 * @param[out] phi Longitude of the projected point in native spherical
 *                 coordinates [deg].
 * @param[out] theta Latitude of the projected point in native spherical
 *                   coordinates [deg].
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * Deproject pixel (x,y) coordinates in the plane of projection to native
 * spherical coordinates (phi,theta).
 *
 * This method has been adapted from the wcslib function prj.c::sflx2s().
 * The interface follows very closely that of wcslib. In contrast to the
 * wcslib routine, however, the method assumes that the projection has been
 * setup previously (as this will be done by the constructor).
 ***************************************************************************/
void GWcsSFL::prj_x2s(int nx, int ny, int sxy, int spt,
                      const double* x, const double* y,
                      double* phi, double* theta, int* stat) const
{
    // Initialize projection if required
    if (!m_prjset) {
        prj_set();
    }

    // Set value replication length mx,my
    int mx;
    int my;
    if (ny > 0) {
        mx = nx;
        my = ny;
    } 
    else {
        mx = 1;
        my = 1;
        ny = nx;
    }

    // Initialise status code and statistics
    int status    = 0;
    int n_invalid = 0;


    // Do x dependence
    const double* xp     = x;
    int           rowoff = 0;
    int           rowlen = nx * spt;
    for (int ix = 0; ix < nx; ++ix, rowoff += spt, xp += sxy) {
        double  s    = m_w[1] * (*xp + m_x0);
        double* phip = phi + rowoff;
        for (int iy = 0; iy < my; ++iy, phip += rowlen) {
            *phip = s;
        }
    }

    // Do y dependence
    const double* yp     = y;
    double*       phip   = phi;
    double*       thetap = theta;
    int*          statp  = stat;
    for (int iy = 0; iy < ny; ++iy, yp += sxy) {
        double yj  = *yp + m_y0;
        double s   = std::cos(yj/m_r0);

        // Initialise status
        int istat = 0;

        // Invert s
        if (s == 0.0) {
            istat = 1;
            status = 3;
            n_invalid++;
            #if defined(G_DEBUG_PRJ)
            std::cout << "prj_x2s(Phi)..:";
            std::cout << " nx=" << nx;
            std::cout << " ny=" << ny;
            std::cout << " ix=" << ix;
            std::cout << " iy=" << iy;
            std::cout << " yp=" << *yp;
            std::cout << " yj=" << yj;
            std::cout << " phip=" << *phip;
            std::cout << " s=" << s;
            std::cout << std::endl;
            #endif
        }
        else {
            s = 1.0 / s;
        }

        // ...
        double t = m_w[1] * yj;

        // ...
        for (int ix = 0; ix < mx; ++ix, phip += spt, thetap += spt) {
            *phip     *= s;
            *thetap    = t;
            *(statp++) = istat;
        }

    } // endfor: y dependence

    // Handle status code
    if (status == 3) {
        throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid);
    }

    // Return
    return;
}
예제 #5
0
/***********************************************************************//**
 * @brief Generic spherical-to-pixel projection
 *
 * @param[in] nphi Longitude vector length.
 * @param[in] ntheta Latitude vector length (0=no replication).
 * @param[in] spt Input vector step.
 * @param[in] sxy Output vector step.
 * @param[in] phi Longitude vector of the projected point in native spherical
 *                coordinates [deg].
 * @param[in] theta Latitude vector of the projected point in native spherical
 *                  coordinates [deg].
 * @param[out] x Vector of projected x coordinates.
 * @param[out] y Vector of projected y coordinates.
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * Project native spherical coordinates (phi,theta) to pixel (x,y)
 * coordinates in the plane of projection.
 *
 * This method has been adapted from the wcslib function prj.c::mers2x().
 * The interface follows very closely that of wcslib. In contrast to the
 * wcslib routine, however, the method assumes that the projection has been
 * setup previously (as this will be done by the constructor).
 ***************************************************************************/
void GWcsMER::prj_s2x(int nphi, int ntheta, int spt, int sxy,
                      const double* phi, const double* theta,
                      double* x, double* y, int* stat) const
{
    // Initialize projection if required
    if (!m_prjset) {
        prj_set();
    }

    // Set value replication length mphi,mtheta
    int mphi;
    int mtheta;
    if (ntheta > 0) {
        mphi   = nphi;
        mtheta = ntheta;
    } 
    else {
        mphi   = 1;
        mtheta = 1;
        ntheta = nphi;
    }

    // Initialise status code and statistics
    //int status    = 0;
    int n_invalid = 0;

    // Do phi dependence
    const double* phip   = phi;
    int           rowoff = 0;
    int           rowlen = nphi * sxy;
    for (int iphi = 0; iphi < nphi; ++iphi, rowoff += sxy, phip += spt) {
        double  xi = m_w[0] * (*phip) - m_x0;
        double* xp = x + rowoff;
        for (int itheta = 0; itheta < mtheta; ++itheta, xp += rowlen) {
            *xp = xi;
        }
    }


    // Do theta dependence
    const double* thetap = theta;
    double*       yp     = y;
    int*          statp  = stat;
    for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) {
        double eta;
        int    istat = 0;
        if (*thetap <= -90.0 || *thetap >= 90.0) {
            eta    = 0.0;
            istat  = 1;
            n_invalid++;
        }
        else {
            eta = m_r0 * std::log(gammalib::tand((*thetap+90.0)/2.0)) - m_y0;
        }
        for (int iphi = 0; iphi < mphi; ++iphi, yp += sxy) {
            *yp = eta;
            *(statp++) = istat;
        }
    }
    
    // Return
    return;
}
예제 #6
0
/***********************************************************************//**
 * @brief Generic spherical-to-Cartesian projection
 *
 * @param[in] nphi Longitude vector length.
 * @param[in] ntheta Latitude vector length (0=no replication).
 * @param[in] spt Input vector step.
 * @param[in] sxy Output vector step.
 * @param[in] phi Longitude vector of the projected point in native spherical
 *                coordinates [deg].
 * @param[in] theta Latitude vector of the projected point in native spherical
 *                  coordinates [deg].
 * @param[out] x Vector of projected x coordinates.
 * @param[out] y Vector of projected y coordinates.
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * Project native spherical coordinates (phi,theta) to Cartesian (x,y)
 * coordinates in the plane of projection.
 *
 * This method has been adapted from the wcslib function prj.c::cars2x().
 * The interface follows very closely that of wcslib. In contrast to the
 * wcslib routine, however, the method assumes that the projection has been
 * setup previsouly (as this will be done by the constructor).
 ***************************************************************************/
void GWcsSTG::prj_s2x(int nphi, int ntheta, int spt, int sxy,
                      const double* phi, const double* theta,
                      double* x, double* y, int* stat) const
{
    // Initialize projection if required
    if (!m_prjset)
        prj_set();

    // Set value replication length mphi,mtheta
    int mphi;
    int mtheta;
    if (ntheta > 0) {
        mphi   = nphi;
        mtheta = ntheta;
    } 
    else {
        mphi   = 1;
        mtheta = 1;
        ntheta = nphi;
    }

    // Initialise status code and statistics
    int status    = 0;
    int n_invalid = 0;
    
    // Do phi dependence
    const double* phip   = phi;
    int           rowoff = 0;
    int           rowlen = nphi * sxy;
    for (int iphi = 0; iphi < nphi; ++iphi, rowoff += sxy, phip += spt) {
        double sinphi;
        double cosphi;
        sincosd(*phip, &sinphi, &cosphi);
        double* xp = x + rowoff;
        double* yp = y + rowoff;
        for (int itheta = 0; itheta < mtheta; ++itheta) {
            *xp = sinphi;
            *yp = cosphi;
            xp += rowlen;
            yp += rowlen;
        }
    }

    // Do theta dependence
    const double* thetap = theta;
    double*       xp     = x;
    double*       yp     = y;
    int*          statp  = stat;
    for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) {
        
        // Compute sine of Theta
        double s = 1.0 + sind(*thetap);
        
        // If 1+sine is zero we cannot proceed. Set all pixels to (0,0) and flag
        // them as being bad
        if (s == 0.0) {
            for (int iphi = 0; iphi < mphi; ++iphi, xp += sxy, yp += sxy) {
                *xp        = 0.0;
                *yp        = 0.0;
                *(statp++) = 1;
                n_invalid++;
            }
            status = 4;
        }
        
        // ... otherwise proceed, but if strict bound checking has been requested
        // then flag all pixels as bad that have negative sin(theta)
        else {
            double r = m_w[0] * cosd(*thetap)/s;
            for (int iphi = 0; iphi < mphi; ++iphi, xp += sxy, yp += sxy) {
                *xp        =  r*(*xp) - m_x0;
                *yp        = -r*(*yp) - m_y0;
                *(statp++) = 0;
            }
        }
    }
  
    // Handle status code
    if (status == 4)
        throw GException::wcs_invalid_phi_theta(G_PRJ_S2X, n_invalid);
    
    // Return
    return;
}
예제 #7
0
/***********************************************************************//**
 * @brief Generic spherical-to-pixel projection
 *
 * @param[in] nphi Longitude vector length.
 * @param[in] ntheta Latitude vector length (0=no replication).
 * @param[in] spt Input vector step.
 * @param[in] sxy Output vector step.
 * @param[in] phi Longitude vector of the projected point in native spherical
 *                coordinates [deg].
 * @param[in] theta Latitude vector of the projected point in native spherical
 *                  coordinates [deg].
 * @param[out] x Vector of projected x coordinates.
 * @param[out] y Vector of projected y coordinates.
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * @exception GException::wcs_invalid_phi_theta
 *            One or more of the (phi,theta) coordinates were invalid, as
 *            indicated by the stat vector.
 *
 * Project native spherical coordinates (phi,theta) to pixel (x,y)
 * coordinates in the plane of projection.
 *
 * This method has been adapted from the wcslib function prj.c::mols2x()
 * (version 4.20). The interface follows very closely that of wcslib. In
 * contrast to the wcslib routine, however, the method assumes that the
 * projection has been setup previously (as this will be done by the
 * constructor).
 ***************************************************************************/
void GWcsMOL::prj_s2x(int nphi, int ntheta, int spt, int sxy,
                      const double* phi, const double* theta,
                      double* x, double* y, int* stat) const
{
    // Set tolerance
    const double tol = 1.0e-13;

    // Initialize projection if required
    if (!m_prjset) {
        prj_set();
    }

    // Set value replication length mphi,mtheta
    int mphi;
    int mtheta;
    if (ntheta > 0) {
        mphi   = nphi;
        mtheta = ntheta;
    } 
    else {
        mphi   = 1;
        mtheta = 1;
        ntheta = nphi;
    }

    // Initialise status code and statistics
    int status    = 0;
    int n_invalid = 0;
    
    // Do phi dependence
    const double* phip   = phi;
    int           rowoff = 0;
    int           rowlen = nphi * sxy;
    for (int iphi = 0; iphi < nphi; ++iphi, rowoff += sxy, phip += spt) {
        double  xi = m_w[1] * (*phip);
        double* xp = x + rowoff;
        for (int itheta = 0; itheta < mtheta; ++itheta) {
            *xp = xi;
            xp += rowlen;
        }
    }

    // Do theta dependence
    const double* thetap = theta;
    double*       xp     = x;
    double*       yp     = y;
    int*          statp  = stat;
    for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) {

        // Compute xi and eta
        double xi  = 0.0;
        double eta = 0.0;
        if (std::abs(*thetap) == 90.0) {
            xi  = 0.0;
            eta = copysign(m_w[0], *thetap);
        }
        else if (*thetap == 0.0) {
            xi  = 1.0;
            eta = 0.0;
        }
        else {
            double u  =  gammalib::pi * std::sin(*thetap * gammalib::deg2rad);
            double v0 = -gammalib::pi;
            double v1 =  gammalib::pi;
            double v  = u;
            for (int k = 0; k < 100; ++k) {
                double resid = (v - u) + std::sin(v);
                if (resid < 0.0) {
                    if (resid > -tol) {
                        break;
                    }
                    v0 = v;
                }
                else {
                    if (resid < tol) {
                        break;
                    }
                    v1 = v;
                }
                v = 0.5 * (v0 + v1);
            }
            double gamma = 0.5 * v;
            xi           = std::cos(gamma);
            eta          = std::sin(gamma) * m_w[0];
        }
        eta -= m_y0;

        // Do ...
        for (int iphi = 0; iphi < mphi; ++iphi, xp += sxy, yp += sxy, statp += sxy) {
            *xp    = xi * (*xp) - m_x0;
            *yp    = eta;
            *statp = 0;
        }

    } // endfor: theta dependence
  
    // Handle status code
    if (status == 4) {
        throw GException::wcs_invalid_phi_theta(G_PRJ_S2X, n_invalid);
    }
    
    // Return
    return;
}
예제 #8
0
/***********************************************************************//**
 * @brief Pixel-to-spherical deprojection
 *
 * @param[in] nx X vector length.
 * @param[in] ny Y vector length (0=no replication).
 * @param[in] sxy Input vector step.
 * @param[in] spt Output vector step.
 * @param[in] x Vector of projected x coordinates.
 * @param[in] y Vector of projected y coordinates.
 * @param[out] phi Longitude of the projected point in native spherical
 *                 coordinates [deg].
 * @param[out] theta Latitude of the projected point in native spherical
 *                   coordinates [deg].
 * @param[out] stat Status return value for each vector element
 *
 * @exception GException::wcs_invalid_x_y
 *            One or more of the (x,y) coordinates were invalid, as indicated
 *            by the stat vector.
 *
 * Deproject pixel (x,y) coordinates in the plane of projection to native
 * spherical coordinates (phi,theta).
 *
 * This method has been adapted from the wcslib function prj.c::molx2s()
 * (version 4.20). The interface follows very closely that of wcslib. In
 * contrast to the wcslib routine, however, the method assumes that the
 * projection has been setup previously (as this will be done by the
 * constructor).
 ***************************************************************************/
void GWcsMOL::prj_x2s(int nx, int ny, int sxy, int spt, 
                      const double* x, const double* y,
                      double* phi, double* theta, int* stat) const
{
    // Set tolerance
    const double tol = 1.0e-12;

    // Initialize projection if required
    if (!m_prjset) {
        prj_set();
    }

    // Set value replication length mx,my
    int mx;
    int my;
    if (ny > 0) {
        mx = nx;
        my = ny;
    } 
    else {
        mx = 1;
        my = 1;
        ny = nx;
    }

    // Initialise status code and statistics
    int status    = 0;
    int n_invalid = 0;
    
    // Do x dependence
    const double* xp     = x;
    int           rowoff = 0;
    int           rowlen = nx * spt;
    for (int ix = 0; ix < nx; ++ix, rowoff += spt, xp += sxy) {
        double  xj     = *xp + m_x0;
        double  s      = m_w[3] * xj;
        double  t      = std::abs(xj) - tol;
        double* phip   = phi   + rowoff;
        double* thetap = theta + rowoff;
        for (int iy = 0; iy < my; ++iy, phip += rowlen, thetap += rowlen) {
            *phip   = s;
            *thetap = t;
        }
    }

    // Do y dependence
    const double* yp     = y;
    double*       phip   = phi;
    double*       thetap = theta;
    int*          statp  = stat;
    for (int iy = 0; iy < ny; ++iy, yp += sxy) {

        // Initialise status
        int istat = 0;

        // Compute some stuff
        double yj  = *yp + m_y0;
        double y0  = yj / m_r0;
        double r   = 2.0 - y0 * y0;
        double s   = 0.0;

        // Check limits
        if (r <= tol) {
            if (r < -tol) {
                istat  = 1;
                status = 3;
                n_invalid++;
                #if defined(G_DEBUG_PRJ)
                std::cout << "prj_x2s(Phi)..:";
                std::cout << " nx=" << nx;
                std::cout << " ny=" << ny;
                std::cout << " iy=" << iy;
                std::cout << " yp=" << *yp;
                std::cout << " yj=" << yj;
                std::cout << " y0=" << y0;
                std::cout << " phip=" << *phip;
                std::cout << " r=" << r;
                std::cout << " s=" << s;
                std::cout << std::endl;
                #endif
            }
            else {
                istat = -1; // OK if fabs(x) < tol whence phi = 0.0
            }
            r = 0.0;
            s = 0.0;
        }
        else {
            r = std::sqrt(r);
            s = 1.0 / r;
        }

        // Compute z and t
        double z = yj * m_w[2];
        if (std::abs(z) > 1.0) {
            if (std::abs(z) > 1.0+tol) {
                istat  = 1;
                status = 3;
                n_invalid++;
                #if defined(G_DEBUG_PRJ)
                std::cout << "prj_x2s(Phi)..:";
                std::cout << " nx=" << nx;
                std::cout << " ny=" << ny;
                std::cout << " iy=" << iy;
                std::cout << " yp=" << *yp;
                std::cout << " yj=" << yj;
                std::cout << " y0=" << y0;
                std::cout << " phip=" << *phip;
                std::cout << " r=" << r;
                std::cout << " s=" << s;
                std::cout << " z=" << z;
                std::cout << std::endl;
                #endif
                z = 0.0;
            }
            else {
                z = copysign(1.0, z) + y0 * r / gammalib::pi;
            }
        }
        else {
            z = std::asin(z) * m_w[4] + y0 * r / gammalib::pi;
        }
        if (std::abs(z) > 1.0) {
            if (std::abs(z) > 1.0+tol) {
                istat  = 1;
                status = 3;
                n_invalid++;
                #if defined(G_DEBUG_PRJ)
                std::cout << "prj_x2s(Phi)..:";
                std::cout << " nx=" << nx;
                std::cout << " ny=" << ny;
                std::cout << " iy=" << iy;
                std::cout << " yp=" << *yp;
                std::cout << " yj=" << yj;
                std::cout << " y0=" << y0;
                std::cout << " phip=" << *phip;
                std::cout << " r=" << r;
                std::cout << " s=" << s;
                std::cout << " z=" << z;
                std::cout << std::endl;
                #endif
                z = 0.0;
            }
            else {
                z = copysign(1.0, z);
            }
        }
        double t = std::asin(z) * gammalib::rad2deg;

        // Do ...
        for (int ix = 0; ix < mx; ++ix, phip += spt, thetap += spt, statp += spt) {

            // Set status flag
            if (istat < 0 && *thetap >= 0.0) {
                *statp = 1;
                status = 3;
                n_invalid++;
            }
            else {
                *statp = 0;
            }

            // Set values
            *phip  *= s;
            *thetap = t;
            
        }

    } // endfor: did y dependence

    // Handle status code
    if (status == 3) {
        throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid);
    }

    // Return
    return;
}