40 #define G_CONSTRUCT "GHealpix::GHealpix(int& ,std::string& ,std::string&)"
41 #define G_READ "GHealpix::read(GFitsHDU&)"
42 #define G_XY2DIR "GHealpix::xy2dir(GSkyPixel&)"
43 #define G_DIR2XY2 "GHealpix::dir2xy(GSkyDir&)"
44 #define G_NEST2RING "GHealpix::nest2ring(int&)"
45 #define G_RING2NEST "GHealpix::ring2nest(int&)"
46 #define G_PIX2ANG_RING "GHealpix::pix2ang_ring(int, double*, double*)"
47 #define G_PIX2ANG_NEST "GHealpix::pix2ang_nest(int, double*, double*)"
48 #define G_ORDERING_SET "GHealpix::ordering(std::string&)"
49 #define G_INTERPOLATOR "GHealpix::interpolator(double&, double&)"
50 #define G_NEIGHBOURS "GHealpix::neighbours(GSkyPixel&)"
51 #define G_BOUNDARIES "GHealpix::boundaries(GSkyPixel&, int&)"
62 const int jrll[12] = {2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};
63 const int jpll[12] = {1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};
66 const int nb_facearray[][12] = {{ 8, 9,10,11,-1,-1,-1,-1,10,11, 8, 9 },
67 { 5, 6, 7, 4, 8, 9,10,11, 9,10,11, 8 },
68 { -1,-1,-1,-1, 5, 6, 7, 4,-1,-1,-1,-1 },
69 { 4, 5, 6, 7,11, 8, 9,10,11, 8, 9,10 },
70 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 },
71 { 1, 2, 3, 0, 0, 1, 2, 3, 5, 6, 7, 4 },
72 { -1,-1,-1,-1, 7, 4, 5, 6,-1,-1,-1,-1 },
73 { 3, 0, 1, 2, 3, 0, 1, 2, 4, 5, 6, 7 },
74 { 2, 3, 0, 1,-1,-1,-1,-1, 0, 1, 2, 3 }};
124 const std::string& order,
132 std::string msg =
"Invalid nside parameter "+
gammalib::str(nside)+
133 " specified. Please specify one of 1,2,4,8,16,32,"
134 "64,128,256,512,1024,2048,4096 or 8192.";
293 if (hdu.
string(
"PIXTYPE") !=
"HEALPIX") {
294 std::string msg =
"FITS HDU does not contain Healpix data. Please "
295 "make sure that the \"PIXTYPE\" keyword in the FITS "
296 "HUD is set to \"HEALPIX\".";
304 ordering = hdu.
string(
"ORDERING");
307 ordering = hdu.
string(
"ORDER");
315 coordsys = hdu.
string(
"HIER_CRD");
317 else if (hdu.
has_card(
"COORDSYS")) {
318 coordsys = hdu.
string(
"COORDSYS");
362 std::string pixtype =
"HEALPIX";
365 hdu.
card(
"PIXTYPE", pixtype,
"HEALPix pixelisation");
366 hdu.
card(
"NSIDE",
nside(),
"HEALPix resolution parameter");
367 hdu.
card(
"FIRSTPIX", 0,
"Index of first pixel");
368 hdu.
card(
"LASTPIX",
npix()-1,
"Index of last pixel");
370 "Pixel ordering scheme, either RING or NESTED");
372 "Coordinate system, either CEL or GAL");
387 if (!pixel.
is_1D()) {
388 std::string msg =
"Sky map pixel "+pixel.
print()+
" is not"
390 "Only 1-dimensional pixels are supported by the"
391 " Healpix projection.";
504 return (interpolator);
523 ordering =
"UNKNOWN";
546 if (uordering ==
"RING") {
549 else if (uordering ==
"NESTED" || uordering ==
"NEST") {
553 std::string msg =
"Invalid ordering parameter \""+ordering+
"\" "
554 "encountered. Please specify one of \"RING\", "
555 "\"NESTED\" or \"NEST\"";
582 if (!pixel.
is_1D()) {
583 std::string msg =
"Sky map pixel "+pixel.
print()+
" is not"
585 "Only 1-dimensional pixels are supported by the"
586 " Healpix projection.";
591 std::vector<int> result;
597 pix2xyf(
int(pixel), &ix, &iy, &face_num);
603 if ((ix > 0) && (ix < nsm1) && (iy > 0) && (iy < nsm1)) {
607 for (
int m = 0; m < 8; ++m) {
609 result.push_back(index);
615 int fpix = int(face_num) << (2*
m_order);
622 result.push_back(fpix + pxm + py0);
623 result.push_back(fpix + pxm + pyp);
624 result.push_back(fpix + px0 + pyp);
625 result.push_back(fpix + pxp + pyp);
626 result.push_back(fpix + pxp + py0);
627 result.push_back(fpix + pxp + pym);
628 result.push_back(fpix + px0 + pym);
629 result.push_back(fpix + pxm + pym);
636 for (
int i = 0; i < 8; ++i) {
673 result.push_back(
xyf2ring(x, y, f));
676 result.push_back(
xyf2nest(x, y, f));
682 result.push_back(-1);
714 if (!pixel.
is_1D()) {
715 std::string msg =
"Sky map pixel "+pixel.
print()+
" is not"
717 "Only 1-dimensional pixels are supported by the"
718 " Healpix projection.";
729 pix2xyf(
int(pixel), &ix, &iy, &face);
733 double xc = (ix + 0.5) /
m_nside;
734 double yc = (iy + 0.5) /
m_nside;
735 double d = 1.0 / (step*
m_nside);
738 for (
int i = 0; i < step; ++i) {
745 xyf2loc(xc+dc-i*d, yc+dc, face, &z, &phi);
749 xyf2loc(xc-dc, yc+dc-i*d, face, &z, &phi);
753 xyf2loc(xc-dc+i*d, yc-dc, face, &z, &phi);
757 xyf2loc(xc+dc, yc-dc+i*d, face, &z, &phi);
811 result.append(
"=== GHealpix ===");
860 for (
int m = 0; m < 0x100; ++m) {
862 (m&0x1 ) | ((m&0x2 ) << 7) | ((m&0x4 ) >> 1) | ((m&0x8 ) << 6)
863 | ((m&0x10) >> 2) | ((m&0x20) << 5) | ((m&0x40) >> 3) | ((m&0x80) << 4);
865 (m&0x1 ) | ((m&0x2 ) << 1) | ((m&0x4 ) << 2) | ((m&0x8 ) << 3)
866 | ((m&0x10) << 4) | ((m&0x20) << 5) | ((m&0x40) << 6) | ((m&0x80) << 7);
955 int raw = (value & 0x5555) | ((value & 0x55550000) >> 15);
956 int compressed =
ctab[raw & 0xff] | (
ctab[raw >> 8] << 4);
975 int spread =
utab[value & 0xff] | (
utab[(value >> 8) & 0xff] << 16);
1060 iring = (1+
isqrt(1+2*pix)) >> 1;
1061 iphi = (pix+1) - 2*iring*(iring-1);
1064 *face = (iphi-1)/nr;
1072 iphi = ip - tmp * 4 * m_nside + 1;
1073 kshift = (iring +
m_nside) & 1;
1075 int ire = iring - m_nside + 1;
1076 int irm = nl2 + 2 - ire;
1077 int ifm = iphi - ire/2 + m_nside - 1;
1078 int ifp = iphi - irm/2 + m_nside - 1;
1087 *face = (ifp==ifm) ? (ifp|4) : ((ifp<ifm) ? ifp : (ifm+8));
1093 iring = (1+
isqrt(2*ip-1))>>1;
1094 iphi = 4 * iring + 1 - (ip - 2*iring*(iring-1));
1097 iring = 2 * nl2 - iring;
1098 *face = 8 + (iphi-1)/nr;
1103 int ipt = 2 * iphi -
jpll[*face] * nr - kshift -1;
1107 *ix = (ipt-irt) >> 1;
1108 *iy = (-ipt-irt) >> 1;
1129 int pix = (int(face) << (2 *
m_order)) +
1162 int kshift = 1-shifted;
1163 int jp = (
jpll[face]*nr + ix - iy + 1 + kshift) / 2;
1173 return (n_before + jp - 1);
1190 double* z,
double* phi)
const
1193 double jr =
jrll[face] - x - y;
1199 double tmp = nr*nr / 3.0;
1204 double tmp = nr*nr / 3.0;
1209 *z = (2.0-jr) * 2.0/3.0;
1213 double tmp =
jpll[face] * nr + x - y;
1240 double sintheta =
std::sqrt((1.0 - z) * (1.0 + z));
1248 dir.
radec(longitude, latitude);
1251 dir.
lb(longitude, latitude);
1275 int nstest = 1 << m;
1276 if (nside == nstest) {
1305 std::string msg =
"A hierarchical map projection is required.";
1316 int iring =
xyf2ring(ix, iy, face);
1339 std::string msg =
"A hierarchical map projection is required.";
1350 int iring =
xyf2nest(ix, iy, face);
1367 int raw = (ipix & 0x5555) | ((ipix & 0x55550000) >> 15);
1368 *x =
ctab[raw & 0xff] | (
ctab[raw >> 8] << 4);
1371 raw = ((ipix & 0xaaaa) >> 1) | ((ipix & 0xaaaa0000) >> 16);
1372 *y =
ctab[raw & 0xff] | (
ctab[raw >> 8] << 4);
1388 return utab[x&0xff] | (
utab[x>>8]<<16) | (
utab[y&0xff]<<1) | (
utab[y>>8]<<17);
1412 int iring = int(0.5*(1+
isqrt(1+2*ipix)));
1413 int iphi = (ipix+1) - 2*iring*(iring-1);
1422 int iphi = ip%(4*
m_nside) + 1;
1423 double fodd = ((iring+
m_nside)&1) ? 1 : 0.5;
1432 int iring = int(0.5*(1+
isqrt(2*ip-1)));
1433 int iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
1463 int face_num = ipix >> (2*
m_order);
1472 int jr = (
jrll[face_num] <<
m_order) - ix - iy - 1;
1501 int jp = (
jpll[face_num]*nr + ix - iy + 1 + kshift) / 2;
1502 if (jp > nl4) jp -= nl4;
1503 if (jp < 1) jp += nl4;
1526 double za = fabs(z);
1531 double temp1 =
m_nside*(0.5+tt);
1532 double temp2 =
m_nside*z*0.75;
1533 int jp = int(temp1-temp2);
1534 int jm = int(temp1+temp2);
1535 int ir =
m_nside + 1 + jp - jm;
1536 int kshift = 1 - (ir & 1);
1537 int ip = (jp+jm-
m_nside+kshift+1)/2;
1544 double tp = tt - int(tt);
1546 int jp = int(tp*tmp);
1547 int jm = int((1.0-tp)*tmp);
1548 int ir = jp + jm + 1;
1549 int ip = int(tt*ir);
1552 ipix = 2*ir*(ir-1) + ip;
1576 double za = fabs(z);
1581 double temp1 =
ns_max*(0.5+tt);
1582 double temp2 =
ns_max*z*0.75;
1583 int jp = int(temp1-temp2);
1584 int jm = int(temp1+temp2);
1588 face_num = (ifp==4) ? 4: ifp+4;
1602 int jp = int(tp*tmp);
1603 int jm = int((1.0-tp)*tmp);
1619 int ipf =
xy2pix(ix, iy);
1621 return ipf + (face_num<<(2*
m_order));
1642 double acostheta =
std::abs(costheta);
1646 iring = int(
m_nside * (2.0 - 1.5 * costheta));
1652 if (costheta <= 0.0) {
1653 iring = 4 *
m_nside - iring - 1;
1677 bool* shifted)
const
1682 *ringpix = 4 * ring;
1683 *startpix = 2 * ring * (ring-1);
1688 *shifted = ((ring-
m_nside) & 1) == 0;
1723 bool* shifted)
const
1726 int northring = (ring > 2 *
m_nside) ? 4 *
m_nside - ring : ring;
1730 double tmp = northring * northring *
m_fact2;
1731 double costheta = 1.0 - tmp;
1732 double sintheta =
std::sqrt(tmp * (2.0-tmp));
1733 *startpix = 2 * northring * (northring - 1);
1734 *ringpix = 4 * northring;
1741 *shifted = ((northring -
m_nside) & 1) == 0;
1746 if (northring != ring) {
1777 std::string msg =
"Colatitude "+
gammalib::str(theta)+
" is outside "
1778 "valid range [0,pi].";
1797 double tmp = (phi/dphi - 0.5*shift);
1798 int i1 = (tmp < 0.0) ? int(tmp)-1 : int(tmp);
1799 double w1 = (phi - (i1+0.5*shift)*dphi) / dphi;
1807 interpolator.
index1() = sp + i1;
1808 interpolator.
index2() = sp + i2;
1809 interpolator.
weight1() = 1.0 - w1;
1818 double tmp = (phi/dphi - 0.5*shift);
1819 int i1 = (tmp < 0.0) ? int(tmp)-1 : int(tmp);
1820 double w1 = (phi - (i1+0.5*shift)*dphi) / dphi;
1828 interpolator.
index3() = sp + i1;
1829 interpolator.
index4() = sp + i2;
1830 interpolator.
weight3() = 1.0 - w1;
1837 double wtheta = theta/theta2;
1838 interpolator.
weight3() *= wtheta;
1839 interpolator.
weight4() *= wtheta;
1840 double fac = (1.0-wtheta)*0.25;
1843 interpolator.
weight3() += fac;
1844 interpolator.
weight4() += fac;
1845 interpolator.
index1() = (interpolator.
index3() + 2) & 3;
1846 interpolator.
index2() = (interpolator.
index4() + 2) & 3;
1851 double wtheta = (theta-theta1) / (gammalib::pi-theta1);
1852 interpolator.
weight1() *= (1.0 - wtheta);
1853 interpolator.
weight2() *= (1.0 - wtheta);
1854 double fac = wtheta*0.25;
1855 interpolator.
weight1() += fac;
1856 interpolator.
weight2() += fac;
1865 double wtheta = (theta-theta1) / (theta2-theta1);
1866 interpolator.
weight1() *= (1.0 - wtheta);
1867 interpolator.
weight2() *= (1.0 - wtheta);
1868 interpolator.
weight3() *= wtheta;
1869 interpolator.
weight4() *= wtheta;
1916 double sintheta =
std::sqrt((1.0 - z) * (1.0 + z));
1917 vector[0] = sintheta *
std::cos(phi);
1918 vector[1] = sintheta *
std::sin(phi);
double m_solidangle
Solid angle of pixel.
GSkyDirs boundaries(const GSkyPixel &pixel, const int &step=1) const
Return pixel boundaries.
void nest2xyf(const int &pix, int *ix, int *iy, int *face) const
Convert pixel number in nested scheme to (x,y,face) tuple.
std::string print(const GChatter &chatter=NORMAL) const
Print pixel.
void init_members(void)
Initialise class members.
virtual void clear(void)
Clear object.
GHealpix(void)
Void constructor.
bool has_card(const int &cardno) const
Check existence of header card.
bool is_1D(void) const
Check if pixel is 1D.
double norm(const GVector &vector)
Computes vector norm.
const int & nside(void) const
Returns number of divisions of the side of each base pixel.
GSkyDir & append(const GSkyDir &dir)
Append sky direction to container.
std::vector< int > neighbours(const GSkyPixel &pixel) const
Return neighbouring pixels of a pixel.
void copy_members(const GHealpix &wcs)
Copy class members.
Sky directions container class definition.
GHealpix & operator=(const GHealpix &wcs)
Assignment operator.
GVector abs(const GVector &vector)
Computes absolute of vector elements.
void lb(const double &l, const double &b)
Set galactic sky direction (radians)
Abstract FITS extension base class.
virtual GSkyPixel dir2pix(const GSkyDir &dir) const
Returns sky map pixel of sky coordinate.
int & index2(void)
Access index 2.
const double & b(void) const
Return galactic latitude in radians.
GVector cos(const GVector &vector)
Computes cosine of vector elements.
virtual void read(const GFitsHDU &hdu)
Read Healpix definition from FITS header.
int m_nside
Number of divisions of each base pixel (1-8192)
unsigned int isqrt(unsigned int arg) const
Integer n that fulfills n*n <= arg < (n+1)*(n+1)
double modulo(const double &v1, const double &v2)
Returns the remainder of the division.
double max_pixrad(void) const
Return maximum angular distance between pixel centre and corners.
virtual GBilinear interpolator(const GSkyDir &dir) const
Return interpolator for given sky direction.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print WCS information.
void pix2ang_ring(int ipix, double *theta, double *phi) const
Convert pixel index to (theta,phi) angles for ring ordering.
virtual GSkyProjection & operator=(const GSkyProjection &proj)
Assignment operator.
void ring2xyf(const int &pix, int *ix, int *iy, int *face) const
Convert pixel number in ring scheme to (x,y,face) tuple.
double acos(const double &arg)
Computes acos by avoiding NaN due to rounding errors.
void get_ring_info(const int &ring, int *startpix, int *ringpix, bool *shifted) const
Returns useful information about a given ring of the projection.
double & weight2(void)
Access weight 2.
const int nb_swaparray[][3]
int nside2order(const int &nside) const
Convert nside to order.
int m_ordering
Pixel ordering (0=ring, 1=nested, -1=?)
int xyf2ring(const int &ix, const int &iy, const int &face) const
Convert (x,y,face) tuple to pixel number in ring scheme.
void pix2ang_nest(int ipix, double *theta, double *phi) const
Convert pixel index to (theta,phi) angles for nested ordering.
HealPix projection class definition.
const double & ra(void) const
Return Right Ascension in radians.
int m_ncap
Number of pixels in polar cap.
void radec(const double &ra, const double &dec)
Set equatorial sky direction (radians)
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
virtual GSkyDir pix2dir(const GSkyPixel &pixel) const
Returns sky direction of pixel.
HealPix projection class interface definition.
int spread_bits(const int &value) const
Spread Bits.
int ang2pix_z_phi_nest(double z, double phi) const
Returns pixel which contains angular coordinates (z,phi)
GVector set_z_phi(const double &z, const double &phi) const
Return 3D vector.
GVector cross(const GVector &a, const GVector &b)
Vector cross product.
Bilinear interpolator class.
int & index1(void)
Access index 1.
const int nb_facearray[][12]
int ring2nest(const int &pix) const
Converts pixel number in ring indexing scheme to nested scheme.
int & index4(void)
Access index 4.
int m_coordsys
0=CEL, 1=GAL
void pix2xy(const int &ipix, int *x, int *y) const
Convert pixel index to (x,y) coordinate.
double angle(const GVector &a, const GVector &b)
Computes angle between vectors.
int integer(const std::string &keyname) const
Return card value as integer.
const double & l(void) const
Return galactic longitude in radians.
const double & dec(void) const
Return Declination in radians.
int compress_bits(const int &value) const
Compress Bits.
const int & npix(void) const
Returns number of pixels.
int nest2ring(const int &pix) const
Converts pixel number in nested indexing scheme to ring scheme.
Vector class interface definition.
const std::string & extname(void) const
Return extension name.
int xyf2nest(const int &ix, const int &iy, const int &face) const
Convert (x,y,face) tuple to pixel number in nested scheme.
GVector asin(const GVector &vector)
Computes arcsin of vector elements.
double & weight3(void)
Access weight 3.
virtual std::string coordsys(void) const
Returns coordinate system.
void free_members(void)
Delete class members.
int xy2pix(int x, int y) const
Convert (x,y) coordinate to pixel.
int & index3(void)
Access index 3.
virtual bool compare(const GSkyProjection &proj) const
Returns true if argument is identical.
GSkyDir loc2dir(const double &z, const double &phi) const
Convert local coordinate into sky direction.
double & weight4(void)
Access weight 4.
int ang2pix_z_phi_ring(double z, double phi) const
Returns pixel which contains angular coordinates (z,phi)
void xyf2loc(const double &x, const double &y, const int &face, double *z, double *phi) const
Convert (x,y,f) tuple into local coordinates.
double & weight1(void)
Access weight 1.
std::string ordering(void) const
Returns ordering parameter.
virtual ~GHealpix(void)
Destructor.
GVector sin(const GVector &vector)
Computes sine of vector elements.
std::string string(const std::string &keyname) const
Return card value as string.
Exception handler interface definition.
void pix2xyf(const int &pix, int *ix, int *iy, int *face) const
Convert pixel number in to (x,y,face) tuple.
void init_members(void)
Initialise class members.
std::string toupper(const std::string &s)
Convert string to upper case.
double atan2(const double &y, const double &x)
Compute arc tangens in radians.
Abstract sky projection base class.
int m_num_pixels
Number of pixels in projection.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
virtual GHealpix * clone(void) const
Clone instance.
int ring_above(const double &z) const
Get ring index north of cos(theta)
virtual void write(GFitsHDU &hdu) const
Write Healpix definition into FITS HDU.
GFitsHeaderCard & card(const int &cardno)
Return header card.
Mathematical function definitions.
void free_members(void)
Delete class members.
Sky directions container class.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.