Commit ba12d62e92fb3f89438f50f445970d70ccbb0152
1 parent
445cf984
Add several methods to the HealPix class.
The following methods have been added: - set_z_phi - loc2dir - xyf2loc - pix2xyf - max_pixrad - boundaries - neighbours
Showing
3 changed files
with
455 additions
and
42 deletions
include/GHealpix.hpp
| ... | ... | @@ -75,41 +75,49 @@ public: |
| 75 | 75 | virtual std::string print(const GChatter& chatter = NORMAL) const; |
| 76 | 76 | |
| 77 | 77 | // Other methods |
| 78 | - const int& npix(void) const; | |
| 79 | - const int& nside(void) const; | |
| 80 | - std::string ordering(void) const; | |
| 81 | - void ordering(const std::string& ordering); | |
| 78 | + const int& npix(void) const; | |
| 79 | + const int& nside(void) const; | |
| 80 | + std::string ordering(void) const; | |
| 81 | + void ordering(const std::string& ordering); | |
| 82 | + std::vector<int> neighbours(const GSkyPixel& pixel) const; | |
| 83 | + std::vector<GSkyDir> boundaries(const GSkyPixel& pixel, const int& step = 1) const; | |
| 84 | + double max_pixrad(void) const; | |
| 82 | 85 | |
| 83 | 86 | private: |
| 84 | 87 | // Private methods |
| 85 | - void init_members(void); | |
| 86 | - void copy_members(const GHealpix& wcs); | |
| 87 | - void free_members(void); | |
| 88 | - virtual bool compare(const GSkyProjection& proj) const; | |
| 88 | + void init_members(void); | |
| 89 | + void copy_members(const GHealpix& wcs); | |
| 90 | + void free_members(void); | |
| 91 | + virtual bool compare(const GSkyProjection& proj) const; | |
| 89 | 92 | |
| 90 | 93 | // Low-level HealPix methods |
| 91 | - int compress_bits(const int& value) const; | |
| 92 | - int spread_bits(const int& value) const; | |
| 93 | - void nest2xyf(const int& pix, int* ix, int* iy, int* face) const; | |
| 94 | - void ring2xyf(const int& pix, int* ix, int* iy, int* face) const; | |
| 95 | - int xyf2nest(const int& ix, const int& iy, const int& face) const; | |
| 96 | - int xyf2ring(const int& ix, const int& iy, const int& face) const; | |
| 97 | - int nside2order(const int& nside) const; | |
| 98 | - int nest2ring(const int& pix) const; | |
| 99 | - int ring2nest(const int& pix) const; | |
| 100 | - void pix2xy(const int& ipix, int* x, int* y) const; | |
| 101 | - int xy2pix(int x, int y) const; | |
| 102 | - void pix2ang_ring(int ipix, double* theta, double* phi) const; | |
| 103 | - void pix2ang_nest(int ipix, double* theta, double* phi) const; | |
| 104 | - int ang2pix_z_phi_ring(double z, double phi) const; | |
| 105 | - int ang2pix_z_phi_nest(double z, double phi) const; | |
| 106 | - int ring_above(const double& z) const; | |
| 107 | - void get_ring_info(const int& ring, int* startpix, int* ringpix, | |
| 108 | - bool* shifted) const; | |
| 109 | - void get_ring_info(const int& ring, int* startpix, int* ringpix, | |
| 110 | - double* theta, bool* shifted) const; | |
| 111 | - GBilinear interpolator(const double& theta, const double& phi) const; | |
| 112 | - unsigned int isqrt(unsigned int arg) const; | |
| 94 | + int compress_bits(const int& value) const; | |
| 95 | + int spread_bits(const int& value) const; | |
| 96 | + void pix2xyf(const int& pix, int* ix, int* iy, int* face) const; | |
| 97 | + void nest2xyf(const int& pix, int* ix, int* iy, int* face) const; | |
| 98 | + void ring2xyf(const int& pix, int* ix, int* iy, int* face) const; | |
| 99 | + int xyf2nest(const int& ix, const int& iy, const int& face) const; | |
| 100 | + int xyf2ring(const int& ix, const int& iy, const int& face) const; | |
| 101 | + void xyf2loc(const double& x, const double& y, const int& face, | |
| 102 | + double* z, double* phi) const; | |
| 103 | + int nside2order(const int& nside) const; | |
| 104 | + int nest2ring(const int& pix) const; | |
| 105 | + int ring2nest(const int& pix) const; | |
| 106 | + void pix2xy(const int& ipix, int* x, int* y) const; | |
| 107 | + int xy2pix(int x, int y) const; | |
| 108 | + void pix2ang_ring(int ipix, double* theta, double* phi) const; | |
| 109 | + void pix2ang_nest(int ipix, double* theta, double* phi) const; | |
| 110 | + int ang2pix_z_phi_ring(double z, double phi) const; | |
| 111 | + int ang2pix_z_phi_nest(double z, double phi) const; | |
| 112 | + int ring_above(const double& z) const; | |
| 113 | + void get_ring_info(const int& ring, int* startpix, int* ringpix, | |
| 114 | + bool* shifted) const; | |
| 115 | + void get_ring_info(const int& ring, int* startpix, int* ringpix, | |
| 116 | + double* theta, bool* shifted) const; | |
| 117 | + GBilinear interpolator(const double& theta, const double& phi) const; | |
| 118 | + unsigned int isqrt(unsigned int arg) const; | |
| 119 | + GVector set_z_phi(const double& z, const double& phi) const; | |
| 120 | + GSkyDir loc2dir(const double& z, const double& phi) const; | |
| 113 | 121 | |
| 114 | 122 | // Private data area |
| 115 | 123 | int m_nside; //!< Number of divisions of each base pixel (1-8192) | ... | ... |
pyext/GHealpix.i
| ... | ... | @@ -27,6 +27,13 @@ |
| 27 | 27 | /* Put headers and other declarations here that are needed for compilation */ |
| 28 | 28 | #include "GHealpix.hpp" |
| 29 | 29 | %} |
| 30 | +%include "std_vector.i" | |
| 31 | +namespace std { | |
| 32 | + %template(SkyDirVector) vector<GSkyDir>; | |
| 33 | +} | |
| 34 | +namespace std { | |
| 35 | + %template(IntVector) vector<int>; | |
| 36 | +} | |
| 30 | 37 | |
| 31 | 38 | |
| 32 | 39 | /***********************************************************************//** |
| ... | ... | @@ -60,10 +67,13 @@ public: |
| 60 | 67 | virtual GBilinear interpolator(const GSkyDir& dir) const; |
| 61 | 68 | |
| 62 | 69 | // Other methods |
| 63 | - const int& npix(void) const; | |
| 64 | - const int& nside(void) const; | |
| 65 | - std::string ordering(void) const; | |
| 66 | - void ordering(const std::string& ordering); | |
| 70 | + const int& npix(void) const; | |
| 71 | + const int& nside(void) const; | |
| 72 | + std::string ordering(void) const; | |
| 73 | + void ordering(const std::string& ordering); | |
| 74 | + std::vector<int> neighbours(const GSkyPixel& pixel) const; | |
| 75 | + std::vector<GSkyDir> boundaries(const GSkyPixel& pixel, const int& step = 1) const; | |
| 76 | + double max_pixrad(void) const; | |
| 67 | 77 | }; |
| 68 | 78 | |
| 69 | 79 | ... | ... |
src/sky/GHealpix.cpp
| ... | ... | @@ -32,6 +32,7 @@ |
| 32 | 32 | #include "GException.hpp" |
| 33 | 33 | #include "GTools.hpp" |
| 34 | 34 | #include "GMath.hpp" |
| 35 | +#include "GVector.hpp" | |
| 35 | 36 | #include "GHealpix.hpp" |
| 36 | 37 | |
| 37 | 38 | /* __ Method name definitions ____________________________________________ */ |
| ... | ... | @@ -45,6 +46,8 @@ |
| 45 | 46 | #define G_PIX2ANG_NEST "GHealpix::pix2ang_nest(int, double*, double*)" |
| 46 | 47 | #define G_ORDERING_SET "GHealpix::ordering(std::string&)" |
| 47 | 48 | #define G_INTERPOLATOR "GHealpix::interpolator(double&, double&)" |
| 49 | +#define G_NEIGHBOURS "GHealpix::neighbours(GSkyPixel&)" | |
| 50 | +#define G_BOUNDARIES "GHealpix::boundaries(GSkyPixel&, int&)" | |
| 48 | 51 | |
| 49 | 52 | /* __ Macros _____________________________________________________________ */ |
| 50 | 53 | |
| ... | ... | @@ -55,10 +58,30 @@ |
| 55 | 58 | /* __ Local prototypes ___________________________________________________ */ |
| 56 | 59 | |
| 57 | 60 | /* __ Constants __________________________________________________________ */ |
| 58 | -const int jrll[12] = {2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; | |
| 59 | -const int jpll[12] = {1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7}; | |
| 60 | -const int order_max = 13; | |
| 61 | -const int ns_max = 1 << order_max; | |
| 61 | +const int jrll[12] = {2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; | |
| 62 | +const int jpll[12] = {1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7}; | |
| 63 | +const int nb_xoffset[] = {-1,-1, 0, 1, 1, 1, 0,-1}; | |
| 64 | +const int nb_yoffset[] = { 0, 1, 1, 1, 0,-1,-1,-1}; | |
| 65 | +const int nb_facearray[][12] = {{ 8, 9,10,11,-1,-1,-1,-1,10,11, 8, 9 }, // S | |
| 66 | + { 5, 6, 7, 4, 8, 9,10,11, 9,10,11, 8 }, // SE | |
| 67 | + { -1,-1,-1,-1, 5, 6, 7, 4,-1,-1,-1,-1 }, // E | |
| 68 | + { 4, 5, 6, 7,11, 8, 9,10,11, 8, 9,10 }, // SW | |
| 69 | + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }, // center | |
| 70 | + { 1, 2, 3, 0, 0, 1, 2, 3, 5, 6, 7, 4 }, // NE | |
| 71 | + { -1,-1,-1,-1, 7, 4, 5, 6,-1,-1,-1,-1 }, // W | |
| 72 | + { 3, 0, 1, 2, 3, 0, 1, 2, 4, 5, 6, 7 }, // NW | |
| 73 | + { 2, 3, 0, 1,-1,-1,-1,-1, 0, 1, 2, 3 }}; // N | |
| 74 | +const int nb_swaparray[][3] = {{ 0,0,3 }, // S | |
| 75 | + { 0,0,6 }, // SE | |
| 76 | + { 0,0,0 }, // E | |
| 77 | + { 0,0,5 }, // SW | |
| 78 | + { 0,0,0 }, // center | |
| 79 | + { 5,0,0 }, // NE | |
| 80 | + { 0,0,0 }, // W | |
| 81 | + { 6,0,0 }, // NW | |
| 82 | + { 3,0,0 }}; // N | |
| 83 | +const int order_max = 13; | |
| 84 | +const int ns_max = 1 << order_max; | |
| 62 | 85 | |
| 63 | 86 | /* __ Static conversion arrays ___________________________________________ */ |
| 64 | 87 | static short ctab[0x100]; |
| ... | ... | @@ -534,6 +557,239 @@ void GHealpix::ordering(const std::string& ordering) |
| 534 | 557 | |
| 535 | 558 | |
| 536 | 559 | /***********************************************************************//** |
| 560 | + * @brief Return neighbouring pixels of a pixel | |
| 561 | + * | |
| 562 | + * @param[in] pix Pixel index. | |
| 563 | + * @return Array of neighbouring pixels. | |
| 564 | + * | |
| 565 | + * Returns the 8 neighbours of a given pixel. The method returns a vector | |
| 566 | + * with contains the pixel indices of the SW, W, NW, N, NE, E, SE and S | |
| 567 | + * neighbours of @p pix (in the given order). If a neighbour does not exist | |
| 568 | + * (this can only be the case for the W, N, E and S neighbors), its entry is | |
| 569 | + * set to -1. | |
| 570 | + * | |
| 571 | + * This method has been adapted from the neighbors() function located in the | |
| 572 | + * file healpix_base.cc in Healpix version 3.20. | |
| 573 | + ***************************************************************************/ | |
| 574 | +std::vector<int> GHealpix::neighbours(const GSkyPixel& pixel) const | |
| 575 | +{ | |
| 576 | + // Throw an exception if sky map pixel is not 1D | |
| 577 | + if (!pixel.is_1D()) { | |
| 578 | + std::string msg = "Sky map pixel "+pixel.print()+" is not" | |
| 579 | + " 1-dimensional.\n" | |
| 580 | + "Only 1-dimensional pixels are supported by the" | |
| 581 | + " Healpix projection."; | |
| 582 | + throw GException::invalid_argument(G_NEIGHBOURS, msg); | |
| 583 | + } | |
| 584 | + | |
| 585 | + // Initialise result array | |
| 586 | + std::vector<int> result; | |
| 587 | + | |
| 588 | + // Determine pixel index and face number | |
| 589 | + int ix; | |
| 590 | + int iy; | |
| 591 | + int face_num; | |
| 592 | + pix2xyf(int(pixel), &ix, &iy, &face_num); | |
| 593 | + | |
| 594 | + // ... | |
| 595 | + const int nsm1 = m_nside - 1; | |
| 596 | + | |
| 597 | + // ... | |
| 598 | + if ((ix > 0) && (ix < nsm1) && (iy > 0) && (iy < nsm1)) { | |
| 599 | + | |
| 600 | + // Ring ordering scheme ... | |
| 601 | + if (m_ordering == 0) { // Ring? | |
| 602 | + for (int m = 0; m < 8; ++m) { | |
| 603 | + int index = xyf2ring(ix+nb_xoffset[m],iy+nb_yoffset[m],face_num); | |
| 604 | + result.push_back(index); | |
| 605 | + } | |
| 606 | + } | |
| 607 | + | |
| 608 | + // ... or nested scheme? | |
| 609 | + else { | |
| 610 | + int fpix = int(face_num) << (2*m_order); | |
| 611 | + int px0 = spread_bits(ix); | |
| 612 | + int py0 = spread_bits(iy) << 1; | |
| 613 | + int pxp = spread_bits(ix+1); | |
| 614 | + int pyp = spread_bits(iy+1) << 1; | |
| 615 | + int pxm = spread_bits(ix-1); | |
| 616 | + int pym = spread_bits(iy-1) << 1; | |
| 617 | + result.push_back(fpix + pxm + py0); | |
| 618 | + result.push_back(fpix + pxm + pyp); | |
| 619 | + result.push_back(fpix + px0 + pyp); | |
| 620 | + result.push_back(fpix + pxp + pyp); | |
| 621 | + result.push_back(fpix + pxp + py0); | |
| 622 | + result.push_back(fpix + pxp + pym); | |
| 623 | + result.push_back(fpix + px0 + pym); | |
| 624 | + result.push_back(fpix + pxm + pym); | |
| 625 | + } | |
| 626 | + | |
| 627 | + } // endif | |
| 628 | + | |
| 629 | + // ... | |
| 630 | + else { | |
| 631 | + for (int i = 0; i < 8; ++i) { | |
| 632 | + int x = ix + nb_xoffset[i]; | |
| 633 | + int y = iy + nb_yoffset[i]; | |
| 634 | + int nbnum = 4; | |
| 635 | + if (x < 0) { | |
| 636 | + x += m_nside; | |
| 637 | + nbnum -= 1; | |
| 638 | + } | |
| 639 | + else if (x >= m_nside) { | |
| 640 | + x -= m_nside; | |
| 641 | + nbnum += 1; | |
| 642 | + } | |
| 643 | + if (y < 0) { | |
| 644 | + y += m_nside; | |
| 645 | + nbnum -= 3; | |
| 646 | + } | |
| 647 | + else if (y >= m_nside) { | |
| 648 | + y -= m_nside; | |
| 649 | + nbnum += 3; | |
| 650 | + } | |
| 651 | + | |
| 652 | + // Compute face | |
| 653 | + int f = nb_facearray[nbnum][face_num]; | |
| 654 | + | |
| 655 | + // If face is valid then compute index | |
| 656 | + if (f >= 0) { | |
| 657 | + int bits = nb_swaparray[nbnum][face_num>>2]; | |
| 658 | + if (bits & 1) { | |
| 659 | + x = m_nside - x - 1; | |
| 660 | + } | |
| 661 | + if (bits & 2) { | |
| 662 | + y = m_nside - y - 1; | |
| 663 | + } | |
| 664 | + if (bits & 4) { | |
| 665 | + std::swap(x,y); | |
| 666 | + } | |
| 667 | + if (m_ordering == 0) { // Ring? | |
| 668 | + result.push_back(xyf2ring(x, y, f)); | |
| 669 | + } | |
| 670 | + else { | |
| 671 | + result.push_back(xyf2nest(x, y, f)); | |
| 672 | + } | |
| 673 | + } | |
| 674 | + | |
| 675 | + // ... otherwise push back an invalid pixel | |
| 676 | + else { | |
| 677 | + result.push_back(-1); | |
| 678 | + } | |
| 679 | + | |
| 680 | + } // endfor | |
| 681 | + | |
| 682 | + } // endelse | |
| 683 | + | |
| 684 | + // Return indices | |
| 685 | + return result; | |
| 686 | +} | |
| 687 | + | |
| 688 | + | |
| 689 | +/***********************************************************************//** | |
| 690 | + * @brief Return pixel boundaries | |
| 691 | + * | |
| 692 | + * @param[in] pixel Sky pixel. | |
| 693 | + * @param[in] step Number of returned points (4*step, defaults to 4). | |
| 694 | + * @return Array of pixel boundaries. | |
| 695 | + * | |
| 696 | + * The method returns a vector with sky directions along the boundary of a | |
| 697 | + * HealPix pixel. By default, the 4 corners of HealPix pixel will be | |
| 698 | + * returned. The first point corresponds to the northernmost corner, the | |
| 699 | + * subsequent points follow the pixel boundary through west, south and east | |
| 700 | + * corners. If step>1 more intermediate points will be added after the 4th | |
| 701 | + * corner of the pixel. | |
| 702 | + * | |
| 703 | + * This method has been adapted from the boundaries() function located in the | |
| 704 | + * file healpix_base.cc in Healpix version 3.20. | |
| 705 | + ***************************************************************************/ | |
| 706 | +std::vector<GSkyDir> GHealpix::boundaries(const GSkyPixel& pixel, | |
| 707 | + const int& step) const | |
| 708 | +{ | |
| 709 | + // Throw an exception if sky map pixel is not 1D | |
| 710 | + if (!pixel.is_1D()) { | |
| 711 | + std::string msg = "Sky map pixel "+pixel.print()+" is not" | |
| 712 | + " 1-dimensional.\n" | |
| 713 | + "Only 1-dimensional pixels are supported by the" | |
| 714 | + " Healpix projection."; | |
| 715 | + throw GException::invalid_argument(G_BOUNDARIES, msg); | |
| 716 | + } | |
| 717 | + | |
| 718 | + // Allocate boundaries | |
| 719 | + std::vector<GSkyDir> boundaries; | |
| 720 | + | |
| 721 | + // Determine pixel index and face number | |
| 722 | + int ix; | |
| 723 | + int iy; | |
| 724 | + int face; | |
| 725 | + pix2xyf(int(pixel), &ix, &iy, &face); | |
| 726 | + | |
| 727 | + // ... | |
| 728 | + double dc = 0.5 / m_nside; | |
| 729 | + double xc = (ix + 0.5) / m_nside; | |
| 730 | + double yc = (iy + 0.5) / m_nside; | |
| 731 | + double d = 1.0 / (step*m_nside); | |
| 732 | + | |
| 733 | + // | |
| 734 | + for (int i = 0; i < step; ++i) { | |
| 735 | + | |
| 736 | + // Declare local coordinates | |
| 737 | + double z; | |
| 738 | + double phi; | |
| 739 | + | |
| 740 | + // First coordinate | |
| 741 | + xyf2loc(xc+dc-i*d, yc+dc, face, &z, &phi); | |
| 742 | + boundaries.push_back(loc2dir(z, phi)); | |
| 743 | + | |
| 744 | + // Second coordinate | |
| 745 | + xyf2loc(xc-dc, yc+dc-i*d, face, &z, &phi); | |
| 746 | + boundaries.push_back(loc2dir(z, phi)); | |
| 747 | + | |
| 748 | + // Third coordinate | |
| 749 | + xyf2loc(xc-dc+i*d, yc-dc, face, &z, &phi); | |
| 750 | + boundaries.push_back(loc2dir(z, phi)); | |
| 751 | + | |
| 752 | + // Forth coordinate | |
| 753 | + xyf2loc(xc+dc, yc-dc+i*d, face, &z, &phi); | |
| 754 | + boundaries.push_back(loc2dir(z, phi)); | |
| 755 | + | |
| 756 | + } // endfor: looped over step size | |
| 757 | + | |
| 758 | + // Return boundaries | |
| 759 | + return boundaries; | |
| 760 | +} | |
| 761 | + | |
| 762 | + | |
| 763 | +/***********************************************************************//** | |
| 764 | + * @brief Return maximum angular distance between pixel centre and corners | |
| 765 | + * | |
| 766 | + * @return Maximum angular distance between pixel centre and corners (radians). | |
| 767 | + * | |
| 768 | + * Returns the maximum angular distance (in radians) between any pixel | |
| 769 | + * centre and its corners. | |
| 770 | + * | |
| 771 | + * This method has been adapted from the max_pixrad() function located in the | |
| 772 | + * file healpix_base.cc in Healpix version 3.20. | |
| 773 | + ***************************************************************************/ | |
| 774 | +double GHealpix::max_pixrad(void) const | |
| 775 | +{ | |
| 776 | + // Compute ... | |
| 777 | + double t1 = 1.0 - 1.0/m_nside; | |
| 778 | + t1 *= t1; | |
| 779 | + | |
| 780 | + // Get vectors | |
| 781 | + GVector va = set_z_phi(2.0/3.0, gammalib::pi/(4*m_nside)); | |
| 782 | + GVector vb = set_z_phi(1.0 - t1/3, 0.0); | |
| 783 | + | |
| 784 | + // Get angle | |
| 785 | + double angle = std::atan2(norm(cross(va, vb)), va * vb); | |
| 786 | + | |
| 787 | + // Return angle | |
| 788 | + return angle; | |
| 789 | +} | |
| 790 | + | |
| 791 | + | |
| 792 | +/***********************************************************************//** | |
| 537 | 793 | * @brief Print WCS information |
| 538 | 794 | * |
| 539 | 795 | * @param[in] chatter Chattiness (defaults to NORMAL). |
| ... | ... | @@ -720,9 +976,37 @@ int GHealpix::spread_bits(const int& value) const |
| 720 | 976 | |
| 721 | 977 | |
| 722 | 978 | /***********************************************************************//** |
| 979 | + * @brief Convert pixel number in to (x,y,face) tuple | |
| 980 | + * | |
| 981 | + * @param[in] pix Pixel number. | |
| 982 | + * @param[out] ix X index. | |
| 983 | + * @param[out] iy Y index. | |
| 984 | + * @param[out] face Face number. | |
| 985 | + * | |
| 986 | + * This method has been adapted from the pix2xyf() function located in | |
| 987 | + * the file healpix_base.cc in Healpix version 3.20. | |
| 988 | + ***************************************************************************/ | |
| 989 | +void GHealpix::pix2xyf(const int& pix, int* ix, int* iy, int* face) const | |
| 990 | +{ | |
| 991 | + // Handle ring scheme ... | |
| 992 | + if (m_ordering == 0) { | |
| 993 | + ring2xyf(pix, ix, iy, face); | |
| 994 | + } | |
| 995 | + | |
| 996 | + // ... or nested scheme | |
| 997 | + else { | |
| 998 | + nest2xyf(pix, ix, iy, face); | |
| 999 | + } | |
| 1000 | + | |
| 1001 | + // Return | |
| 1002 | + return; | |
| 1003 | +} | |
| 1004 | + | |
| 1005 | + | |
| 1006 | +/***********************************************************************//** | |
| 723 | 1007 | * @brief Convert pixel number in nested scheme to (x,y,face) tuple |
| 724 | 1008 | * |
| 725 | - * @param[in] pix Pixel number in nested scheme | |
| 1009 | + * @param[in] pix Pixel number in nested scheme. | |
| 726 | 1010 | * @param[out] ix X index. |
| 727 | 1011 | * @param[out] iy Y index. |
| 728 | 1012 | * @param[out] face Face number. |
| ... | ... | @@ -887,6 +1171,91 @@ int GHealpix::xyf2ring(const int& ix, const int& iy, const int& face) const |
| 887 | 1171 | |
| 888 | 1172 | |
| 889 | 1173 | /***********************************************************************//** |
| 1174 | + * @brief Convert (x,y,f) tuple into local coordinates | |
| 1175 | + * | |
| 1176 | + * @param[in] x X value. | |
| 1177 | + * @param[in] y Y value. | |
| 1178 | + * @param[in] face Face number. | |
| 1179 | + * @param[out] z Z value. | |
| 1180 | + * @param[out] phi Phi value. | |
| 1181 | + * | |
| 1182 | + * This method has been adapted from the xyf2loc() function located in the | |
| 1183 | + * file healpix_base.cc in Healpix version 3.20. | |
| 1184 | + ***************************************************************************/ | |
| 1185 | +void GHealpix::xyf2loc(const double& x, const double& y, const int& face, | |
| 1186 | + double* z, double* phi) const | |
| 1187 | +{ | |
| 1188 | + // ... | |
| 1189 | + double jr = jrll[face] - x - y; | |
| 1190 | + double nr; | |
| 1191 | + | |
| 1192 | + // Compute z | |
| 1193 | + if (jr < 1) { | |
| 1194 | + nr = jr; | |
| 1195 | + double tmp = nr*nr / 3.0; | |
| 1196 | + *z = 1 - tmp; | |
| 1197 | + } | |
| 1198 | + else if (jr > 3) { | |
| 1199 | + nr = 4 - jr; | |
| 1200 | + double tmp = nr*nr / 3.0; | |
| 1201 | + *z = tmp - 1; | |
| 1202 | + } | |
| 1203 | + else { | |
| 1204 | + nr = 1; | |
| 1205 | + *z = (2.0-jr) * 2.0/3.0; | |
| 1206 | + } | |
| 1207 | + | |
| 1208 | + // Compute Phi | |
| 1209 | + double tmp = jpll[face] * nr + x - y; | |
| 1210 | + if (tmp < 0) { | |
| 1211 | + tmp += 8; | |
| 1212 | + } | |
| 1213 | + if (tmp >= 8) { | |
| 1214 | + tmp -= 8; | |
| 1215 | + } | |
| 1216 | + *phi = (nr < 1.0e-15) ? 0.0 : (0.5 * gammalib::pihalf * tmp) / nr; | |
| 1217 | + | |
| 1218 | + // Return | |
| 1219 | + return; | |
| 1220 | +} | |
| 1221 | + | |
| 1222 | + | |
| 1223 | +/***********************************************************************//** | |
| 1224 | + * @brief Convert local coordinate into sky direction | |
| 1225 | + * | |
| 1226 | + * @param[in] z Z value. | |
| 1227 | + * @param[in] phi Phi value. | |
| 1228 | + * @return Sky direction. | |
| 1229 | + * | |
| 1230 | + * This method has been adapted from the locToVec3() function located in | |
| 1231 | + * the file healpix_base.cc in Healpix version 3.20. | |
| 1232 | + ***************************************************************************/ | |
| 1233 | +GSkyDir GHealpix::loc2dir(const double& z, const double& phi) const | |
| 1234 | +{ | |
| 1235 | + // Compute longitude and latitude | |
| 1236 | + double sintheta = std::sqrt((1.0 - z) * (1.0 + z)); | |
| 1237 | + double longitude = std::atan2(sintheta * std::sin(phi), sintheta * std::cos(phi)); | |
| 1238 | + double latitude = std::asin(z); | |
| 1239 | + | |
| 1240 | + // Set sky direction | |
| 1241 | + GSkyDir dir; | |
| 1242 | + switch (m_coordsys) { | |
| 1243 | + case 0: | |
| 1244 | + dir.radec(longitude, latitude); | |
| 1245 | + break; | |
| 1246 | + case 1: | |
| 1247 | + dir.lb(longitude, latitude); | |
| 1248 | + break; | |
| 1249 | + default: | |
| 1250 | + break; | |
| 1251 | + } | |
| 1252 | + | |
| 1253 | + // Return sky direction | |
| 1254 | + return dir; | |
| 1255 | +} | |
| 1256 | + | |
| 1257 | + | |
| 1258 | +/***********************************************************************//** | |
| 890 | 1259 | * @brief Convert nside to order |
| 891 | 1260 | * |
| 892 | 1261 | * @param[in] nside Number of sides. |
| ... | ... | @@ -1459,7 +1828,7 @@ GBilinear GHealpix::interpolator(const double& theta, const double& phi) const |
| 1459 | 1828 | // Now handle the special case that the colatitude is North of all |
| 1460 | 1829 | // rings |
| 1461 | 1830 | if (ir1 == 0) { |
| 1462 | - double wtheta = theta/theta2; | |
| 1831 | + double wtheta = theta/theta2; | |
| 1463 | 1832 | interpolator.weight3() *= wtheta; |
| 1464 | 1833 | interpolator.weight4() *= wtheta; |
| 1465 | 1834 | double fac = (1.0-wtheta)*0.25; |
| ... | ... | @@ -1473,7 +1842,7 @@ GBilinear GHealpix::interpolator(const double& theta, const double& phi) const |
| 1473 | 1842 | |
| 1474 | 1843 | // ... and now the case that the colatitude is South of all rings |
| 1475 | 1844 | else if (ir2 == 4*m_nside) { |
| 1476 | - double wtheta = (theta-theta1) / (gammalib::pi-theta1); | |
| 1845 | + double wtheta = (theta-theta1) / (gammalib::pi-theta1); | |
| 1477 | 1846 | interpolator.weight1() *= (1.0 - wtheta); |
| 1478 | 1847 | interpolator.weight2() *= (1.0 - wtheta); |
| 1479 | 1848 | double fac = wtheta*0.25; |
| ... | ... | @@ -1487,7 +1856,7 @@ GBilinear GHealpix::interpolator(const double& theta, const double& phi) const |
| 1487 | 1856 | |
| 1488 | 1857 | // ... and now multiply-in the theta weights for the general case |
| 1489 | 1858 | else { |
| 1490 | - double wtheta = (theta-theta1) / (theta2-theta1); | |
| 1859 | + double wtheta = (theta-theta1) / (theta2-theta1); | |
| 1491 | 1860 | interpolator.weight1() *= (1.0 - wtheta); |
| 1492 | 1861 | interpolator.weight2() *= (1.0 - wtheta); |
| 1493 | 1862 | interpolator.weight3() *= wtheta; |
| ... | ... | @@ -1520,3 +1889,29 @@ unsigned int GHealpix::isqrt(unsigned int arg) const |
| 1520 | 1889 | // Return |
| 1521 | 1890 | return unsigned(std::sqrt(arg+0.5)); |
| 1522 | 1891 | } |
| 1892 | + | |
| 1893 | + | |
| 1894 | +/***********************************************************************//** | |
| 1895 | + * @brief Return 3D vector | |
| 1896 | + * | |
| 1897 | + * @param[in] z Z value. | |
| 1898 | + * @param[in] phi Phi value. | |
| 1899 | + * @return 3D vector | |
| 1900 | + * | |
| 1901 | + * This method has been adapted from the set_z_phi() function located in the | |
| 1902 | + * file vec3.h in Healpix version 3.20. | |
| 1903 | + ***************************************************************************/ | |
| 1904 | +GVector GHealpix::set_z_phi(const double& z, const double& phi) const | |
| 1905 | +{ | |
| 1906 | + // Initialise 3D vector | |
| 1907 | + GVector vector(3); | |
| 1908 | + | |
| 1909 | + // Assign elements | |
| 1910 | + double sintheta = std::sqrt((1.0 - z) * (1.0 + z)); | |
| 1911 | + vector[0] = sintheta * std::cos(phi); | |
| 1912 | + vector[1] = sintheta * std::sin(phi); | |
| 1913 | + vector[2] = z; | |
| 1914 | + | |
| 1915 | + // Return vector | |
| 1916 | + return vector; | |
| 1917 | +} | ... | ... |