Commit f834a1a96955e57f199542132efbd331a93dbf85
1 parent
86674206
enhance class
Showing
3 changed files
with
276 additions
and
56 deletions
include/GHealpix.hpp
| @@ -49,9 +49,11 @@ public: | @@ -49,9 +49,11 @@ public: | ||
| 49 | // Methods | 49 | // Methods |
| 50 | void read(const GFitsHDU* hdu); | 50 | void read(const GFitsHDU* hdu); |
| 51 | int nside(void) const; | 51 | int nside(void) const; |
| 52 | + int order(void) const; | ||
| 52 | int num_pixels(void) const; | 53 | int num_pixels(void) const; |
| 53 | double omega(void) const; | 54 | double omega(void) const; |
| 54 | GSkyDir pix2ang(const int& ipix); | 55 | GSkyDir pix2ang(const int& ipix); |
| 56 | + int ang2pix(GSkyDir dir) const; | ||
| 55 | 57 | ||
| 56 | private: | 58 | private: |
| 57 | // Private methods | 59 | // Private methods |
| @@ -59,15 +61,20 @@ private: | @@ -59,15 +61,20 @@ private: | ||
| 59 | void copy_members(const GHealpix& pixels); | 61 | void copy_members(const GHealpix& pixels); |
| 60 | void free_members(void); | 62 | void free_members(void); |
| 61 | GHealpix* clone(void) const; | 63 | GHealpix* clone(void) const; |
| 64 | + int nside2order(int nside); | ||
| 62 | void pix2xy(const int& ipix, int* x, int* y); | 65 | void pix2xy(const int& ipix, int* x, int* y); |
| 66 | + int xy2pix(int x, int y) const; | ||
| 63 | void pix2ang_ring(int ipix, double* theta, double* phi); | 67 | void pix2ang_ring(int ipix, double* theta, double* phi); |
| 64 | void pix2ang_nest(int ipix, double* theta, double* phi); | 68 | void pix2ang_nest(int ipix, double* theta, double* phi); |
| 69 | + int ang2pix_z_phi_ring(double z, double phi) const; | ||
| 70 | + int ang2pix_z_phi_nest(double z, double phi) const; | ||
| 65 | 71 | ||
| 66 | // Private data area | 72 | // Private data area |
| 67 | int m_nside; //!< Number of divisions of each base pixel (1-8192) | 73 | int m_nside; //!< Number of divisions of each base pixel (1-8192) |
| 68 | int m_npface; //!< | 74 | int m_npface; //!< |
| 69 | int m_ncap; //!< | 75 | int m_ncap; //!< |
| 70 | - int m_order; //!< Ordering (0=ring, 1=nested, -1=?) | 76 | + int m_order; //!< Order |
| 77 | + int m_scheme; //!< Ordering scheme (0=ring, 1=nested, -1=?) | ||
| 71 | int m_coordsys; //!< Coordinate system (0=equatorial, 1=galactic, -1=?) | 78 | int m_coordsys; //!< Coordinate system (0=equatorial, 1=galactic, -1=?) |
| 72 | int m_num_pixels; //!< Number of pixels | 79 | int m_num_pixels; //!< Number of pixels |
| 73 | int m_size_pixels; //!< Vector size of each pixel | 80 | int m_size_pixels; //!< Vector size of each pixel |
pyext/GHealpix.i
| @@ -40,6 +40,7 @@ public: | @@ -40,6 +40,7 @@ public: | ||
| 40 | int num_pixels(void) const; | 40 | int num_pixels(void) const; |
| 41 | double omega(void) const; | 41 | double omega(void) const; |
| 42 | GSkyDir pix2ang(const int& ipix); | 42 | GSkyDir pix2ang(const int& ipix); |
| 43 | + int ang2pix(GSkyDir dir) const; | ||
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 45 | 46 |
src/GHealpix.cpp
| @@ -19,7 +19,8 @@ | @@ -19,7 +19,8 @@ | ||
| 19 | 19 | ||
| 20 | /* __ Includes ___________________________________________________________ */ | 20 | /* __ Includes ___________________________________________________________ */ |
| 21 | #include <iostream> | 21 | #include <iostream> |
| 22 | -#include <math.h> | 22 | +//#include <math.h> |
| 23 | +#include <cmath> | ||
| 23 | #include "GException.hpp" | 24 | #include "GException.hpp" |
| 24 | #include "GTools.hpp" | 25 | #include "GTools.hpp" |
| 25 | #include "GHealpix.hpp" | 26 | #include "GHealpix.hpp" |
| @@ -37,15 +38,19 @@ | @@ -37,15 +38,19 @@ | ||
| 37 | 38 | ||
| 38 | /* __ Debug definitions __________________________________________________ */ | 39 | /* __ Debug definitions __________________________________________________ */ |
| 39 | 40 | ||
| 41 | +/* __ Local prototypes ___________________________________________________ */ | ||
| 42 | +unsigned int isqrt(unsigned int arg); | ||
| 43 | + | ||
| 40 | /* __ Constants __________________________________________________________ */ | 44 | /* __ Constants __________________________________________________________ */ |
| 41 | -const int jrll[12] = {2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; | ||
| 42 | -const int jpll[12] = {1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7}; | 45 | +const int jrll[12] = {2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; |
| 46 | +const int jpll[12] = {1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7}; | ||
| 47 | +const int order_max = 13; | ||
| 48 | +const int ns_max = 1 << order_max; | ||
| 43 | 49 | ||
| 44 | /* __ Static conversion arrays ___________________________________________ */ | 50 | /* __ Static conversion arrays ___________________________________________ */ |
| 45 | static short ctab[0x100]; | 51 | static short ctab[0x100]; |
| 46 | static short utab[0x100]; | 52 | static short utab[0x100]; |
| 47 | 53 | ||
| 48 | - | ||
| 49 | /*========================================================================== | 54 | /*========================================================================== |
| 50 | = = | 55 | = = |
| 51 | = GHealpix constructors/destructors = | 56 | = GHealpix constructors/destructors = |
| @@ -178,6 +183,8 @@ void GHealpix::read(const GFitsHDU* hdu) | @@ -178,6 +183,8 @@ void GHealpix::read(const GFitsHDU* hdu) | ||
| 178 | m_fact2 = 4.0 / m_num_pixels; | 183 | m_fact2 = 4.0 / m_num_pixels; |
| 179 | m_fact1 = 2 * m_nside * m_fact2; | 184 | m_fact1 = 2 * m_nside * m_fact2; |
| 180 | m_omega = fourpi / m_num_pixels; | 185 | m_omega = fourpi / m_num_pixels; |
| 186 | + m_order = nside2order(m_nside); | ||
| 187 | + | ||
| 181 | 188 | ||
| 182 | // Get ordering scheme from ORDERING keyword | 189 | // Get ordering scheme from ORDERING keyword |
| 183 | std::string ordering; | 190 | std::string ordering; |
| @@ -185,14 +192,14 @@ void GHealpix::read(const GFitsHDU* hdu) | @@ -185,14 +192,14 @@ void GHealpix::read(const GFitsHDU* hdu) | ||
| 185 | ordering = hdu->card("ORDERING")->string(); | 192 | ordering = hdu->card("ORDERING")->string(); |
| 186 | } | 193 | } |
| 187 | catch (GException::fits_key_not_found &e) { | 194 | catch (GException::fits_key_not_found &e) { |
| 188 | - m_order = -1; // Flag unknown ordering | 195 | + m_scheme = -1; // Flag unknown ordering |
| 189 | } | 196 | } |
| 190 | 197 | ||
| 191 | // Decode ordering scheme string | 198 | // Decode ordering scheme string |
| 192 | if (ordering == "RING") | 199 | if (ordering == "RING") |
| 193 | - m_order = 0; | 200 | + m_scheme = 0; |
| 194 | else if (ordering == "NESTED") | 201 | else if (ordering == "NESTED") |
| 195 | - m_order = 1; | 202 | + m_scheme = 1; |
| 196 | else | 203 | else |
| 197 | throw GException::healpix(G_LOAD, "Invalid ordering"); | 204 | throw GException::healpix(G_LOAD, "Invalid ordering"); |
| 198 | 205 | ||
| @@ -268,6 +275,16 @@ int GHealpix::nside(void) const | @@ -268,6 +275,16 @@ int GHealpix::nside(void) const | ||
| 268 | 275 | ||
| 269 | 276 | ||
| 270 | /***********************************************************************//** | 277 | /***********************************************************************//** |
| 278 | + * @brief Returns ordering parameter. | ||
| 279 | + ***************************************************************************/ | ||
| 280 | +int GHealpix::order(void) const | ||
| 281 | +{ | ||
| 282 | + // Return order | ||
| 283 | + return m_order; | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | + | ||
| 287 | +/***********************************************************************//** | ||
| 271 | * @brief Returns number of pixels. | 288 | * @brief Returns number of pixels. |
| 272 | ***************************************************************************/ | 289 | ***************************************************************************/ |
| 273 | int GHealpix::num_pixels(void) const | 290 | int GHealpix::num_pixels(void) const |
| @@ -300,7 +317,7 @@ GSkyDir GHealpix::pix2ang(const int& ipix) | @@ -300,7 +317,7 @@ GSkyDir GHealpix::pix2ang(const int& ipix) | ||
| 300 | double phi = 0.0; | 317 | double phi = 0.0; |
| 301 | 318 | ||
| 302 | // Perform ordering dependent conversion | 319 | // Perform ordering dependent conversion |
| 303 | - switch (m_order) { | 320 | + switch (m_scheme) { |
| 304 | case 0: | 321 | case 0: |
| 305 | pix2ang_ring(ipix, &theta, &phi); | 322 | pix2ang_ring(ipix, &theta, &phi); |
| 306 | break; | 323 | break; |
| @@ -328,6 +345,49 @@ GSkyDir GHealpix::pix2ang(const int& ipix) | @@ -328,6 +345,49 @@ GSkyDir GHealpix::pix2ang(const int& ipix) | ||
| 328 | } | 345 | } |
| 329 | 346 | ||
| 330 | 347 | ||
| 348 | +/***********************************************************************//** | ||
| 349 | + * @brief Returns pixel for a given sky direction | ||
| 350 | + * | ||
| 351 | + * @param[in] ipix Pixel number (0,1,...,num_pixels) | ||
| 352 | + ***************************************************************************/ | ||
| 353 | +int GHealpix::ang2pix(GSkyDir dir) const | ||
| 354 | +{ | ||
| 355 | + // Declare result | ||
| 356 | + int ipix; | ||
| 357 | + double z; | ||
| 358 | + double phi; | ||
| 359 | + | ||
| 360 | + // Compute coordinate system dependent (z,phi) | ||
| 361 | + switch (m_coordsys) { | ||
| 362 | + case 0: | ||
| 363 | + z = cos(pihalf-dir.dec()); | ||
| 364 | + phi = dir.ra(); | ||
| 365 | + break; | ||
| 366 | + case 1: | ||
| 367 | + z = cos(pihalf-dir.b()); | ||
| 368 | + phi = dir.l(); | ||
| 369 | + break; | ||
| 370 | + default: | ||
| 371 | + break; | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + // Perform ordering dependent conversion | ||
| 375 | + switch (m_scheme) { | ||
| 376 | + case 0: | ||
| 377 | + ipix = ang2pix_z_phi_ring(z, phi); | ||
| 378 | + break; | ||
| 379 | + case 1: | ||
| 380 | + ipix = ang2pix_z_phi_nest(z, phi); | ||
| 381 | + break; | ||
| 382 | + default: | ||
| 383 | + break; | ||
| 384 | + } | ||
| 385 | + | ||
| 386 | + // Return pixel index | ||
| 387 | + return ipix; | ||
| 388 | +} | ||
| 389 | + | ||
| 390 | + | ||
| 331 | /*========================================================================== | 391 | /*========================================================================== |
| 332 | = = | 392 | = = |
| 333 | = GHealpix private methods = | 393 | = GHealpix private methods = |
| @@ -344,6 +404,7 @@ void GHealpix::init_members(void) | @@ -344,6 +404,7 @@ void GHealpix::init_members(void) | ||
| 344 | m_npface = 0; | 404 | m_npface = 0; |
| 345 | m_ncap = 0; | 405 | m_ncap = 0; |
| 346 | m_order = 0; | 406 | m_order = 0; |
| 407 | + m_scheme = 0; | ||
| 347 | m_coordsys = 0; | 408 | m_coordsys = 0; |
| 348 | m_num_pixels = 0; | 409 | m_num_pixels = 0; |
| 349 | m_size_pixels = 0; | 410 | m_size_pixels = 0; |
| @@ -380,6 +441,7 @@ void GHealpix::copy_members(const GHealpix& pixels) | @@ -380,6 +441,7 @@ void GHealpix::copy_members(const GHealpix& pixels) | ||
| 380 | m_npface = pixels.m_npface; | 441 | m_npface = pixels.m_npface; |
| 381 | m_ncap = pixels.m_ncap; | 442 | m_ncap = pixels.m_ncap; |
| 382 | m_order = pixels.m_order; | 443 | m_order = pixels.m_order; |
| 444 | + m_scheme = pixels.m_scheme; | ||
| 383 | m_coordsys = pixels.m_coordsys; | 445 | m_coordsys = pixels.m_coordsys; |
| 384 | m_num_pixels = pixels.m_num_pixels; | 446 | m_num_pixels = pixels.m_num_pixels; |
| 385 | m_size_pixels = pixels.m_size_pixels; | 447 | m_size_pixels = pixels.m_size_pixels; |
| @@ -434,6 +496,32 @@ GHealpix* GHealpix::clone(void) const | @@ -434,6 +496,32 @@ GHealpix* GHealpix::clone(void) const | ||
| 434 | 496 | ||
| 435 | 497 | ||
| 436 | /***********************************************************************//** | 498 | /***********************************************************************//** |
| 499 | + * @brief Convert nside to order | ||
| 500 | + * | ||
| 501 | + * @param[in] nside Number of sides. | ||
| 502 | + ***************************************************************************/ | ||
| 503 | +int GHealpix::nside2order(int nside) | ||
| 504 | +{ | ||
| 505 | + // Initialise order | ||
| 506 | + int order = -1; | ||
| 507 | + | ||
| 508 | + // Determine order | ||
| 509 | + for (int m = 0; m <= order_max; ++m) { | ||
| 510 | + int nstest = 1 << m; | ||
| 511 | + if (nside == nstest) { | ||
| 512 | + order = m; | ||
| 513 | + break; | ||
| 514 | + } | ||
| 515 | + if (nside < nstest) | ||
| 516 | + break; | ||
| 517 | + } | ||
| 518 | + | ||
| 519 | + // Return order | ||
| 520 | + return order; | ||
| 521 | +} | ||
| 522 | + | ||
| 523 | + | ||
| 524 | +/***********************************************************************//** | ||
| 437 | * @brief Convert pixel index to (x,y) coordinate | 525 | * @brief Convert pixel index to (x,y) coordinate |
| 438 | * | 526 | * |
| 439 | * @param[in] ipix Pixel index for which (x,y) are to be computed. | 527 | * @param[in] ipix Pixel index for which (x,y) are to be computed. |
| @@ -456,6 +544,19 @@ void GHealpix::pix2xy(const int& ipix, int* x, int* y) | @@ -456,6 +544,19 @@ void GHealpix::pix2xy(const int& ipix, int* x, int* y) | ||
| 456 | 544 | ||
| 457 | 545 | ||
| 458 | /***********************************************************************//** | 546 | /***********************************************************************//** |
| 547 | + * @brief Convert (x,y) coordinate to pixel | ||
| 548 | + * | ||
| 549 | + * @param[in] x x coordinate. | ||
| 550 | + * @param[in] y y coordinate. | ||
| 551 | + ***************************************************************************/ | ||
| 552 | +int GHealpix::xy2pix(int x, int y) const | ||
| 553 | +{ | ||
| 554 | + // Return pixel | ||
| 555 | + return utab[x&0xff] | (utab[x>>8]<<16) | (utab[y&0xff]<<1) | (utab[y>>8]<<17); | ||
| 556 | +} | ||
| 557 | + | ||
| 558 | + | ||
| 559 | +/***********************************************************************//** | ||
| 459 | * @brief Convert pixel index to (theta,phi) angles for ring ordering | 560 | * @brief Convert pixel index to (theta,phi) angles for ring ordering |
| 460 | * | 561 | * |
| 461 | * @param[in] ipix Pixel index for which (theta,phi) are to be computed. | 562 | * @param[in] ipix Pixel index for which (theta,phi) are to be computed. |
| @@ -470,48 +571,34 @@ void GHealpix::pix2ang_ring(int ipix, double* theta, double* phi) | @@ -470,48 +571,34 @@ void GHealpix::pix2ang_ring(int ipix, double* theta, double* phi) | ||
| 470 | if (ipix < 0 || ipix >= m_num_pixels) | 571 | if (ipix < 0 || ipix >= m_num_pixels) |
| 471 | throw GException::out_of_range(G_PIX2ANG_RING, ipix, 0, m_num_pixels-1); | 572 | throw GException::out_of_range(G_PIX2ANG_RING, ipix, 0, m_num_pixels-1); |
| 472 | 573 | ||
| 473 | - // Setup | ||
| 474 | - int ipix1 = ipix + 1; // in {1, m_num_pixels} | ||
| 475 | - int nl2 = 2 * m_nside; | ||
| 476 | - int nl4 = 4 * m_nside; | ||
| 477 | - | ||
| 478 | - // Determine points in each polar cap (0 for nside=1) | ||
| 479 | - int ncap = 2 * m_nside * (m_nside-1); | ||
| 480 | - | ||
| 481 | - double fact1 = 1.5 * m_nside; | ||
| 482 | - double fact2 = 3.0 * m_nside * m_nside; | ||
| 483 | - | ||
| 484 | // Handle North Polar cap | 574 | // Handle North Polar cap |
| 485 | - if (ipix1 <= ncap) { | ||
| 486 | - double hip = ipix1/2.; | ||
| 487 | - double fihip = floor(hip); | ||
| 488 | - int iring = (int)floor(sqrt(hip - sqrt(fihip)))+1; | ||
| 489 | - int iphi = ipix1 - 2*iring*(iring - 1); | ||
| 490 | - *theta = acos(1. - iring*iring / fact2); | ||
| 491 | - *phi = (1.*iphi - 0.5) * pi/(2.*iring); | 575 | + if (ipix < m_ncap) { |
| 576 | + int iring = int(0.5*(1+isqrt(1+2*ipix))); // counted from North pole | ||
| 577 | + int iphi = (ipix+1) - 2*iring*(iring-1); | ||
| 578 | + *theta = acos(1.0 - iring*iring / m_fact2); | ||
| 579 | + *phi = (iphi - 0.5) * pi/(2.0*iring); | ||
| 492 | } | 580 | } |
| 493 | 581 | ||
| 494 | // Handle Equatorial region | 582 | // Handle Equatorial region |
| 495 | - else if(ipix1 <= nl2*(5*m_nside+1)) { | ||
| 496 | - int ip = ipix1 - ncap - 1; | ||
| 497 | - int iring = (int)floor(ip/nl4) + m_nside; | ||
| 498 | - int iphi = (int)fmod(ip,nl4) + 1; | ||
| 499 | - double fodd = 0.5 * (1 + fmod((double)(iring+m_nside),2)); | ||
| 500 | - *theta = acos((nl2 - iring) / fact1); | ||
| 501 | - *phi = (1.*iphi - fodd) * pi/(2.*m_nside); | 583 | + else if (ipix < (m_num_pixels - m_ncap)) { |
| 584 | + int ip = ipix - m_ncap; | ||
| 585 | + int iring = ip/(4*m_nside) + m_nside; // counted from North pole | ||
| 586 | + int iphi = ip%(4*m_nside) + 1; | ||
| 587 | + double fodd = ((iring+m_nside)&1) ? 1 : 0.5; | ||
| 588 | + int nl2 = 2*m_nside; | ||
| 589 | + *theta = acos((nl2 - iring) / m_fact1); | ||
| 590 | + *phi = (iphi - fodd) * pi/nl2; | ||
| 502 | } | 591 | } |
| 503 | 592 | ||
| 504 | - // Handle South Polar cap | 593 | + // Handle South Polar cap |
| 505 | else { | 594 | else { |
| 506 | - int ip = m_num_pixels - ipix1 + 1; | ||
| 507 | - double hip = ip/2.; | ||
| 508 | - double fihip = floor(hip); | ||
| 509 | - int iring = (int)floor(sqrt( hip - sqrt(fihip))) + 1; | ||
| 510 | - int iphi = (int)(4.*iring + 1 - (ip - 2.*iring*(iring-1))); | ||
| 511 | - *theta = acos( -1. + iring*iring / fact2 ); | ||
| 512 | - *phi = (1.*iphi - 0.5) * pi/(2.*iring); | 595 | + int ip = m_num_pixels - ipix; |
| 596 | + int iring = int(0.5*(1+isqrt(2*ip-1))); // Counted from South pole | ||
| 597 | + int iphi = 4*iring + 1 - (ip - 2*iring*(iring-1)); | ||
| 598 | + *theta = acos(iring*iring / m_fact2 - 1.0); | ||
| 599 | + *phi = (iphi - 0.5) * pi/(2.*iring); | ||
| 513 | } | 600 | } |
| 514 | - | 601 | + |
| 515 | // Return | 602 | // Return |
| 516 | return; | 603 | return; |
| 517 | } | 604 | } |
| @@ -534,7 +621,7 @@ void GHealpix::pix2ang_nest(int ipix, double* theta, double* phi) | @@ -534,7 +621,7 @@ void GHealpix::pix2ang_nest(int ipix, double* theta, double* phi) | ||
| 534 | 621 | ||
| 535 | // Get face number and index in face | 622 | // Get face number and index in face |
| 536 | int nl4 = 4 * m_nside; | 623 | int nl4 = 4 * m_nside; |
| 537 | - int face_num = ipix/m_npface; // Face number in {0,11} | 624 | + int face_num = ipix >> (2*m_order); // Face number in {0,11} |
| 538 | int ipf = ipix & (m_npface - 1); | 625 | int ipf = ipix & (m_npface - 1); |
| 539 | 626 | ||
| 540 | // Get pixel coordinates | 627 | // Get pixel coordinates |
| @@ -543,7 +630,7 @@ void GHealpix::pix2ang_nest(int ipix, double* theta, double* phi) | @@ -543,7 +630,7 @@ void GHealpix::pix2ang_nest(int ipix, double* theta, double* phi) | ||
| 543 | pix2xy(ipf, &ix, &iy); | 630 | pix2xy(ipf, &ix, &iy); |
| 544 | 631 | ||
| 545 | // Computes the z coordinate on the sphere | 632 | // Computes the z coordinate on the sphere |
| 546 | - int jr = jrll[face_num]*m_nside - ix - iy - 1; | 633 | + int jr = (jrll[face_num] << m_order) - ix - iy - 1; |
| 547 | 634 | ||
| 548 | // Declare result variables | 635 | // Declare result variables |
| 549 | int nr; | 636 | int nr; |
| @@ -585,6 +672,118 @@ void GHealpix::pix2ang_nest(int ipix, double* theta, double* phi) | @@ -585,6 +672,118 @@ void GHealpix::pix2ang_nest(int ipix, double* theta, double* phi) | ||
| 585 | } | 672 | } |
| 586 | 673 | ||
| 587 | 674 | ||
| 675 | +/***********************************************************************//** | ||
| 676 | + * @brief Returns pixels which contains angular coordinates (z,phi) | ||
| 677 | + * | ||
| 678 | + * @param[in] z Cosine of zenith angle - cos(theta). | ||
| 679 | + * @param[in] phi Azimuth angle in radians. | ||
| 680 | + ***************************************************************************/ | ||
| 681 | +int GHealpix::ang2pix_z_phi_ring(double z, double phi) const | ||
| 682 | +{ | ||
| 683 | + // Initialise pixel | ||
| 684 | + int ipix = 0; | ||
| 685 | + | ||
| 686 | + // Setup | ||
| 687 | + double za = abs(z); | ||
| 688 | + double tt = modulo(phi,twopi) * inv_pihalf; // in [0,4) | ||
| 689 | + | ||
| 690 | + // Equatorial region | ||
| 691 | + if (za <= twothird) { | ||
| 692 | + double temp1 = m_nside*(0.5+tt); | ||
| 693 | + double temp2 = m_nside*z*0.75; | ||
| 694 | + int jp = int(temp1-temp2); // index of ascending edge line | ||
| 695 | + int jm = int(temp1+temp2); // index of descending edge line | ||
| 696 | + int ir = m_nside + 1 + jp - jm; // in {1,2n+1} | ||
| 697 | + int kshift = 1 - (ir & 1); // kshift=1 if ir even, 0 otherwise | ||
| 698 | + int ip = (jp+jm-m_nside+kshift+1)/2; // in {0,4n-1} | ||
| 699 | + ip = modulo(ip,4*m_nside); | ||
| 700 | + ipix = m_ncap + (ir-1)*4*m_nside + ip; | ||
| 701 | + } | ||
| 702 | + | ||
| 703 | + // North & South polar caps | ||
| 704 | + else { | ||
| 705 | + double tp = tt - int(tt); | ||
| 706 | + double tmp = m_nside * sqrt(3*(1-za)); | ||
| 707 | + int jp = int(tp*tmp); // increasing edge line index | ||
| 708 | + int jm = int((1.0-tp)*tmp); // decreasing edge line index | ||
| 709 | + int ir = jp + jm + 1; // ring number counted from the closest pole | ||
| 710 | + int ip = int(tt*ir); // in {0,4*ir-1} | ||
| 711 | + ip = modulo(ip,4*ir); | ||
| 712 | + if (z>0) | ||
| 713 | + ipix = 2*ir*(ir-1) + ip; | ||
| 714 | + else | ||
| 715 | + ipix = m_num_pixels - 2*ir*(ir+1) + ip; | ||
| 716 | + } | ||
| 717 | + | ||
| 718 | + // Return pixel | ||
| 719 | + return ipix; | ||
| 720 | +} | ||
| 721 | + | ||
| 722 | + | ||
| 723 | +/***********************************************************************//** | ||
| 724 | + * @brief Returns pixels which contains angular coordinates (z,phi) | ||
| 725 | + * | ||
| 726 | + * @param[in] z Cosine of zenith angle - cos(theta). | ||
| 727 | + * @param[in] phi Azimuth angle in radians. | ||
| 728 | + ***************************************************************************/ | ||
| 729 | +int GHealpix::ang2pix_z_phi_nest(double z, double phi) const | ||
| 730 | +{ | ||
| 731 | + // Initialise face and pixel numbers | ||
| 732 | + int face_num; | ||
| 733 | + int ix; | ||
| 734 | + int iy; | ||
| 735 | + | ||
| 736 | + // Setup | ||
| 737 | + double za = abs(z); | ||
| 738 | + double tt = modulo(phi,twopi) * inv_pihalf; // in [0,4) | ||
| 739 | + | ||
| 740 | + // Equatorial region | ||
| 741 | + if (za <= twothird) { | ||
| 742 | + double temp1 = ns_max*(0.5+tt); | ||
| 743 | + double temp2 = ns_max*z*0.75; | ||
| 744 | + int jp = int(temp1-temp2); // index of ascending edge line | ||
| 745 | + int jm = int(temp1+temp2); // index of descending edge line | ||
| 746 | + int ifp = jp >> order_max; // in {0,4} | ||
| 747 | + int ifm = jm >> order_max; | ||
| 748 | + if (ifp == ifm) // faces 4 to 7 | ||
| 749 | + face_num = (ifp==4) ? 4: ifp+4; | ||
| 750 | + else if (ifp < ifm) // (half-)faces 0 to 3 | ||
| 751 | + face_num = ifp; | ||
| 752 | + else // (half-)faces 8 to 11 | ||
| 753 | + face_num = ifm + 8; | ||
| 754 | + ix = jm & (ns_max-1); | ||
| 755 | + iy = ns_max - (jp & (ns_max-1)) - 1; | ||
| 756 | + } | ||
| 757 | + | ||
| 758 | + // Polar region, za > 2/3 | ||
| 759 | + else { | ||
| 760 | + int ntt = int(tt); | ||
| 761 | + double tp = tt-ntt; | ||
| 762 | + double tmp = ns_max*sqrt(3*(1-za)); | ||
| 763 | + int jp = int(tp*tmp); // increasing edge line index | ||
| 764 | + int jm = int((1.0-tp)*tmp); // decreasing edge line index | ||
| 765 | + if (jp >= ns_max) jp = ns_max-1; // for points too close to the boundary | ||
| 766 | + if (jm >= ns_max) jm = ns_max-1; | ||
| 767 | + if (z >= 0) { | ||
| 768 | + face_num = ntt; // in {0,3} | ||
| 769 | + ix = ns_max - jm - 1; | ||
| 770 | + iy = ns_max - jp - 1; | ||
| 771 | + } | ||
| 772 | + else { | ||
| 773 | + face_num = ntt + 8; // in {8,11} | ||
| 774 | + ix = jp; | ||
| 775 | + iy = jm; | ||
| 776 | + } | ||
| 777 | + } | ||
| 778 | + | ||
| 779 | + // Get pixel | ||
| 780 | + int ipf = xy2pix(ix, iy); | ||
| 781 | + ipf >>= (2*(order_max - m_order)); // in {0, nside**2 - 1} | ||
| 782 | + return ipf + (face_num<<(2*m_order)); // in {0, 12*nside**2 - 1} | ||
| 783 | +} | ||
| 784 | + | ||
| 785 | + | ||
| 786 | + | ||
| 588 | /*========================================================================== | 787 | /*========================================================================== |
| 589 | = = | 788 | = = |
| 590 | = GHealpix friends = | 789 | = GHealpix friends = |
| @@ -601,15 +800,18 @@ ostream& operator<< (ostream& os, const GHealpix& pixels) | @@ -601,15 +800,18 @@ ostream& operator<< (ostream& os, const GHealpix& pixels) | ||
| 601 | { | 800 | { |
| 602 | // Put header in stream | 801 | // Put header in stream |
| 603 | os << "=== GHealpix ===" << endl; | 802 | os << "=== GHealpix ===" << endl; |
| 604 | - os << " Number of base pixel div. .: " << pixels.m_nside << endl; | ||
| 605 | - os << " Number of pixels ..........: " << pixels.m_num_pixels << endl; | 803 | + os << " Nside (number of divisions): " << pixels.m_nside << endl; |
| 804 | + os << " Npface (pixels per face) ..: " << pixels.m_npface << endl; | ||
| 805 | + os << " Ncap (number of cap pixels): " << pixels.m_ncap << endl; | ||
| 806 | + os << " Npix (number of pixels) ...: " << pixels.m_num_pixels << endl; | ||
| 807 | + os << " Order .....................: " << pixels.m_order << endl; | ||
| 606 | os << " Pixel vector size .........: " << pixels.m_size_pixels << endl; | 808 | os << " Pixel vector size .........: " << pixels.m_size_pixels << endl; |
| 607 | os << " Solid angle ...............: " << scientific << pixels.m_omega | 809 | os << " Solid angle ...............: " << scientific << pixels.m_omega |
| 608 | - << fixed << endl; | 810 | + << fixed << " sr" << endl; |
| 609 | 811 | ||
| 610 | // Put ordering in stream | 812 | // Put ordering in stream |
| 611 | os << " Ordering ..................: "; | 813 | os << " Ordering ..................: "; |
| 612 | - switch (pixels.m_order) { | 814 | + switch (pixels.m_scheme) { |
| 613 | case 0: | 815 | case 0: |
| 614 | os << "Ring" << endl; | 816 | os << "Ring" << endl; |
| 615 | break; | 817 | break; |
| @@ -628,22 +830,19 @@ ostream& operator<< (ostream& os, const GHealpix& pixels) | @@ -628,22 +830,19 @@ ostream& operator<< (ostream& os, const GHealpix& pixels) | ||
| 628 | os << " Coordinate system .........: "; | 830 | os << " Coordinate system .........: "; |
| 629 | switch (pixels.m_coordsys) { | 831 | switch (pixels.m_coordsys) { |
| 630 | case 0: | 832 | case 0: |
| 631 | - os << "Equatorial (RA,Dec)" << endl; | 833 | + os << "Equatorial (RA,Dec)"; |
| 632 | break; | 834 | break; |
| 633 | case 1: | 835 | case 1: |
| 634 | - os << "Galactic (l,b)" << endl; | 836 | + os << "Galactic (l,b)"; |
| 635 | break; | 837 | break; |
| 636 | case -1: | 838 | case -1: |
| 637 | - os << "*** Unknown ***" << endl; | 839 | + os << "*** Unknown ***"; |
| 638 | break; | 840 | break; |
| 639 | default: | 841 | default: |
| 640 | - os << "*** Invalid ***" << endl; | 842 | + os << "*** Invalid ***"; |
| 641 | break; | 843 | break; |
| 642 | } | 844 | } |
| 643 | 845 | ||
| 644 | - for (int i = 0; i < pixels.m_num_pixels; ++i) | ||
| 645 | - os << pixels.m_dir[i] << " "; | ||
| 646 | - | ||
| 647 | // Return output stream | 846 | // Return output stream |
| 648 | return os; | 847 | return os; |
| 649 | } | 848 | } |
| @@ -654,3 +853,16 @@ ostream& operator<< (ostream& os, const GHealpix& pixels) | @@ -654,3 +853,16 @@ ostream& operator<< (ostream& os, const GHealpix& pixels) | ||
| 654 | = Other functions used by GHealpix = | 853 | = Other functions used by GHealpix = |
| 655 | = = | 854 | = = |
| 656 | ==========================================================================*/ | 855 | ==========================================================================*/ |
| 856 | + | ||
| 857 | +/***********************************************************************//** | ||
| 858 | + * @brief Integer n that fulfills n*n <= arg < (n+1)*(n+1) | ||
| 859 | + * | ||
| 860 | + * @param[in] arg Argument. | ||
| 861 | + * | ||
| 862 | + * Returns the integer \a n, which fulfills \a n*n <= arg < (n+1)*(n+1). | ||
| 863 | + ***************************************************************************/ | ||
| 864 | +unsigned int isqrt(unsigned int arg) | ||
| 865 | +{ | ||
| 866 | + // Return | ||
| 867 | + return unsigned(sqrt(arg+0.5)); | ||
| 868 | +} |