39 #define G_READ "GWcs::read(GFitsHDU&)"
40 #define G_PIX2DIR "GWcs::pix2dir(int&)"
41 #define G_DIR2PIX "GWcs::dir2pix(GSkyDir&)"
42 #define G_CRVAL "GWcs::crval(int&)"
43 #define G_CRPIX "GWcs::crpix(int&)"
44 #define G_CDELT "GWcs::cdelt(int&)"
45 #define G_WCS_SET_CTYPE "GWcs::wcs_set_ctype()"
46 #define G_WCS_P2S "GWcs::wcs_s2p(int, int, double*, double*, double*,"\
47 " double*, double*, int*)"
48 #define G_WCS_S2P "GWcs::wcs_s2p(int, int, double*, double*, double*,"\
49 " double*, double*, int*)"
50 #define G_CEL_SET "GWcs::cel_set()"
51 #define G_LIN_MATINV "GWcs::lin_matinv(std::vector<double>&,"\
52 " std::vector<double>&)"
59 #define G_SOLIDANGLE_OPTION 2 // 1=sin/cos, 2=tan, 3=vectors
104 const double& crval1,
const double& crval2,
105 const double& crpix1,
const double& crpix2,
112 set_members(coords, crval1, crval2, crpix1, crpix2, cdelt1, cdelt2);
237 std::string ctype1 = hdu.
string(
"CTYPE1");
238 std::string ctype2 = hdu.
string(
"CTYPE2");
239 double crval1 = hdu.
real(
"CRVAL1");
240 double crval2 = hdu.
real(
"CRVAL2");
241 double crpix1 = hdu.
real(
"CRPIX1");
242 double crpix2 = hdu.
real(
"CRPIX2");
243 double cdelt1 = (hdu.
has_card(
"CDELT1")) ? hdu.
real(
"CDELT1") : hdu.
real(
"CD1_1");
244 double cdelt2 = (hdu.
has_card(
"CDELT2")) ? hdu.
real(
"CDELT2") : hdu.
real(
"CD2_2");
248 std::string xcoord = ctype1.substr(0,4);
249 std::string ycoord = ctype2.substr(0,4);
250 if (xcoord ==
"RA--" && ycoord ==
"DEC-") {
255 else if (xcoord ==
"DEC-" && ycoord ==
"RA--") {
260 else if (xcoord ==
"GLON" && ycoord ==
"GLAT") {
265 else if (xcoord ==
"GLAT" && ycoord ==
"GLON") {
270 else if (xcoord ==
"ELON" && ycoord ==
"ELAT") {
275 else if (xcoord ==
"ELAT" && ycoord ==
"ELON") {
280 else if (xcoord ==
"HLON" && ycoord ==
"HLAT") {
285 else if (xcoord ==
"HLAT" && ycoord ==
"HLON") {
290 else if (xcoord ==
"SLON" && ycoord ==
"SLAT") {
295 else if (xcoord ==
"SLAT" && ycoord ==
"SLON") {
301 std::string msg =
"Invalid X and/or Y coordinates \""+xcoord+
"\""
302 "/\""+ycoord+
"\" encountered. Please specify a "
303 "FITS HDU with one of \"RA--/DEC-\", "
304 "\"GLON/GLAT\", \"ELON/ELAT\", \"HLON/HLAT\" or "
310 set_members(coords, crval1, crval2, crpix1, crpix2, cdelt1, cdelt2);
348 for (
int i = 0; i <
m_naxis; ++i) {
350 std::string comment =
"Pixel coordinate of reference point (starting from 1)";
357 for (
int i = 0; i <
m_naxis; ++i) {
360 if (
m_cunit.at(i).length() > 0) {
363 comment +=
"Coordinate increment at reference point";
368 for (
int i = 0; i <
m_naxis; ++i) {
369 if (
m_cunit.at(i).length() > 0) {
371 std::string comment =
"Units of coordinate increment and value";
378 for (
int i = 0; i <
m_naxis; ++i) {
394 for (
int i = 0; i <
m_naxis; ++i) {
397 if (
m_cunit.at(i).length() > 0) {
400 comment +=
"Coordinate value at reference point";
405 hdu.
card(
"CROTA2", 0.0,
"[deg] Rotation Angle");
411 hdu.
card(
"LONPOLE",
m_lonpole,
"[deg] Native longitude of celestial pole");
414 hdu.
card(
"LATPOLE",
m_latpole,
"[deg] Native latitude of celestial pole");
425 hdu.
card(
"RADESYS",
m_radesys,
"Equatorial coordinate system");
430 hdu.
card(
"EQUINOX",
m_equinox,
"[yr] Equinox of equatorial coordinates");
496 #if G_SOLIDANGLE_OPTION == 1
502 double a12 = dir1.
dist(dir2);
503 double a14 = dir1.
dist(dir4);
504 double a23 = dir2.dist(dir3);
505 double a34 = dir3.dist(dir4);
509 if (a12 <= 0.0 || a14 <= 0.0) {
512 double a24 = dir2.dist(dir4);
525 double angle2 =
gammalib::acos((cos_a34-cos_a24*cos_a23)/(sin_a24*sin_a23));
526 double angle3 =
gammalib::acos((cos_a24-cos_a34*cos_a23)/(sin_a34*sin_a23));
527 double angle4 =
gammalib::acos((cos_a23-cos_a24*cos_a34)/(sin_a24*sin_a34));
536 else if (a23 <= 0.0 || a34 <= 0.0) {
539 double a24 = dir2.dist(dir4);
552 double angle1 =
gammalib::acos((cos_a24-cos_a12*cos_a14)/(sin_a12*sin_a14));
553 double angle2 =
gammalib::acos((cos_a14-cos_a12*cos_a24)/(sin_a12*sin_a24));
554 double angle4 =
gammalib::acos((cos_a12-cos_a14*cos_a24)/(sin_a14*sin_a24));
565 double a13 = dir1.
dist(dir3);
566 double a24 = dir2.dist(dir4);
583 double angle1 =
std::acos((cos_a13-cos_a34*cos_a14)/(sin_a34*sin_a14));
584 double angle2 =
std::acos((cos_a24-cos_a23*cos_a34)/(sin_a23*sin_a34));
585 double angle3 =
std::acos((cos_a13-cos_a12*cos_a23)/(sin_a12*sin_a23));
586 double angle4 =
std::acos((cos_a24-cos_a14*cos_a12)/(sin_a14*sin_a12));
594 #elif G_SOLIDANGLE_OPTION == 2
597 double solidangle = 0.0;
600 double a12 = dir1.
dist(dir2);
601 double a14 = dir1.
dist(dir4);
602 double a23 = dir2.dist(dir3);
603 double a24 = dir2.dist(dir4);
604 double a34 = dir3.dist(dir4);
608 if (a12 <= 0.0 || a14 <= 0.0) {
609 double s = 0.5 * (a23 + a34 + a24);
618 else if (a23 <= 0.0 || a34 <= 0.0) {
619 double s = 0.5 * (a12 + a24 + a14);
630 double s1 = 0.5 * (a12 + a24 + a14);
637 double s2 = 0.5 * (a23 + a34 + a24);
644 solidangle = 4.0 * (excess1 + excess2);
653 GVector vec2 = dir2.celvector();
654 GVector vec3 = dir3.celvector();
655 GVector vec4 = dir4.celvector();
669 (angle1 + angle2 + angle3 + angle4) -
701 bool update_cache =
true;
705 update_cache =
false;
722 pixcrd[0] = pixel.
x() + 1.0;
723 pixcrd[1] = pixel.
y() + 1.0;
726 wcs_p2s(1, 2, pixcrd, imgcrd, &phi, &theta, world, &stat);
733 dir.
lb_deg(world[0], world[1]);
747 #if defined(G_XY2DIR_DEBUG)
748 std::cout <<
"xy2dir: pixel=" << pixel
749 <<
" (x,y)=(" << pixcrd[0] <<
"," << pixcrd[1] <<
")"
750 <<
" (phi,theta)=(" << phi <<
"," << theta <<
")"
751 <<
" (lng,lat)=(" << world[0] <<
"," << world[1] <<
")"
785 bool update_cache =
true;
789 update_cache =
false;
810 world[0] = dir.
l_deg();
811 world[1] = dir.
b_deg();
815 wcs_s2p(1, 2, world, &phi, &theta, imgcrd, pixcrd, &stat);
819 pixel.
xy(pixcrd[0]-1.0, pixcrd[1]-1.0);
832 #if defined(G_DIR2XY_DEBUG)
833 std::cout <<
"dir2xy: dir=" << dir
834 <<
" (lng,lat)=(" << world[0] <<
"," << world[1] <<
")"
835 <<
" (phi,theta)=(" << phi <<
"," << theta <<
")"
836 <<
" (x,y)=" << pixel << std::endl;
860 const double& crval1,
const double& crval2,
861 const double& crpix1,
const double& crpix2,
862 const double& cdelt1,
const double& cdelt2)
868 set_members(coords, crval1, crval2, crpix1, crpix2, cdelt1, cdelt2);
890 #if defined(G_RANGE_CHECK)
891 if (inx < 0 || inx >=
m_naxis) {
914 #if defined(G_RANGE_CHECK)
915 if (inx < 0 || inx >=
m_naxis) {
938 #if defined(G_RANGE_CHECK)
939 if (inx < 0 || inx >=
m_naxis) {
1046 for (
int i = 0; i <
PVN; ++i) {
1091 const double& crval1,
const double& crval2,
1092 const double& crpix1,
const double& crpix2,
1093 const double& cdelt1,
const double& cdelt2)
1132 bool result =
false;
1135 const GWcs* ptr =
dynamic_cast<const GWcs*
>(&proj);
1139 result = ((
code() == ptr->
code()) &&
1195 for (
int i = 0; i < naxis; ++i) {
1215 for (
int i = 0; i < naxis; ++i) {
1216 for (
int j = 0; j < naxis; ++j) {
1217 m_cd.push_back(0.0);
1283 if (
code() ==
"GLS") {
1394 if (
code().length() != 3) {
1395 std::string msg =
"WCS type code has length "+
1397 "character type code is expected.";
1426 std::string msg =
"Invalid coordinate system identifier "+
1428 "coordinate system identifier needs to be "
1429 "comprised with 0 and 4 (included).";
1463 std::string msg =
"Invalid coordinate system identifier "+
1465 "coordinate system identifier needs to be "
1466 "comprised with 0 and 4 (included).";
1516 const double* pixcrd,
1530 std::string msg =
"Number of coordinates "+
gammalib::str(ncoord)+
1531 " is less than 1. Please specify at least one "
1535 if ((ncoord > 1) && (nelem <
m_naxis)) {
1536 std::string msg =
"Vector length "+
gammalib::str(nelem)+
" of each "
1537 "axis is smaller than the number of axes. Please "
1538 "specify a vector length that equals at least the "
1544 lin_p2x(ncoord, nelem, pixcrd, imgcrd);
1591 const double* world,
1605 std::string msg =
"Number of coordinates "+
gammalib::str(ncoord)+
1606 " is less than 1. Please specify at least one "
1610 if ((ncoord > 1) && (nelem <
m_naxis)) {
1611 std::string msg =
"Vector length "+
gammalib::str(nelem)+
" of each "
1612 "axis is smaller than the number of axes. Please "
1613 "specify a vector length that equals at least the "
1624 phi, theta, imgcrd+
m_lng, imgcrd+
m_lat, stat);
1629 lin_x2p(ncoord, nelem, imgcrd, pixcrd);
1675 for (
int i = 0; i <
m_crval.size(); ++i) {
1677 result.append(
", ");
1680 if (
m_cunit[i].length() > 0) {
1681 result.append(
" "+
m_cunit[i]);
1686 for (
int i = 0; i <
m_crpix.size(); ++i) {
1688 result.append(
", ");
1694 for (
int i = 0; i <
m_cdelt.size(); ++i) {
1696 result.append(
", ");
1699 if (
m_cunit[i].length() > 0) {
1700 result.append(
" "+
m_cunit[i]);
1722 result.append(
"Not used. Theta_p determined uniquely by"
1723 " CRVALia and LONPOLEa keywords.");
1726 result.append(
"Required to select between two valid solutions"
1730 result.append(
"Theta_p was specified solely by LATPOLE.");
1733 result.append(
"UNDEFINED");
1739 for (
int k = 0; k < 4; ++k) {
1741 result.append(
", ");
1745 result.append(
") deg");
1749 for (
int k = 0; k < 5; ++k) {
1751 result.append(
", ");
1755 result.append(
" deg");
1763 result.append(
"True");
1766 result.append(
"False");
1772 result.append(
"True");
1775 result.append(
"False");
1778 for (
int k = 0; k <
m_piximg.size(); ++k) {
1780 result.append(
", ");
1786 for (
int k = 0; k <
m_imgpix.size(); ++k) {
1788 result.append(
", ");
1797 result.append(
"True");
1800 result.append(
"False");
1806 result.append(
"True");
1809 result.append(
"False");
1844 result.append(
"UNDEFINED");
1881 for (
int k = 0; k < 5; ++k) {
1924 const double tol = 1.0e-10;
1938 double lng0 =
m_ref[0];
1939 double lat0 =
m_ref[1];
1940 double phip =
m_ref[2];
1941 double latp =
m_ref[3];
1946 phip = (lat0 <
m_theta0) ? 180.0 : 0.0;
1948 if (phip < -180.0) {
1951 else if (phip > 180.0) {
1997 double x = cthe0 * cphip;
2005 std::string msg =
"Sine of reference latitude is "+
2007 "zero is expected.";
2016 else if (latp < -90.0) {
2024 double slz = slat0/z;
2035 std::string msg =
"Sine of reference latitude divided "
2037 " significantly differs from +/- 1.";
2048 double latp1 = u + v;
2049 if (latp1 > 180.0) {
2052 else if (latp1 < -180.0) {
2057 double latp2 = u - v;
2058 if (latp2 > 180.0) {
2061 else if (latp2 < -180.0) {
2072 latp = (
std::abs(latp1) < 90.0+tol) ? latp1 : latp2;
2075 latp = (
std::abs(latp2) < 90.0+tol) ? latp2 : latp1;
2083 else if (latp < -90.0) {
2099 else if (latp > 0.0) {
2100 lngp = lng0 + phip -
m_phi0 - 180.0;
2105 lngp = lng0 - phip +
m_phi0;
2113 double y = sphip*cthe0/clat0;
2114 if (x == 0.0 && y == 0.0) {
2115 std::string msg =
"(X,Y) values are (0,0), yet at least one "
2116 "of X or Y should differ from zero.";
2128 else if (lngp > 360.0) {
2136 else if (lngp < -360.0) {
2157 std::string msg =
"Absolute value of latitude of pole "+
2159 "significantly from 90 degrees which results in an "
2160 "ill-conditioned coordinate transformation.";
2212 prj_x2s(nx, ny, sxy, 1, x, y, phi, theta, stat);
2215 int nphi = (ny > 0) ? (nx*ny) : nx;
2218 sph_x2s(nphi, 0, 1, sll, phi, theta, lng, lat);
2265 sph_s2x(nlng, nlat, sll, 1, lng, lat, phi, theta);
2275 nphi = (nlat > 0) ? (nlng*nlat) : nlng;
2280 prj_s2x(nphi, ntheta, 1, sxy, phi, theta, x, y, stat);
2315 const double* theta,
2320 const double tol = 1.0e-5;
2341 const double* phip = phi;
2342 const double* thetap = theta;
2351 for (
int itheta = 0; itheta < ntheta; ++itheta, phip += spt, thetap += spt) {
2352 for (
int iphi = 0; iphi < mphi; ++iphi, lngp += sll, latp += sll) {
2355 *lngp = *phip + dlng;
2369 if (*lngp > 360.0) {
2372 else if (*lngp < -360.0) {
2388 for (
int itheta = 0; itheta < ntheta; ++itheta, phip += spt, thetap += spt) {
2389 for (
int iphi = 0; iphi < mphi; ++iphi, lngp += sll, latp += sll) {
2392 *lngp = dlng - *phip;
2406 if (*lngp > 360.0) {
2409 else if (*lngp < -360.0) {
2423 const double* phip = phi;
2425 int rowlen = nphi*sll;
2426 for (
int iphi = 0; iphi < nphi; ++iphi, rowoff += sll, phip += spt) {
2427 double dphi = *phip -
m_euler[2];
2428 double* lngp = lng + rowoff;
2429 for (
int itheta = 0; itheta < mtheta; ++itheta, lngp += rowlen) {
2435 const double* thetap = theta;
2438 for (
int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) {
2446 double costhe3 = costhe *
m_euler[3];
2447 double costhe4 = costhe * m_euler[4];
2448 double sinthe3 = sinthe * m_euler[3];
2449 double sinthe4 = sinthe * m_euler[4];
2452 for (
int iphi = 0; iphi < mphi; ++iphi, lngp += sll, latp += sll) {
2455 double dphi = *lngp;
2461 double x = sinthe4 - costhe3*cosphi;
2462 double y = -costhe*sinphi;
2467 costhe3*(1.0 - cosphi);
2472 if (x != 0.0 || y != 0.0) {
2476 dlng = (m_euler[1] < 90.0) ? dphi + 180.0 : -dphi;
2480 *lngp = m_euler[0] + dlng;
2483 if (m_euler[0] >= 0.0) {
2493 if (*lngp > 360.0) {
2496 else if (*lngp < -360.0) {
2502 if (fmod(dphi,180.0) == 0.0) {
2503 *latp = *thetap + cosphi*m_euler[1];
2504 if (*latp > 90.0) *latp = 180.0 - *latp;
2505 if (*latp < -90.0) *latp = -180.0 - *latp;
2511 double z = sinthe3 + costhe4*cosphi;
2515 else if (z < -0.99) {
2558 double* theta)
const
2561 const double tol = 1.0e-5;
2580 const double* lngp = lng;
2581 const double* latp = lat;
2583 double* thetap = theta;
2592 for (
int ilat = 0; ilat < nlat; ++ilat, lngp += sll, latp += sll) {
2593 for (
int ilng = 0; ilng < mlng; ++ilng, phip += spt, thetap += spt) {
2596 *phip = fmod(*lngp + dphi, 360.0);
2600 if (*phip > 180.0) {
2603 else if (*phip < -180.0) {
2619 for (
int ilat = 0; ilat < nlat; ++ilat, lngp += sll, latp += sll) {
2620 for (
int ilng = 0; ilng < mlng; ++ilng, phip += spt, thetap += spt) {
2623 *phip = fmod(dphi - *lngp, 360.0);
2627 if (*phip > 180.0) {
2630 else if (*phip < -180.0) {
2645 const double* lngp = lng;
2647 int rowlen = nlng * spt;
2648 for (
int ilng = 0; ilng < nlng; ++ilng, rowoff += spt, lngp += sll) {
2649 double dlng = *lngp -
m_euler[0];
2650 double* phip = phi + rowoff;
2651 for (
int ilat = 0; ilat < mlat; ++ilat, phip += rowlen) {
2657 const double* latp = lat;
2659 double* thetap = theta;
2660 for (
int ilat = 0; ilat < nlat; ++ilat, latp += sll) {
2666 double coslat3 = coslat*
m_euler[3];
2667 double coslat4 = coslat*m_euler[4];
2668 double sinlat3 = sinlat*m_euler[3];
2669 double sinlat4 = sinlat*m_euler[4];
2672 for (
int ilng = 0; ilng < mlng; ++ilng, phip += spt, thetap += spt) {
2675 double dlng = *phip;
2681 double x = sinlat4 - coslat3*coslng;
2682 double y = -coslat*sinlng;
2687 coslat3*(1.0 - coslng);
2692 if (x != 0.0 || y != 0.0) {
2696 if (m_euler[1] < 90.0) {
2697 dphi = dlng - 180.0;
2705 *phip = fmod(m_euler[2] + dphi, 360.0);
2708 if (*phip > 180.0) {
2711 else if (*phip < -180.0) {
2717 if (fmod(dlng, 180.0) == 0.0) {
2718 *thetap = *latp + coslng*m_euler[1];
2719 if (*thetap > 90.0) *thetap = 180.0 - *thetap;
2720 if (*thetap < -90.0) *thetap = -180.0 - *thetap;
2726 double z = sinlat3 + coslat4*coslng;
2730 else if (z < -0.99) {
2796 for (
int i = 0; i < naxis; ++i) {
2802 for (
int j = 0; j < naxis; ++j) {
2804 m_pc.push_back(1.0);
2807 m_pc.push_back(0.0);
2837 for (
int i = 0, index = 0; i <
m_naxis; ++i) {
2838 for (
int j = 0; j <
m_naxis; ++j, ++index) {
2840 if (
m_pc[index] != 1.0) {
2846 if (
m_pc[index] != 0.0) {
2858 #if defined(G_LIN_MATINV_FORCE_PC)
2860 std::cout <<
"DEBUG: Force PC usage in linear transformations." << std::endl;
2867 for (
int i = 0, index = 0; i <
m_naxis; ++i) {
2868 for (
int j = 0; j <
m_naxis; ++j, ++index) {
2901 const double* pixcrd,
2902 double* imgcrd)
const
2910 const double* pix = pixcrd;
2911 double* img = imgcrd;
2917 for (
int k = 0; k < ncoord; ++k) {
2920 for (
int i = 0; i <
m_naxis; ++i) {
2936 for (
int k = 0; k < ncoord; ++k) {
2939 for (
int i = 0; i <
m_naxis; ++i) {
2945 for (
int j = 0; j <
m_naxis; ++j) {
2946 double temp = *(pix++) -
m_crpix[j];
2980 const double* imgcrd,
2981 double* pixcrd)
const
2989 const double* img = imgcrd;
2990 double* pix = pixcrd;
2996 for (
int k = 0; k < ncoord; ++k) {
2999 for (
int i = 0; i <
m_naxis; ++i) {
3015 for (
int k = 0; k < ncoord; ++k) {
3018 for (
int j = 0, ji = 0; j <
m_naxis; ++j) {
3020 for (
int i = 0; i <
m_naxis; ++i, ++ji) {
3053 std::vector<double>& inv)
const
3059 std::vector<int> mxl;
3060 std::vector<int> lxm;
3061 std::vector<double> rowmax;
3062 std::vector<double> lu = mat;
3069 for (
int i = 0, ij = 0; i <
m_naxis; ++i) {
3076 rowmax.push_back(0.0);
3077 for (
int j = 0; j <
m_naxis; ++j, ++ij) {
3079 if (dtemp > rowmax[i]) {
3085 if (rowmax[i] == 0.0) {
3086 std::string msg =
"Singular matrix encountered in row "+
3095 for (
int k = 0; k <
m_naxis; ++k) {
3098 double colmax =
std::abs(lu[k*m_naxis+k]) / rowmax[k];
3100 for (
int i = k+1; i <
m_naxis; ++i) {
3101 int ik = i*m_naxis + k;
3102 double dtemp =
std::abs(lu[ik]) / rowmax[i];
3103 if (dtemp > colmax) {
3113 for (
int j = 0, pj = pivot*m_naxis, kj = k*m_naxis; j <
m_naxis;
3115 double dtemp = lu[pj];
3121 double dtemp = rowmax[pivot];
3122 rowmax[pivot] = rowmax[k];
3126 int itemp = mxl[pivot];
3127 mxl[pivot] = mxl[k];
3133 for (
int i = k+1; i <
m_naxis; ++i) {
3136 int ik = i*m_naxis + k;
3139 if (lu[ik] != 0.0) {
3142 lu[ik] /= lu[k*m_naxis+k];
3145 for (
int j = k+1; j <
m_naxis; ++j) {
3146 lu[i*m_naxis+j] -= lu[ik]*lu[k*m_naxis+j];
3157 for (
int i = 0; i <
m_naxis; ++i) {
3162 for (
int k = 0; k <
m_naxis; ++k) {
3165 inv[lxm[k]*m_naxis+k] = 1.0;
3168 for (
int i = lxm[k]+1; i <
m_naxis; ++i) {
3169 for (
int j = lxm[k]; j < i; ++j) {
3170 inv[i*m_naxis+k] -= lu[i*m_naxis+j]*inv[j*m_naxis+k];
3175 for (
int i = m_naxis-1; i >= 0; --i) {
3176 for (
int j = i+1; j <
m_naxis; ++j) {
3177 inv[i*m_naxis+k] -= lu[i*m_naxis+j]*inv[j*m_naxis+k];
3179 inv[i*m_naxis+k] /= lu[i*m_naxis+i];
3211 for (
int k = 4; k <
PVN; ++k) {
3296 register double* phip = phi;
3297 register double* thetap = theta;
3298 register int* statp = stat;
3301 for (
int itheta = 0; itheta < ntheta; ++itheta) {
3304 for (
int iphi = 0; iphi < nphi; ++iphi, phip += spt, thetap += spt, statp++) {
3310 if (*phip < -180.0) {
3311 if (*phip < -180.0-tol) {
3321 else if (180.0 < *phip) {
3322 if (180.0+tol < *phip) {
3332 if (*thetap < -90.0) {
3333 if (*thetap < -90.0-tol) {
3343 else if (90.0 < *thetap) {
3344 if (90.0+tol < *thetap) {
bool m_linset
Linear transformation is set.
void wcs_p2s(int ncoord, int nelem, const double *pixcrd, double *imgcrd, double *phi, double *theta, double *world, int *stat) const
Pixel-to-world transformation.
void init_members(void)
Initialise class members.
GSkyPixel m_last_pix2dir_pix
Last pixel for pix2dir.
void cel_ini(void) const
Initialise celestial transformation parameters.
std::vector< double > m_imgpix
Image to pixel transformation matrix.
bool has_card(const int &cardno) const
Check existence of header card.
void set_members(const std::string &coords, const double &crval1, const double &crval2, const double &crpix1, const double &crpix2, const double &cdelt1, const double &cdelt2)
Set World Coordinate System parameters.
virtual GSkyDir pix2dir(const GSkyPixel &pixel) const
Returns sky direction of sky map pixel.
double dec_deg(void) const
Returns Declination in degrees.
void prj_off(const double &phi0, const double &theta0) const
Compute fiducial offset to force (x,y) = (0,0) at (phi0,theta0)
int m_naxis
Number of axes.
void prj_ini(void) const
Initialise projection parameters.
void x(const double &x)
Set x value of sky map pixel.
std::vector< double > m_crpix
CRPIXja keyvalues for each pixel axis.
void set(const std::string &coords, const double &crval1, const double &crval2, const double &crpix1, const double &crpix2, const double &cdelt1, const double &cdelt2)
Set World Coordinate System parameters.
std::vector< std::string > m_ctype
CTYPEia keyvalues for each coord axis.
GVector abs(const GVector &vector)
Computes absolute of vector elements.
void lin_p2x(int ncoord, int nelem, const double *pixcrd, double *imgcrd) const
Pixel-to-world linear transformation.
std::vector< double > m_piximg
Pixel to image transformation matrix.
Abstract FITS extension base class.
virtual void prj_set(void) const =0
GVector cos(const GVector &vector)
Computes cosine of vector elements.
bool undefined(const double &value) const
Check if value is undefined.
bool m_celset
Celestial transformation is set.
int m_latpreq
LATPOLEa requirement.
void xy(const double &x, const double &y)
Set x and y value of sky map pixel.
void wcs_s2p(int ncoord, int nelem, const double *world, double *phi, double *theta, double *imgcrd, double *pixcrd, int *stat) const
World-to-pixel transformation.
virtual GSkyProjection & operator=(const GSkyProjection &proj)
Assignment operator.
double acos(const double &arg)
Computes acos by avoiding NaN due to rounding errors.
void cel_x2s(int nx, int ny, int sxy, int sll, const double *x, const double *y, double *phi, double *theta, double *lng, double *lat, int *stat) const
Pixel-to-world celestial transformation.
void spc_ini(void)
Initialise spectral transformation parameters.
double crval(const int &inx) const
Return value of reference pixel.
double m_ref[4]
Celestial coordinates of fiducial.
void unset_lock(const int &lock_id=0) const
Releases a previously set OpenMP lock.
void clear(void)
Clear instance.
virtual double solidangle(const GSkyPixel &pixel) const
Returns solid angle of pixel in units of steradians.
void y(const double &y)
Set y value of sky map pixel.
GSkyPixel m_last_dir2pix_pix
Last pixel for dir2pix.
std::vector< double > m_cdelt
CDELTia keyvalues for each coord axis.
void sph_s2x(int nlng, int nlat, int sll, int spt, const double *lng, const double *lat, double *phi, double *theta) const
Rotation in the pixel-to-world direction.
double m_equinox
EQUINOX keyvalue.
void free_members(void)
Delete class members.
void cel_set(void) const
Setup of celestial transformation.
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
virtual std::string code(void) const =0
void wcs_ini(int naxis)
Initialise World Coordinate System.
double real(const std::string &keyname) const
Return card value as double precision.
std::vector< double > m_crval
CRVALia keyvalues for each coord axis.
double m_latpole
LATPOLEa keyvalue.
bool m_unity
Signals unity PC matrix.
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
void init_lock(const int &lock_id=0) const
Initializes an OpenMP lock with a specific name.
double crpix(const int &inx) const
Return reference pixel.
std::vector< double > m_crota
CROTAia keyvalues for each coord axis.
void wcs_set(void) const
Setup of World Coordinate System.
virtual void prj_s2x(int nphi, int ntheta, int spt, int sxy, const double *phi, const double *theta, double *x, double *y, int *stat) const =0
double m_lonpole
LONPOLEa keyvalue.
double acosd(const double &value)
Compute arc cosine in degrees.
double m_restfrq
RESTFRQa keyvalue.
GVector tan(const GVector &vector)
Computes tangens of vector elements.
std::vector< std::string > m_ctype_c
CTYPEia comments for each coord axis.
GVector cross(const GVector &a, const GVector &b)
Vector cross product.
void celvector(const GVector &vector)
Set sky direction from 3D vector in celestial coordinates.
void sincosd(const double &angle, double *s, double *c)
Compute sine and cosine of angle in degrees.
double cdelt(const int &inx) const
Return pixel size.
virtual GWcs & operator=(const GWcs &wcs)
Assignment operator.
void wcs_set_ctype(void) const
Set CTYPEa keywords.
virtual void write(GFitsHDU &hdu) const
Write WCS definition into FITS HDU header.
virtual GSkyPixel dir2pix(const GSkyDir &dir) const
Returns sky map pixel of sky direction.
int m_coordsys
0=CEL, 1=GAL
std::vector< double > m_cd
CDi_ja linear transformation matrix.
double ra_deg(void) const
Returns Right Ascension in degrees.
virtual void read(const GFitsHDU &hdu)
Read WCS definition from FITS header.
double m_pv[PVN]
Projection parameters.
void sph_x2s(int nphi, int ntheta, int spt, int sll, const double *phi, const double *theta, double *lng, double *lat) const
Rotation in the pixel-to-world direction.
virtual bool compare(const GSkyProjection &proj) const
Compares sky projection.
double m_x0
Fiducial x offset.
GSkyDir m_last_pix2dir_dir
Last sky direction for pix2dir.
double m_restwav
RESTWAVa keyvalue.
std::string wcs_print(const GChatter &chatter=NORMAL) const
Print WCS information.
GSkyDir m_last_dir2pix_dir
Last sky direction for dir2pix.
double m_theta0
Native zenith angle of fiducial point.
void radec_deg(const double &ra, const double &dec)
Set equatorial sky direction (degrees)
void lin_ini(int naxis)
Initialise linear transformation parameters.
std::string wcs_print_value(const double &value) const
Helper function for value printing.
void wcs_set_radesys(void) const
Set radesys and equinox members.
virtual std::string coordsys(void) const
Returns coordinate system.
void free_members(void)
Delete class members.
bool m_isolat
True if |latitude| is preserved.
virtual ~GWcs(void)
Destructor.
double m_phi0
Native azimuth angle of fiducial point.
std::vector< double > m_w
Intermediate values.
bool m_has_pix2dir_cache
Has valid pix2dir cache value.
bool m_offset
Force (x,y) = (0,0) at (phi_0,theta_0)
std::string m_radesys
RADESYS keyvalue.
Abstract world coordinate system base class.
int prj_bchk(const double &tol, const int &nphi, const int &ntheta, const int &spt, double *phi, double *theta, int *stat) const
Performs bounds checking on native spherical coordinates.
void clear(void)
Clear sky direction.
GWcs(void)
Void constructor.
double m_y0
Fiducial y offset.
double atan2d(const double &y, const double &x)
Compute arc tangens in degrees.
void copy_members(const GWcs &wcs)
Copy class members.
double cosd(const double &angle)
Compute cosine of angle in degrees.
void set_lock(const int &lock_id=0) const
Sets an OpenMP lock with a specific name.
void lin_matinv(const std::vector< double > &mat, std::vector< double > &inv) const
Invert linear transformation matrix.
void lb_deg(const double &l, const double &b)
Set galactic sky direction (degrees)
GVector sin(const GVector &vector)
Computes sine of vector elements.
void cel_s2x(int nlng, int nlat, int sll, int sxy, const double *lng, const double *lat, double *phi, double *theta, double *x, double *y, int *stat) const
World-to-pixel celestial transformation.
std::string string(const std::string &keyname) const
Return card value as string.
Exception handler interface definition.
std::vector< double > m_pc
PCi_ja linear transformation matrix.
double asind(const double &value)
Compute arc sine in degrees.
bool m_prjset
Projection is set.
void init_members(void)
Initialise class members.
double dist(const GSkyDir &dir) const
Compute angular distance between sky directions in radians.
virtual void clear(void)=0
Clear object.
double l_deg(void) const
Return galactic longitude in degrees.
double b_deg(void) const
Returns galactic latitude in degrees.
Abstract sky projection base class.
void lin_set(void) const
Initialise linear transformation parameters.
static const double UNDEFINED
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
bool m_wcsset
WCS information is set.
double m_euler[5]
Euler angles and functions thereof.
GFitsHeaderCard & card(const int &cardno)
Return header card.
std::vector< std::string > m_cunit
CUNITia keyvalues for each coord axis.
virtual void prj_x2s(int nx, int ny, int sxy, int spt, const double *x, const double *y, double *phi, double *theta, int *stat) const =0
GVector atan(const GVector &vector)
Computes arctan of vector elements.
double sind(const double &angle)
Compute sine of angle in degrees.
virtual std::string name(void) const =0
Abstract world coordinate system base class definition.
double m_r0
Radius of the generating sphere.
Mathematical function definitions.
void lin_x2p(int ncoord, int nelem, const double *imgcrd, double *pixcrd) const
World-to-pixel linear transformation.
bool m_bounds
Enable strict bounds checking.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
bool m_has_dir2pix_cache
Has valid dir2pix cache value.