Commit f5618c950ceb03c0949aa09c4eaa9d1b3160a74a
1 parent
257bd8bf
Implement generic GSkyPixel class and rename pixel/index/direction conversion methods consistently.
The GSkyPixel class now handles 1D and 2D sky indices. This made the distinctive 1D and 2D methods in GSkyProjection and the derived classes obsolete. Now, all projection classes take GSkyPixel as argument. The GSkymap class now uses the universal GSkyPixel class. Methods have been renamed consistently. An integer index is now consistently called "sky map index" and the GSkyPixel object is named a "sky map pixel". Methods operating on indices contain now "inx", method operating on sky map pixels "pix".
Showing
22 changed files
with
779 additions
and
764 deletions
include/GHealpix.hpp
| ... | ... | @@ -61,16 +61,14 @@ public: |
| 61 | 61 | // Implemented pure virtual base class methods |
| 62 | 62 | virtual void clear(void); |
| 63 | 63 | virtual GHealpix* clone(void) const; |
| 64 | + virtual int size(void) const; | |
| 64 | 65 | virtual std::string code(void) const; |
| 65 | 66 | virtual std::string name(void) const; |
| 66 | 67 | virtual void read(const GFitsHDU* hdu); |
| 67 | 68 | virtual void write(GFitsHDU* hdu) const; |
| 68 | - virtual double omega(const int& pix) const; | |
| 69 | - virtual double omega(const GSkyPixel& pix) const; | |
| 70 | - virtual GSkyDir pix2dir(const int& pix) const; | |
| 71 | - virtual int dir2pix(const GSkyDir& dir) const; | |
| 72 | - virtual GSkyDir xy2dir(const GSkyPixel& pix) const; | |
| 73 | - virtual GSkyPixel dir2xy(const GSkyDir& dir) const; | |
| 69 | + virtual double omega(const GSkyPixel& pixel) const; | |
| 70 | + virtual GSkyDir pix2dir(const GSkyPixel& pixel) const; | |
| 71 | + virtual GSkyPixel dir2pix(const GSkyDir& dir) const; | |
| 74 | 72 | virtual std::string print(const GChatter& chatter = NORMAL) const; |
| 75 | 73 | |
| 76 | 74 | // Other methods |
| ... | ... | @@ -108,6 +106,20 @@ private: |
| 108 | 106 | |
| 109 | 107 | |
| 110 | 108 | /***********************************************************************//** |
| 109 | + * @brief Return dimension of projection | |
| 110 | + * | |
| 111 | + * @return Dimension of projection. | |
| 112 | + * | |
| 113 | + * Returns the dimension of the projection. | |
| 114 | + ***************************************************************************/ | |
| 115 | +inline | |
| 116 | +int GHealpix::size(void) const | |
| 117 | +{ | |
| 118 | + return 1; | |
| 119 | +} | |
| 120 | + | |
| 121 | + | |
| 122 | +/***********************************************************************//** | |
| 111 | 123 | * @brief Return projection code |
| 112 | 124 | * |
| 113 | 125 | * @return Projection code. | ... | ... |
include/GSkyProjection.hpp
| ... | ... | @@ -62,16 +62,14 @@ public: |
| 62 | 62 | // Pure virtual methods |
| 63 | 63 | virtual void clear(void) = 0; |
| 64 | 64 | virtual GSkyProjection* clone(void) const = 0; |
| 65 | + virtual int size(void) const = 0; | |
| 65 | 66 | virtual std::string code(void) const = 0; |
| 66 | 67 | virtual std::string name(void) const = 0; |
| 67 | 68 | virtual void read(const GFitsHDU* hdu) = 0; |
| 68 | 69 | virtual void write(GFitsHDU* hdu) const = 0; |
| 69 | - virtual double omega(const int& pix) const = 0; | |
| 70 | - virtual double omega(const GSkyPixel& pix) const = 0; | |
| 71 | - virtual GSkyDir pix2dir(const int& pix) const = 0; | |
| 72 | - virtual int dir2pix(const GSkyDir& dir) const = 0; | |
| 73 | - virtual GSkyDir xy2dir(const GSkyPixel& pix) const = 0; | |
| 74 | - virtual GSkyPixel dir2xy(const GSkyDir& dir) const = 0; | |
| 70 | + virtual double omega(const GSkyPixel& pixel) const = 0; | |
| 71 | + virtual GSkyDir pix2dir(const GSkyPixel& pixel) const = 0; | |
| 72 | + virtual GSkyPixel dir2pix(const GSkyDir& dir) const = 0; | |
| 75 | 73 | virtual std::string print(const GChatter& chatter = NORMAL) const = 0; |
| 76 | 74 | |
| 77 | 75 | // Virtual methods | ... | ... |
include/GSkymap.hpp
| ... | ... | @@ -45,20 +45,22 @@ |
| 45 | 45 | /***********************************************************************//** |
| 46 | 46 | * @class GSkymap |
| 47 | 47 | * |
| 48 | - * @brief GSkymap class interface defintion | |
| 48 | + * @brief Sky map class | |
| 49 | 49 | * |
| 50 | - * This class implements a set of skymaps. Skymaps may either be present in | |
| 50 | + * This class implements a set of sky maps. Skymaps may either be present in | |
| 51 | 51 | * the HEALPix format or in any (supported) WCS format. Skymap pixels are |
| 52 | 52 | * stored in a double precision array indexed by (x,y,map), with the x |
| 53 | 53 | * axis being the most rapidely varying axis. |
| 54 | 54 | * |
| 55 | - * Skymap pixels may be either accessed via 1D operators (i,map), where i | |
| 56 | - * runs over the (x,y) direction of the map, or via 2D operators (pixel,map), | |
| 55 | + * Skymap pixels may be either accessed via index operators (i,map), where i | |
| 56 | + * runs over the (x,y) direction of the map, or via pixel operators (pixel,map), | |
| 57 | 57 | * where pixel implements a 2D (x,y) pixel direction. The first operator is |
| 58 | 58 | * the preferred access method for HEALPix maps while the second operator is |
| 59 | 59 | * the preferred access method for WCS maps. Conversion methods between the |
| 60 | 60 | * index or sky pixel and the true physical sky direction are provided by the |
| 61 | 61 | * pix2dir() and dir2pix() methods. |
| 62 | + * | |
| 63 | + * @todo Rewrite class description. | |
| 62 | 64 | ***************************************************************************/ |
| 63 | 65 | class GSkymap : public GBase { |
| 64 | 66 | |
| ... | ... | @@ -83,44 +85,38 @@ public: |
| 83 | 85 | virtual ~GSkymap(void); |
| 84 | 86 | |
| 85 | 87 | // Operators |
| 86 | - GSkymap& operator=(const GSkymap& map); | |
| 87 | - | |
| 88 | - // 1D pixel methods | |
| 89 | - double& operator()(const int& pixel, const int& map = 0); | |
| 90 | - const double& operator()(const int& pixel, const int& map = 0) const; | |
| 91 | - GSkyDir pix2dir(const int& pix) const; | |
| 92 | - int dir2pix(const GSkyDir& dir) const; | |
| 93 | - double omega(const int& pix) const; | |
| 94 | - | |
| 95 | - // 2D pixel methods | |
| 88 | + GSkymap& operator=(const GSkymap& map); | |
| 89 | + double& operator()(const int& index, const int& map = 0); | |
| 90 | + const double& operator()(const int& index, const int& map = 0) const; | |
| 96 | 91 | double& operator()(const GSkyPixel& pixel, const int& map = 0); |
| 97 | 92 | const double& operator()(const GSkyPixel& pixel, const int& map = 0) const; |
| 98 | - GSkyDir xy2dir(const GSkyPixel& pix) const; | |
| 99 | - GSkyPixel dir2xy(const GSkyDir& dir) const; | |
| 100 | - double omega(const GSkyPixel& pix) const; | |
| 101 | - | |
| 102 | - // Sky direction methods | |
| 103 | 93 | double operator()(const GSkyDir& dir, const int& map = 0) const; |
| 104 | 94 | |
| 105 | 95 | // Methods |
| 106 | - void clear(void); | |
| 107 | - GSkymap* clone(void) const; | |
| 108 | - void load(const std::string& filename); | |
| 109 | - void save(const std::string& filename, bool clobber = false) const; | |
| 110 | - void read(const GFitsHDU* hdu); | |
| 111 | - void write(GFits* file) const; | |
| 112 | - int npix(void) const; | |
| 113 | - int nx(void) const; | |
| 114 | - int ny(void) const; | |
| 115 | - int nmaps(void) const; | |
| 116 | - int xy2pix(const GSkyPixel& pix) const; | |
| 117 | - GSkyPixel pix2xy(const int& pix) const; | |
| 118 | - GSkyProjection* projection(void) const { return m_proj; } | |
| 119 | - void projection(const GSkyProjection& proj); | |
| 120 | - double* pixels(void) const { return m_pixels; } | |
| 121 | - bool contains(const GSkyDir& dir) const; | |
| 122 | - bool contains(const GSkyPixel& pixel) const; | |
| 123 | - std::string print(const GChatter& chatter = NORMAL) const; | |
| 96 | + void clear(void); | |
| 97 | + GSkymap* clone(void) const; | |
| 98 | + const int& npix(void) const; | |
| 99 | + const int& nx(void) const; | |
| 100 | + const int& ny(void) const; | |
| 101 | + const int& nmaps(void) const; | |
| 102 | + GSkyPixel inx2pix(const int& index) const; | |
| 103 | + GSkyDir inx2dir(const int& index) const; | |
| 104 | + GSkyDir pix2dir(const GSkyPixel& pixel) const; | |
| 105 | + int pix2inx(const GSkyPixel& pixel) const; | |
| 106 | + int dir2inx(const GSkyDir& dir) const; | |
| 107 | + GSkyPixel dir2pix(const GSkyDir& dir) const; | |
| 108 | + double omega(const int& index) const; | |
| 109 | + double omega(const GSkyPixel& pixel) const; | |
| 110 | + bool contains(const GSkyDir& dir) const; | |
| 111 | + bool contains(const GSkyPixel& pixel) const; | |
| 112 | + const GSkyProjection* projection(void) const; | |
| 113 | + void projection(const GSkyProjection& proj); | |
| 114 | + const double* pixels(void) const; | |
| 115 | + void load(const std::string& filename); | |
| 116 | + void save(const std::string& filename, bool clobber = false) const; | |
| 117 | + void read(const GFitsHDU* hdu); | |
| 118 | + void write(GFits* file) const; | |
| 119 | + std::string print(const GChatter& chatter = NORMAL) const; | |
| 124 | 120 | |
| 125 | 121 | private: |
| 126 | 122 | // Private methods |
| ... | ... | @@ -148,4 +144,86 @@ private: |
| 148 | 144 | double* m_pixels; //!< Pointer to skymap pixels |
| 149 | 145 | }; |
| 150 | 146 | |
| 147 | + | |
| 148 | +/***********************************************************************//** | |
| 149 | + * @brief Returns number of pixels | |
| 150 | + * | |
| 151 | + * @return Number of pixels in one sky map. | |
| 152 | + * | |
| 153 | + * Returns the number of pixels in one sky map. | |
| 154 | + ***************************************************************************/ | |
| 155 | +inline | |
| 156 | +const int& GSkymap::npix(void) const | |
| 157 | +{ | |
| 158 | + return m_num_pixels; | |
| 159 | +} | |
| 160 | + | |
| 161 | + | |
| 162 | +/***********************************************************************//** | |
| 163 | + * @brief Returns number of pixels in x coordinate | |
| 164 | + * | |
| 165 | + * @return Number of pixels in the X direction. | |
| 166 | + * | |
| 167 | + * Returns the number of pixels in the X direction. If the sky map is a | |
| 168 | + * one dimensional array (which is the case for the Healpix projection), | |
| 169 | + * the method returns 0. | |
| 170 | + ***************************************************************************/ | |
| 171 | +inline | |
| 172 | +const int& GSkymap::nx(void) const | |
| 173 | +{ | |
| 174 | + return m_num_x; | |
| 175 | +} | |
| 176 | + | |
| 177 | + | |
| 178 | +/***********************************************************************//** | |
| 179 | + * @brief Returns number of pixels in y coordinate | |
| 180 | + * | |
| 181 | + * @return Number of pixels in the Y direction. | |
| 182 | + * | |
| 183 | + * Returns the number of pixels in the Y direction. If the sky map is a | |
| 184 | + * one dimensional array (which is the case for the Healpix projection), | |
| 185 | + * the method returns 0. | |
| 186 | + ***************************************************************************/ | |
| 187 | +inline | |
| 188 | +const int& GSkymap::ny(void) const | |
| 189 | +{ | |
| 190 | + return m_num_y; | |
| 191 | +} | |
| 192 | + | |
| 193 | + | |
| 194 | +/***********************************************************************//** | |
| 195 | + * @brief Returns number of maps | |
| 196 | + * | |
| 197 | + * @return Number of maps in the sky map object. | |
| 198 | + ***************************************************************************/ | |
| 199 | +inline | |
| 200 | +const int& GSkymap::nmaps(void) const | |
| 201 | +{ | |
| 202 | + return m_num_maps; | |
| 203 | +} | |
| 204 | + | |
| 205 | + | |
| 206 | +/***********************************************************************//** | |
| 207 | + * @brief Returns pointer to sky projection | |
| 208 | + * | |
| 209 | + * @return Pointer to sky projection (NULL if no projection is defined). | |
| 210 | + ***************************************************************************/ | |
| 211 | +inline | |
| 212 | +const GSkyProjection* GSkymap::projection(void) const | |
| 213 | +{ | |
| 214 | + return m_proj; | |
| 215 | +} | |
| 216 | + | |
| 217 | + | |
| 218 | +/***********************************************************************//** | |
| 219 | + * @brief Returns pointer to pixel data | |
| 220 | + * | |
| 221 | + * @return Pointer to pixel data. | |
| 222 | + ***************************************************************************/ | |
| 223 | +inline | |
| 224 | +const double* GSkymap::pixels(void) const | |
| 225 | +{ | |
| 226 | + return m_pixels; | |
| 227 | +} | |
| 228 | + | |
| 151 | 229 | #endif /* GSKYMAP_HPP */ | ... | ... |
include/GWcs.hpp
| ... | ... | @@ -67,14 +67,12 @@ public: |
| 67 | 67 | virtual std::string print(const GChatter& chatter = NORMAL) const = 0; |
| 68 | 68 | |
| 69 | 69 | // Implemented virtual base class methods |
| 70 | + virtual int size(void) const; | |
| 70 | 71 | virtual void read(const GFitsHDU* hdu); |
| 71 | 72 | virtual void write(GFitsHDU* hdu) const; |
| 72 | - virtual double omega(const int& pix) const; | |
| 73 | - virtual double omega(const GSkyPixel& pix) const; | |
| 74 | - virtual GSkyDir pix2dir(const int& pix) const; | |
| 75 | - virtual int dir2pix(const GSkyDir& dir) const; | |
| 76 | - virtual GSkyDir xy2dir(const GSkyPixel& pix) const; | |
| 77 | - virtual GSkyPixel dir2xy(const GSkyDir& dir) const; | |
| 73 | + virtual double omega(const GSkyPixel& pixel) const; | |
| 74 | + virtual GSkyDir pix2dir(const GSkyPixel& pixel) const; | |
| 75 | + virtual GSkyPixel dir2pix(const GSkyDir& dir) const; | |
| 78 | 76 | |
| 79 | 77 | // Other methods |
| 80 | 78 | void set(const std::string& coords, |
| ... | ... | @@ -208,4 +206,18 @@ protected: |
| 208 | 206 | //struct spcprm spc |
| 209 | 207 | }; |
| 210 | 208 | |
| 209 | + | |
| 210 | +/***********************************************************************//** | |
| 211 | + * @brief Return dimension of projection | |
| 212 | + * | |
| 213 | + * @return Dimension of projection. | |
| 214 | + * | |
| 215 | + * Returns the dimension of the projection. | |
| 216 | + ***************************************************************************/ | |
| 217 | +inline | |
| 218 | +int GWcs::size(void) const | |
| 219 | +{ | |
| 220 | + return 2; | |
| 221 | +} | |
| 222 | + | |
| 211 | 223 | #endif /* GWCS_HPP */ | ... | ... |
inst/com/src/GCOMEventCube.cpp
| ... | ... | @@ -504,7 +504,7 @@ int GCOMEventCube::number(void) const |
| 504 | 504 | double number = 0.0; |
| 505 | 505 | |
| 506 | 506 | // Get pointer on skymap pixels |
| 507 | - double* pixels = m_map.pixels(); | |
| 507 | + const double* pixels = m_map.pixels(); | |
| 508 | 508 | |
| 509 | 509 | // Sum event cube |
| 510 | 510 | if (size() > 0 && pixels != NULL) { |
| ... | ... | @@ -708,7 +708,7 @@ void GCOMEventCube::set_scatter_directions(void) |
| 708 | 708 | for (int iy = 0; iy < npsi(); ++iy) { |
| 709 | 709 | for (int ix = 0; ix < nchi(); ++ix) { |
| 710 | 710 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 711 | - m_dirs.push_back(m_map.xy2dir(pixel)); | |
| 711 | + m_dirs.push_back(m_map.pix2dir(pixel)); | |
| 712 | 712 | m_omega.push_back(m_map.omega(pixel)); |
| 713 | 713 | } |
| 714 | 714 | } |
| ... | ... | @@ -871,7 +871,7 @@ void GCOMEventCube::set_bin(const int& index) |
| 871 | 871 | m_dir.phibar(m_phi[iphi]); |
| 872 | 872 | |
| 873 | 873 | // Set pointers |
| 874 | - m_bin.m_counts = &(m_map.pixels()[index]); | |
| 874 | + m_bin.m_counts = const_cast<double*>(&(m_map.pixels()[index])); | |
| 875 | 875 | m_bin.m_omega = &(m_omega[ipix]); |
| 876 | 876 | |
| 877 | 877 | // Return | ... | ... |
inst/com/src/GCOMSupport.cpp
| ... | ... | @@ -54,7 +54,7 @@ |
| 54 | 54 | void com_wcs_mer2car(GSkymap& map) |
| 55 | 55 | { |
| 56 | 56 | // Get WCS poiunter |
| 57 | - GWcs* wcs = dynamic_cast<GWcs*>(map.projection()); | |
| 57 | + const GWcs* wcs = dynamic_cast<const GWcs*>(map.projection()); | |
| 58 | 58 | |
| 59 | 59 | // Apply kluge only if the skymap is in Mercator's projection |
| 60 | 60 | if (wcs != NULL && wcs->code() == "MER") { | ... | ... |
inst/cta/src/GCTAEventCube.cpp
| ... | ... | @@ -418,7 +418,7 @@ int GCTAEventCube::number(void) const |
| 418 | 418 | double number = 0.0; |
| 419 | 419 | |
| 420 | 420 | // Get pointer on skymap pixels |
| 421 | - double* pixels = m_map.pixels(); | |
| 421 | + const double* pixels = m_map.pixels(); | |
| 422 | 422 | |
| 423 | 423 | // Sum event cube |
| 424 | 424 | if (size() > 0 && pixels != NULL) { |
| ... | ... | @@ -670,7 +670,7 @@ void GCTAEventCube::set_directions(void) |
| 670 | 670 | for (int iy = 0; iy < ny(); ++iy) { |
| 671 | 671 | for (int ix = 0; ix < nx(); ++ix) { |
| 672 | 672 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 673 | - m_dirs.push_back(GCTAInstDir(m_map.xy2dir(pixel))); | |
| 673 | + m_dirs.push_back(GCTAInstDir(m_map.pix2dir(pixel))); | |
| 674 | 674 | m_omega.push_back(m_map.omega(pixel)); |
| 675 | 675 | } |
| 676 | 676 | } |
| ... | ... | @@ -770,24 +770,27 @@ void GCTAEventCube::set_bin(const int& index) |
| 770 | 770 | { |
| 771 | 771 | // Optionally check if the index is valid |
| 772 | 772 | #if defined(G_RANGE_CHECK) |
| 773 | - if (index < 0 || index >= size()) | |
| 773 | + if (index < 0 || index >= size()) { | |
| 774 | 774 | throw GException::out_of_range(G_SET_BIN, index, 0, size()-1); |
| 775 | + } | |
| 775 | 776 | #endif |
| 776 | 777 | |
| 777 | 778 | // Check for the existence of energies and energy widths |
| 778 | - if (m_energies.size() != ebins() || m_ewidth.size() != ebins()) | |
| 779 | + if (m_energies.size() != ebins() || m_ewidth.size() != ebins()) { | |
| 779 | 780 | throw GCTAException::no_energies(G_SET_BIN); |
| 781 | + } | |
| 780 | 782 | |
| 781 | 783 | // Check for the existence of sky directions and solid angles |
| 782 | - if (m_dirs.size() != npix() || m_omega.size() != npix()) | |
| 784 | + if (m_dirs.size() != npix() || m_omega.size() != npix()) { | |
| 783 | 785 | throw GCTAException::no_dirs(G_SET_BIN); |
| 786 | + } | |
| 784 | 787 | |
| 785 | 788 | // Get pixel and energy bin indices. |
| 786 | 789 | int ipix = index % npix(); |
| 787 | 790 | int ieng = index / npix(); |
| 788 | 791 | |
| 789 | 792 | // Set pointers |
| 790 | - m_bin.m_counts = &(m_map.pixels()[index]); | |
| 793 | + m_bin.m_counts = const_cast<double*>(&(m_map.pixels()[index])); | |
| 791 | 794 | m_bin.m_energy = &(m_energies[ieng]); |
| 792 | 795 | m_bin.m_time = &m_time; |
| 793 | 796 | m_bin.m_dir = &(m_dirs[ipix]); | ... | ... |
inst/lat/src/GLATEventCube.cpp
| ... | ... | @@ -388,7 +388,7 @@ int GLATEventCube::number(void) const |
| 388 | 388 | double number = 0.0; |
| 389 | 389 | |
| 390 | 390 | // Get pointer on skymap pixels |
| 391 | - double* pixels = m_map.pixels(); | |
| 391 | + const double* pixels = m_map.pixels(); | |
| 392 | 392 | |
| 393 | 393 | // Sum event cube |
| 394 | 394 | if (size() > 0 && pixels != NULL) { |
| ... | ... | @@ -561,7 +561,7 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 561 | 561 | int iy = 0; |
| 562 | 562 | for (int ix = 0; ix < nx(); ++ix) { |
| 563 | 563 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 564 | - double distance = m_map.xy2dir(pixel).dist_deg(srcDir); | |
| 564 | + double distance = m_map.pix2dir(pixel).dist_deg(srcDir); | |
| 565 | 565 | if (distance < radius) { |
| 566 | 566 | radius = distance; |
| 567 | 567 | } |
| ... | ... | @@ -571,7 +571,7 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 571 | 571 | iy = ny()-1; |
| 572 | 572 | for (int ix = 0; ix < nx(); ++ix) { |
| 573 | 573 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 574 | - double distance = m_map.xy2dir(pixel).dist_deg(srcDir); | |
| 574 | + double distance = m_map.pix2dir(pixel).dist_deg(srcDir); | |
| 575 | 575 | if (distance < radius) { |
| 576 | 576 | radius = distance; |
| 577 | 577 | } |
| ... | ... | @@ -581,7 +581,7 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 581 | 581 | int ix = 0; |
| 582 | 582 | for (int iy = 0; iy < ny(); ++iy) { |
| 583 | 583 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 584 | - double distance = m_map.xy2dir(pixel).dist_deg(srcDir); | |
| 584 | + double distance = m_map.pix2dir(pixel).dist_deg(srcDir); | |
| 585 | 585 | if (distance < radius) { |
| 586 | 586 | radius = distance; |
| 587 | 587 | } |
| ... | ... | @@ -591,7 +591,7 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 591 | 591 | ix = nx()-1; |
| 592 | 592 | for (int iy = 0; iy < ny(); ++iy) { |
| 593 | 593 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 594 | - double distance = m_map.xy2dir(pixel).dist_deg(srcDir); | |
| 594 | + double distance = m_map.pix2dir(pixel).dist_deg(srcDir); | |
| 595 | 595 | if (distance < radius) { |
| 596 | 596 | radius = distance; |
| 597 | 597 | } |
| ... | ... | @@ -841,7 +841,7 @@ void GLATEventCube::set_directions(void) |
| 841 | 841 | for (int iy = 0; iy < ny(); ++iy) { |
| 842 | 842 | for (int ix = 0; ix < nx(); ++ix) { |
| 843 | 843 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 844 | - m_dirs.push_back(GLATInstDir(m_map.xy2dir(pixel))); | |
| 844 | + m_dirs.push_back(GLATInstDir(m_map.pix2dir(pixel))); | |
| 845 | 845 | m_omega.push_back(m_map.omega(pixel)); |
| 846 | 846 | } |
| 847 | 847 | } |
| ... | ... | @@ -967,7 +967,7 @@ void GLATEventCube::set_bin(const int& index) |
| 967 | 967 | |
| 968 | 968 | // Set pointers |
| 969 | 969 | m_bin.m_cube = this; |
| 970 | - m_bin.m_counts = &(m_map.pixels()[index]); | |
| 970 | + m_bin.m_counts = const_cast<double*>(&(m_map.pixels()[index])); | |
| 971 | 971 | m_bin.m_energy = &(m_energies[m_bin.m_ieng]); |
| 972 | 972 | m_bin.m_time = &m_time; |
| 973 | 973 | m_bin.m_dir = &(m_dirs[m_bin.m_ipix]); | ... | ... |
inst/lat/src/GLATMeanPsf.cpp
| ... | ... | @@ -738,7 +738,7 @@ void GLATMeanPsf::set_map_corrections(const GLATObservation& obs) |
| 738 | 738 | |
| 739 | 739 | // Compute offset angle in degrees |
| 740 | 740 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 741 | - double offset = cube->map().xy2dir(pixel).dist_deg(m_dir); | |
| 741 | + double offset = cube->map().pix2dir(pixel).dist_deg(m_dir); | |
| 742 | 742 | double omega = cube->map().omega(pixel); |
| 743 | 743 | |
| 744 | 744 | // Use only pixels within maximum PSF radius | ... | ... |
inst/lat/src/GLATResponse.cpp
| ... | ... | @@ -400,10 +400,10 @@ double GLATResponse::irf(const GLATEventBin& event, |
| 400 | 400 | nodes.set_value(srcEng.log10MeV()); |
| 401 | 401 | |
| 402 | 402 | // Compute diffuse response |
| 403 | - GSkymap* map = cube->diffrsp(idiff); | |
| 404 | - double* pixels = map->pixels() + event.ipix(); | |
| 405 | - rsp = nodes.wgt_left() * pixels[nodes.inx_left() * map->npix()] + | |
| 406 | - nodes.wgt_right() * pixels[nodes.inx_right() * map->npix()]; | |
| 403 | + GSkymap* map = cube->diffrsp(idiff); | |
| 404 | + const double* pixels = map->pixels() + event.ipix(); | |
| 405 | + rsp = nodes.wgt_left() * pixels[nodes.inx_left() * map->npix()] + | |
| 406 | + nodes.wgt_right() * pixels[nodes.inx_right() * map->npix()]; | |
| 407 | 407 | |
| 408 | 408 | // Divide by solid angle and ontime since source maps are given in units of |
| 409 | 409 | // counts/pixel/MeV. | ... | ... |
inst/lat/test/test_LAT.cpp
| ... | ... | @@ -287,7 +287,7 @@ void TestGLATLtCube::test_one_ltcube(const std::string& datadir, const double& r |
| 287 | 287 | GLATLtCube ltcube(lat_ltcube); |
| 288 | 288 | GEnergy energy; |
| 289 | 289 | for (int i = 0; i < map.npix(); ++i) { |
| 290 | - GSkyDir dir = map.pix2dir(i); | |
| 290 | + GSkyDir dir = map.inx2dir(i); | |
| 291 | 291 | map(i) = ltcube(dir, energy, test_fct1); |
| 292 | 292 | } |
| 293 | 293 | map.save(file1, true); |
| ... | ... | @@ -304,7 +304,7 @@ void TestGLATLtCube::test_one_ltcube(const std::string& datadir, const double& r |
| 304 | 304 | GLATLtCube ltcube(lat_ltcube); |
| 305 | 305 | GEnergy energy; |
| 306 | 306 | for (int i = 0; i < map.npix(); ++i) { |
| 307 | - GSkyDir dir = map.pix2dir(i); | |
| 307 | + GSkyDir dir = map.inx2dir(i); | |
| 308 | 308 | map(i) = ltcube(dir, energy, test_fct2); |
| 309 | 309 | } |
| 310 | 310 | map.save(file2, true); | ... | ... |
pyext/GHealpix.i
| ... | ... | @@ -47,16 +47,14 @@ public: |
| 47 | 47 | // Implemented pure virtual methods |
| 48 | 48 | virtual void clear(void); |
| 49 | 49 | virtual GHealpix* clone(void) const; |
| 50 | + virtual int size(void) const; | |
| 50 | 51 | virtual std::string code(void) const; |
| 51 | 52 | virtual std::string name(void) const; |
| 52 | 53 | virtual void read(const GFitsHDU* hdu); |
| 53 | 54 | virtual void write(GFitsHDU* hdu) const; |
| 54 | - virtual double omega(const int& pix) const; | |
| 55 | - virtual double omega(const GSkyPixel& pix) const; | |
| 56 | - virtual GSkyDir pix2dir(const int& pix) const; | |
| 57 | - virtual int dir2pix(const GSkyDir& dir) const; | |
| 58 | - virtual GSkyDir xy2dir(const GSkyPixel& pix) const; | |
| 59 | - virtual GSkyPixel dir2xy(const GSkyDir& dir) const; | |
| 55 | + virtual double omega(const GSkyPixel& pixel) const; | |
| 56 | + virtual GSkyDir pix2dir(const GSkyPixel& pixel) const; | |
| 57 | + virtual GSkyPixel dir2pix(const GSkyDir& dir) const; | |
| 60 | 58 | |
| 61 | 59 | // Other methods |
| 62 | 60 | const int& npix(void) const; | ... | ... |
pyext/GSkyProjection.i
| ... | ... | @@ -48,16 +48,14 @@ public: |
| 48 | 48 | // Pure virtual methods (not implemented) |
| 49 | 49 | virtual void clear(void) = 0; |
| 50 | 50 | virtual GSkyProjection* clone(void) const = 0; |
| 51 | + virtual int size(void) const = 0; | |
| 51 | 52 | virtual std::string code(void) const = 0; |
| 52 | 53 | virtual std::string name(void) const = 0; |
| 53 | 54 | virtual void read(const GFitsHDU* hdu) = 0; |
| 54 | 55 | virtual void write(GFitsHDU* hdu) const = 0; |
| 55 | - virtual double omega(const int& pix) const = 0; | |
| 56 | - virtual double omega(const GSkyPixel& pix) const = 0; | |
| 57 | - virtual GSkyDir pix2dir(const int& pix) const = 0; | |
| 58 | - virtual int dir2pix(const GSkyDir& dir) const = 0; | |
| 59 | - virtual GSkyDir xy2dir(const GSkyPixel& pix) const = 0; | |
| 60 | - virtual GSkyPixel dir2xy(const GSkyDir& dir) const = 0; | |
| 56 | + virtual double omega(const GSkyPixel& pixel) const = 0; | |
| 57 | + virtual GSkyDir pix2dir(const GSkyPixel& pixel) const = 0; | |
| 58 | + virtual GSkyPixel dir2pix(const GSkyDir& dir) const = 0; | |
| 61 | 59 | |
| 62 | 60 | // Virtual methods |
| 63 | 61 | virtual std::string coordsys(void) const; | ... | ... |
pyext/GSkymap.i
| ... | ... | @@ -127,34 +127,30 @@ public: |
| 127 | 127 | GSkymap(const GSkymap& map); |
| 128 | 128 | virtual ~GSkymap(void); |
| 129 | 129 | |
| 130 | - // 1D pixel methods | |
| 131 | - GSkyDir pix2dir(const int& pix) const; | |
| 132 | - int dir2pix(const GSkyDir& dir) const; | |
| 133 | - double omega(const int& pix) const; | |
| 134 | - | |
| 135 | - // 2D pixel methods | |
| 136 | - GSkyDir xy2dir(const GSkyPixel& pix) const; | |
| 137 | - GSkyPixel dir2xy(const GSkyDir& dir) const; | |
| 138 | - double omega(const GSkyPixel& pix) const; | |
| 139 | - | |
| 140 | 130 | // Methods |
| 141 | - void clear(void); | |
| 142 | - GSkymap* clone(void) const; | |
| 143 | - void load(const std::string& filename); | |
| 144 | - void save(const std::string& filename, bool clobber = false) const; | |
| 145 | - void read(const GFitsHDU* hdu); | |
| 146 | - void write(GFits* file) const; | |
| 147 | - int npix(void) const; | |
| 148 | - int nx(void) const; | |
| 149 | - int ny(void) const; | |
| 150 | - int nmaps(void) const; | |
| 151 | - int xy2pix(const GSkyPixel& pix) const; | |
| 152 | - GSkyPixel pix2xy(const int& pix) const; | |
| 153 | - GSkyProjection* projection(void) const; | |
| 154 | - void projection(const GSkyProjection& proj); | |
| 155 | - double* pixels(void) const; | |
| 156 | - bool contains(const GSkyDir& dir) const; | |
| 157 | - bool contains(const GSkyPixel& pixel) const; | |
| 131 | + void clear(void); | |
| 132 | + GSkymap* clone(void) const; | |
| 133 | + const int& npix(void) const; | |
| 134 | + const int& nx(void) const; | |
| 135 | + const int& ny(void) const; | |
| 136 | + const int& nmaps(void) const; | |
| 137 | + GSkyPixel inx2pix(const int& index) const; | |
| 138 | + GSkyDir inx2dir(const int& index) const; | |
| 139 | + GSkyDir pix2dir(const GSkyPixel& pixel) const; | |
| 140 | + int pix2inx(const GSkyPixel& pixel) const; | |
| 141 | + int dir2inx(const GSkyDir& dir) const; | |
| 142 | + GSkyPixel dir2pix(const GSkyDir& dir) const; | |
| 143 | + double omega(const int& index) const; | |
| 144 | + double omega(const GSkyPixel& pixel) const; | |
| 145 | + bool contains(const GSkyDir& dir) const; | |
| 146 | + bool contains(const GSkyPixel& pixel) const; | |
| 147 | + const GSkyProjection* projection(void) const; | |
| 148 | + void projection(const GSkyProjection& proj); | |
| 149 | + const double* pixels(void) const; | |
| 150 | + void load(const std::string& filename); | |
| 151 | + void save(const std::string& filename, bool clobber = false) const; | |
| 152 | + void read(const GFitsHDU* hdu); | |
| 153 | + void write(GFits* file) const; | |
| 158 | 154 | }; |
| 159 | 155 | |
| 160 | 156 | ... | ... |
pyext/GWcs.i
| ... | ... | @@ -53,14 +53,12 @@ public: |
| 53 | 53 | virtual std::string name(void) const = 0; |
| 54 | 54 | |
| 55 | 55 | // Implemented virtual methods |
| 56 | + virtual int size(void) const; | |
| 56 | 57 | virtual void read(const GFitsHDU* hdu); |
| 57 | 58 | virtual void write(GFitsHDU* hdu) const; |
| 58 | - virtual double omega(const int& pix) const; | |
| 59 | - virtual double omega(const GSkyPixel& pix) const; | |
| 60 | - virtual GSkyDir pix2dir(const int& pix) const; | |
| 61 | - virtual int dir2pix(const GSkyDir& dir) const; | |
| 62 | - virtual GSkyDir xy2dir(const GSkyPixel& pix) const; | |
| 63 | - virtual GSkyPixel dir2xy(const GSkyDir& dir) const; | |
| 59 | + virtual double omega(const GSkyPixel& pixel) const; | |
| 60 | + virtual GSkyDir pix2dir(const GSkyPixel& pixel) const; | |
| 61 | + virtual GSkyPixel dir2pix(const GSkyDir& dir) const; | |
| 64 | 62 | |
| 65 | 63 | // Other methods |
| 66 | 64 | void set(const std::string& coords, | ... | ... |
src/model/GModelSpatialDiffuseCube.cpp
| ... | ... | @@ -446,15 +446,15 @@ GSkyDir GModelSpatialDiffuseCube::mc(const GEnergy& energy, |
| 446 | 446 | } |
| 447 | 447 | } |
| 448 | 448 | |
| 449 | - // Convert 1D pixel index to 2D pixel index | |
| 450 | - GSkyPixel pixel = m_cube.pix2xy(low-offset); | |
| 449 | + // Convert sky map index to sky map pixel | |
| 450 | + GSkyPixel pixel = m_cube.inx2pix(low-offset); | |
| 451 | 451 | |
| 452 | 452 | // Randomize pixel |
| 453 | 453 | pixel.x(pixel.x() + ran.uniform() - 0.5); |
| 454 | 454 | pixel.y(pixel.y() + ran.uniform() - 0.5); |
| 455 | 455 | |
| 456 | 456 | // Get sky direction |
| 457 | - dir = m_cube.xy2dir(pixel); | |
| 457 | + dir = m_cube.pix2dir(pixel); | |
| 458 | 458 | |
| 459 | 459 | } // endif: there were pixels in sky map |
| 460 | 460 | ... | ... |
src/model/GModelSpatialDiffuseMap.cpp
| ... | ... | @@ -350,15 +350,15 @@ GSkyDir GModelSpatialDiffuseMap::mc(const GEnergy& energy, |
| 350 | 350 | } |
| 351 | 351 | } |
| 352 | 352 | |
| 353 | - // Convert 1D pixel index to 2D pixel index | |
| 354 | - GSkyPixel pixel = m_map.pix2xy(low); | |
| 353 | + // Convert sky map index to sky map pixel | |
| 354 | + GSkyPixel pixel = m_map.inx2pix(low); | |
| 355 | 355 | |
| 356 | 356 | // Randomize pixel |
| 357 | 357 | pixel.x(pixel.x() + ran.uniform() - 0.5); |
| 358 | 358 | pixel.y(pixel.y() + ran.uniform() - 0.5); |
| 359 | 359 | |
| 360 | 360 | // Get sky direction |
| 361 | - dir = m_map.xy2dir(pixel); | |
| 361 | + dir = m_map.pix2dir(pixel); | |
| 362 | 362 | |
| 363 | 363 | } // endif: there were pixels in sky map |
| 364 | 364 | ... | ... |
src/sky/GHealpix.cpp
| ... | ... | @@ -350,27 +350,14 @@ void GHealpix::write(GFitsHDU* hdu) const |
| 350 | 350 | /***********************************************************************//** |
| 351 | 351 | * @brief Returns solid angle of pixel |
| 352 | 352 | * |
| 353 | - * @param[in] pix Pixel number (0,1,...,num_pixels). | |
| 353 | + * @param[in] pixel Sky pixel. | |
| 354 | + * @return Solid angle of pixel. | |
| 354 | 355 | * |
| 355 | - * HEALPix pixels have all the same solid angle, hence the pix argument is | |
| 356 | - * not used. | |
| 356 | + * Returns the solid angle of the specified @p pixel. Note that HEALPix | |
| 357 | + * pixels have all the same solid angle, hence the @p pixel argument is in | |
| 358 | + * fact not used by the method. | |
| 357 | 359 | ***************************************************************************/ |
| 358 | -double GHealpix::omega(const int& pix) const | |
| 359 | -{ | |
| 360 | - // Return solid angle | |
| 361 | - return m_omega; | |
| 362 | -} | |
| 363 | - | |
| 364 | - | |
| 365 | -/***********************************************************************//** | |
| 366 | - * @brief Returns solid angle of pixel | |
| 367 | - * | |
| 368 | - * @param[in] pix Sky pixel. | |
| 369 | - * | |
| 370 | - * HEALPix pixels have all the same solid angle, hence the pix argument is | |
| 371 | - * not used. | |
| 372 | - ***************************************************************************/ | |
| 373 | -double GHealpix::omega(const GSkyPixel& pix) const | |
| 360 | +double GHealpix::omega(const GSkyPixel& pixel) const | |
| 374 | 361 | { |
| 375 | 362 | // Return solid angle |
| 376 | 363 | return m_omega; |
| ... | ... | @@ -380,28 +367,35 @@ double GHealpix::omega(const GSkyPixel& pix) const |
| 380 | 367 | /***********************************************************************//** |
| 381 | 368 | * @brief Returns sky direction of pixel |
| 382 | 369 | * |
| 383 | - * @param[in] pix Pixel number (0,1,...,m_num_pixels). | |
| 370 | + * @param[in] pixel Sky map pixel. | |
| 384 | 371 | ***************************************************************************/ |
| 385 | -GSkyDir GHealpix::pix2dir(const int& pix) const | |
| 372 | +GSkyDir GHealpix::pix2dir(const GSkyPixel& pixel) const | |
| 386 | 373 | { |
| 387 | - // Declare result | |
| 388 | - GSkyDir result; | |
| 389 | - double theta = 0.0; | |
| 390 | - double phi = 0.0; | |
| 374 | + // Throw an exception if sky map pixel is not 1D | |
| 375 | + if (!pixel.is1D()) { | |
| 376 | + std::string msg = "Sky map pixel "+pixel.print()+" is not" | |
| 377 | + " 1-dimensional.\n" | |
| 378 | + "Only 1-dimensional pixels are supported by the" | |
| 379 | + " Healpix projection."; | |
| 380 | + throw GException::invalid_argument(G_XY2DIR, msg); | |
| 381 | + } | |
| 391 | 382 | |
| 392 | 383 | // Perform ordering dependent conversion |
| 384 | + double theta = 0.0; | |
| 385 | + double phi = 0.0; | |
| 393 | 386 | switch (m_ordering) { |
| 394 | 387 | case 0: |
| 395 | - pix2ang_ring(pix, &theta, &phi); | |
| 388 | + pix2ang_ring(int(pixel), &theta, &phi); | |
| 396 | 389 | break; |
| 397 | 390 | case 1: |
| 398 | - pix2ang_nest(pix, &theta, &phi); | |
| 391 | + pix2ang_nest(int(pixel), &theta, &phi); | |
| 399 | 392 | break; |
| 400 | 393 | default: |
| 401 | 394 | break; |
| 402 | 395 | } |
| 403 | 396 | |
| 404 | 397 | // Store coordinate system dependent result |
| 398 | + GSkyDir result; | |
| 405 | 399 | switch (m_coordsys) { |
| 406 | 400 | case 0: |
| 407 | 401 | result.radec(phi, gammalib::pihalf - theta); |
| ... | ... | @@ -412,25 +406,23 @@ GSkyDir GHealpix::pix2dir(const int& pix) const |
| 412 | 406 | default: |
| 413 | 407 | break; |
| 414 | 408 | } |
| 415 | - | |
| 416 | - // Return result | |
| 409 | + | |
| 410 | + // Return | |
| 417 | 411 | return result; |
| 418 | 412 | } |
| 419 | 413 | |
| 420 | 414 | |
| 421 | 415 | /***********************************************************************//** |
| 422 | - * @brief Returns pixel for a given sky direction | |
| 416 | + * @brief Returns sky map pixel of sky coordinate | |
| 423 | 417 | * |
| 424 | - * @param[in] dir Sky direction. | |
| 418 | + * @param[in] dir Sky coordinate. | |
| 419 | + * @return Sky map pixel. | |
| 425 | 420 | ***************************************************************************/ |
| 426 | -int GHealpix::dir2pix(const GSkyDir& dir) const | |
| 421 | +GSkyPixel GHealpix::dir2pix(const GSkyDir& dir) const | |
| 427 | 422 | { |
| 428 | - // Declare result | |
| 429 | - int pix; | |
| 423 | + // Compute coordinate system dependent (z,phi) | |
| 430 | 424 | double z; |
| 431 | 425 | double phi; |
| 432 | - | |
| 433 | - // Compute coordinate system dependent (z,phi) | |
| 434 | 426 | switch (m_coordsys) { |
| 435 | 427 | case 0: |
| 436 | 428 | z = cos(gammalib::pihalf - dir.dec()); |
| ... | ... | @@ -445,75 +437,20 @@ int GHealpix::dir2pix(const GSkyDir& dir) const |
| 445 | 437 | } |
| 446 | 438 | |
| 447 | 439 | // Perform ordering dependent conversion |
| 440 | + int index; | |
| 448 | 441 | switch (m_ordering) { |
| 449 | 442 | case 0: |
| 450 | - pix = ang2pix_z_phi_ring(z, phi); | |
| 443 | + index = ang2pix_z_phi_ring(z, phi); | |
| 451 | 444 | break; |
| 452 | 445 | case 1: |
| 453 | - pix = ang2pix_z_phi_nest(z, phi); | |
| 446 | + index = ang2pix_z_phi_nest(z, phi); | |
| 454 | 447 | break; |
| 455 | 448 | default: |
| 456 | 449 | break; |
| 457 | 450 | } |
| 458 | 451 | |
| 459 | - // Return pixel index | |
| 460 | - return pix; | |
| 461 | -} | |
| 462 | - | |
| 463 | - | |
| 464 | -/***********************************************************************//** | |
| 465 | - * @brief Returns sky direction of pixel | |
| 466 | - * | |
| 467 | - * @param[in] pix Sky pixel. | |
| 468 | - * | |
| 469 | - * This dummy method throws an error when called as sky pixels are not | |
| 470 | - * implemented for a HealPix grid. Maybe we should implement them? | |
| 471 | - * | |
| 472 | - * @todo Think about implementation of sky pixel for HealPix data. We may | |
| 473 | - * use only the first argument, and even carry a usage flag in | |
| 474 | - * GSkyPixel | |
| 475 | - ***************************************************************************/ | |
| 476 | -GSkyDir GHealpix::xy2dir(const GSkyPixel& pix) const | |
| 477 | -{ | |
| 478 | - // Set error message | |
| 479 | - std::string message = "Method not defined for HPX projection."; | |
| 480 | - | |
| 481 | - // Throw error | |
| 482 | - throw GException::wcs(G_XY2DIR, message); | |
| 483 | - | |
| 484 | - // Set dummy return value | |
| 485 | - GSkyDir result; | |
| 486 | - | |
| 487 | - // Return | |
| 488 | - return result; | |
| 489 | -} | |
| 490 | - | |
| 491 | - | |
| 492 | -/***********************************************************************//** | |
| 493 | - * @brief Returns pixel of sky direction | |
| 494 | - * | |
| 495 | - * @param[in] dir Sky direction. | |
| 496 | - * | |
| 497 | - * This dummy method throws an error when called as sky pixels are not | |
| 498 | - * implemented for a HealPix grid. Maybe we should implement them? | |
| 499 | - * | |
| 500 | - * @todo Think about implementation of sky pixel for HealPix data. We may | |
| 501 | - * use only the first argument, and even carry a usage flag in | |
| 502 | - * GSkyPixel | |
| 503 | - ***************************************************************************/ | |
| 504 | -GSkyPixel GHealpix::dir2xy(const GSkyDir& dir) const | |
| 505 | -{ | |
| 506 | - // Set error message | |
| 507 | - std::string message = "Method not defined for HPX projection."; | |
| 508 | - | |
| 509 | - // Throw error | |
| 510 | - throw GException::wcs(G_DIR2XY2, message); | |
| 511 | - | |
| 512 | - // Set dummy return value | |
| 513 | - GSkyPixel result; | |
| 514 | - | |
| 515 | - // Return | |
| 516 | - return result; | |
| 452 | + // Return sky map pixel | |
| 453 | + return (GSkyPixel(index)); | |
| 517 | 454 | } |
| 518 | 455 | |
| 519 | 456 | ... | ... |
src/sky/GSkymap.cpp
| ... | ... | @@ -46,13 +46,13 @@ |
| 46 | 46 | #define G_OP_ACCESS_1D "GSkymap::operator(int&, int&)" |
| 47 | 47 | #define G_OP_ACCESS_2D "GSkymap::operator(GSkyPixel&, int&)" |
| 48 | 48 | #define G_OP_VALUE "GSkymap::operator(GSkyDir&, int&)" |
| 49 | -#define G_READ "GSkymap::read(const GFitsHDU*)" | |
| 50 | -#define G_PIX2DIR "GSkymap::pix2dir(int&)" | |
| 49 | +#define G_INX2DIR "GSkymap::inx2dir(int&)" | |
| 50 | +#define G_PIX2DIR "GSkymap::pix2dir(GSkyPixel&)" | |
| 51 | +#define G_DIR2INX "GSkymap::dir2inx(GSkyDir&)" | |
| 51 | 52 | #define G_DIR2PIX "GSkymap::dir2pix(GSkyDir&)" |
| 52 | -#define G_XY2DIR "GSkymap::xy2dir(GSkyPixel&)" | |
| 53 | -#define G_DIR2XY "GSkymap::dir2xy(GSkyDir&)" | |
| 54 | 53 | #define G_OMEGA1 "GSkymap::omega(int&)" |
| 55 | 54 | #define G_OMEGA2 "GSkymap::omega(GSkyPixel&)" |
| 55 | +#define G_READ "GSkymap::read(const GFitsHDU*)" | |
| 56 | 56 | #define G_SET_WCS "GSkymap::set_wcs(std::string&, std::string&, double&,"\ |
| 57 | 57 | " double&, double&, double&, double&, double&,"\ |
| 58 | 58 | " GMatrix&, GVector&)" |
| ... | ... | @@ -260,72 +260,104 @@ GSkymap::~GSkymap(void) |
| 260 | 260 | ==========================================================================*/ |
| 261 | 261 | |
| 262 | 262 | /***********************************************************************//** |
| 263 | - * @brief 1D pixel access operator | |
| 263 | + * @brief Assignment operator | |
| 264 | + * | |
| 265 | + * @param[in] map Sky map. | |
| 266 | + * @return Sky map. | |
| 267 | + ***************************************************************************/ | |
| 268 | +GSkymap& GSkymap::operator=(const GSkymap& map) | |
| 269 | +{ | |
| 270 | + // Execute only if object is not identical | |
| 271 | + if (this != &map) { | |
| 272 | + | |
| 273 | + // Free members | |
| 274 | + free_members(); | |
| 275 | + | |
| 276 | + // Initialise private members for clean destruction | |
| 277 | + init_members(); | |
| 278 | + | |
| 279 | + // Copy members | |
| 280 | + copy_members(map); | |
| 281 | + | |
| 282 | + } // endif: object was not identical | |
| 283 | + | |
| 284 | + // Return this object | |
| 285 | + return *this; | |
| 286 | +} | |
| 287 | + | |
| 288 | + | |
| 289 | +/***********************************************************************//** | |
| 290 | + * @brief Pixel index access operator | |
| 264 | 291 | * |
| 265 | - * @param[in] pixel Pixel index (0,1,...,m_num_pixels). | |
| 266 | - * @param[in] map Map index (0,1,...,m_num_maps). | |
| 292 | + * @param[in] index Pixel index [0,...,npix()-1]. | |
| 293 | + * @param[in] map Map index [0,...,nmaps()-1]. | |
| 294 | + * @return Sky map pixel value. | |
| 267 | 295 | * |
| 268 | 296 | * @exception GException::out_of_range |
| 269 | 297 | * Pixel index and/or map index are outside valid range. |
| 270 | 298 | * |
| 271 | 299 | * Access sky map pixel by its index, where the most quickly varying axis is |
| 272 | 300 | * the x axis of the map. |
| 273 | - * | |
| 274 | - * @todo Implement proper skymap exception (actual is for matrix elements) | |
| 275 | 301 | ***************************************************************************/ |
| 276 | -double& GSkymap::operator() (const int& pixel, const int& map) | |
| 302 | +double& GSkymap::operator()(const int& index, const int& map) | |
| 277 | 303 | { |
| 278 | 304 | // Throw an error if pixel index or map index is not in valid range |
| 279 | 305 | #if defined(G_RANGE_CHECK) |
| 280 | - if (pixel < 0 || pixel >= m_num_pixels) { | |
| 281 | - throw GException::out_of_range(G_OP_ACCESS_1D, pixel, 0, m_num_pixels-1); | |
| 306 | + if (index < 0 || index >= m_num_pixels) { | |
| 307 | + throw GException::out_of_range(G_OP_ACCESS_1D, | |
| 308 | + "Sky map pixel index", | |
| 309 | + index, m_num_pixels); | |
| 282 | 310 | } |
| 283 | 311 | if (map < 0 || map >= m_num_maps) { |
| 284 | - throw GException::out_of_range(G_OP_ACCESS_1D, map, 0, m_num_maps-1); | |
| 312 | + throw GException::out_of_range(G_OP_ACCESS_1D, | |
| 313 | + "Sky map map index", | |
| 314 | + map, m_num_maps); | |
| 285 | 315 | } |
| 286 | 316 | #endif |
| 287 | 317 | |
| 288 | 318 | // Return reference to pixel value |
| 289 | - return m_pixels[pixel+m_num_pixels*map]; | |
| 319 | + return m_pixels[index+m_num_pixels*map]; | |
| 290 | 320 | } |
| 291 | 321 | |
| 292 | 322 | |
| 293 | 323 | /***********************************************************************//** |
| 294 | - * @brief 1D pixel access operator (const variant) | |
| 324 | + * @brief Pixel index access operator (const variant) | |
| 295 | 325 | * |
| 296 | - * @param[in] pixel Pixel index (0,1,...,m_num_pixels). | |
| 297 | - * @param[in] map Map index (0,1,...,m_num_maps). | |
| 326 | + * @param[in] index Pixel index [0,...,npix()-1]. | |
| 327 | + * @param[in] map Map index [0,...,nmaps()-1]. | |
| 298 | 328 | * |
| 299 | 329 | * @exception GException::out_of_range |
| 300 | 330 | * Pixel index and/or map index are outside valid range. |
| 301 | 331 | * |
| 302 | 332 | * Access sky map pixel by its index, where the most quickly varying axis is |
| 303 | 333 | * the x axis of the map. |
| 304 | - * | |
| 305 | - * @todo Implement proper skymap exception (actual is for matrix elements) | |
| 306 | 334 | ***************************************************************************/ |
| 307 | -const double& GSkymap::operator() (const int& pixel, const int& map) const | |
| 335 | +const double& GSkymap::operator()(const int& index, const int& map) const | |
| 308 | 336 | { |
| 309 | 337 | // Throw an error if pixel index or map index is not in valid range |
| 310 | 338 | #if defined(G_RANGE_CHECK) |
| 311 | - if (pixel < 0 || pixel >= m_num_pixels) { | |
| 312 | - throw GException::out_of_range(G_OP_ACCESS_1D, pixel, 0, m_num_pixels-1); | |
| 339 | + if (index < 0 || index >= m_num_pixels) { | |
| 340 | + throw GException::out_of_range(G_OP_ACCESS_1D, | |
| 341 | + "Sky map pixel index", | |
| 342 | + index, m_num_pixels); | |
| 313 | 343 | } |
| 314 | 344 | if (map < 0 || map >= m_num_maps) { |
| 315 | - throw GException::out_of_range(G_OP_ACCESS_1D, map, 0, m_num_maps-1); | |
| 345 | + throw GException::out_of_range(G_OP_ACCESS_1D, | |
| 346 | + "Sky map map index", | |
| 347 | + map, m_num_maps); | |
| 316 | 348 | } |
| 317 | 349 | #endif |
| 318 | 350 | |
| 319 | 351 | // Return reference to pixel value |
| 320 | - return m_pixels[pixel+m_num_pixels*map]; | |
| 352 | + return m_pixels[index+m_num_pixels*map]; | |
| 321 | 353 | } |
| 322 | 354 | |
| 323 | 355 | |
| 324 | 356 | /***********************************************************************//** |
| 325 | - * @brief 2D pixel access operator | |
| 357 | + * @brief Sky map pixel access operator | |
| 326 | 358 | * |
| 327 | - * @param[in] pixel Sky pixel. | |
| 328 | - * @param[in] map Map index (0,1,...,m_num_maps). | |
| 359 | + * @param[in] pixel Sky map pixel. | |
| 360 | + * @param[in] map Map index [0,...,nmaps()-1]. | |
| 329 | 361 | * |
| 330 | 362 | * @exception GException::out_of_range |
| 331 | 363 | * Sky pixel and/or map index are outside valid range. |
| ... | ... | @@ -335,7 +367,7 @@ const double& GSkymap::operator() (const int& pixel, const int& map) const |
| 335 | 367 | * |
| 336 | 368 | * @todo Implement proper skymap exception (actual is for matrix elements) |
| 337 | 369 | ***************************************************************************/ |
| 338 | -double& GSkymap::operator() (const GSkyPixel& pixel, const int& map) | |
| 370 | +double& GSkymap::operator()(const GSkyPixel& pixel, const int& map) | |
| 339 | 371 | { |
| 340 | 372 | // Throw an error if pixel index or map index is not in valid range |
| 341 | 373 | #if defined(G_RANGE_CHECK) |
| ... | ... | @@ -345,12 +377,14 @@ double& GSkymap::operator() (const GSkyPixel& pixel, const int& map) |
| 345 | 377 | m_num_x-1, m_num_y-1); |
| 346 | 378 | } |
| 347 | 379 | if (map < 0 || map >= m_num_maps) { |
| 348 | - throw GException::out_of_range(G_OP_ACCESS_2D, map, 0, m_num_maps-1); | |
| 380 | + throw GException::out_of_range(G_OP_ACCESS_2D, | |
| 381 | + "Sky map map index", | |
| 382 | + map, m_num_maps); | |
| 349 | 383 | } |
| 350 | 384 | #endif |
| 351 | 385 | |
| 352 | 386 | // Get pixel index |
| 353 | - int index = xy2pix(pixel); | |
| 387 | + int index = pix2inx(pixel); | |
| 354 | 388 | |
| 355 | 389 | // Return reference to pixel value |
| 356 | 390 | return m_pixels[index+m_num_pixels*map]; |
| ... | ... | @@ -358,10 +392,10 @@ double& GSkymap::operator() (const GSkyPixel& pixel, const int& map) |
| 358 | 392 | |
| 359 | 393 | |
| 360 | 394 | /***********************************************************************//** |
| 361 | - * @brief 2D pixel access operator | |
| 395 | + * @brief Sky map pixel access operator | |
| 362 | 396 | * |
| 363 | - * @param[in] pixel Sky pixel. | |
| 364 | - * @param[in] map Map index (0,1,...,m_num_maps). | |
| 397 | + * @param[in] pixel Sky map pixel. | |
| 398 | + * @param[in] map Map index [0,...,nmaps()-1]. | |
| 365 | 399 | * |
| 366 | 400 | * @exception GException::out_of_range |
| 367 | 401 | * Sky pixel and/or map index are outside valid range. |
| ... | ... | @@ -381,12 +415,14 @@ const double& GSkymap::operator()(const GSkyPixel& pixel, const int& map) const |
| 381 | 415 | m_num_x-1, m_num_y-1); |
| 382 | 416 | } |
| 383 | 417 | if (map < 0 || map >= m_num_maps) { |
| 384 | - throw GException::out_of_range(G_OP_ACCESS_2D, map, 0, m_num_maps-1); | |
| 418 | + throw GException::out_of_range(G_OP_ACCESS_2D, | |
| 419 | + "Sky map map index", | |
| 420 | + map, m_num_maps); | |
| 385 | 421 | } |
| 386 | 422 | #endif |
| 387 | 423 | |
| 388 | 424 | // Get pixel index |
| 389 | - int index = xy2pix(pixel); | |
| 425 | + int index = pix2inx(pixel); | |
| 390 | 426 | |
| 391 | 427 | // Return reference to pixel value |
| 392 | 428 | return m_pixels[index+m_num_pixels*map]; |
| ... | ... | @@ -397,7 +433,7 @@ const double& GSkymap::operator()(const GSkyPixel& pixel, const int& map) const |
| 397 | 433 | * @brief Return interpolated skymap value for sky direction |
| 398 | 434 | * |
| 399 | 435 | * @param[in] dir Sky direction. |
| 400 | - * @param[in] map Map index (0,1,...,m_num_maps). | |
| 436 | + * @param[in] map Map index [0,...,nmaps()-1]. | |
| 401 | 437 | * |
| 402 | 438 | * @exception GException::out_of_range |
| 403 | 439 | * Map index lies outside valid range. |
| ... | ... | @@ -406,12 +442,14 @@ const double& GSkymap::operator()(const GSkyPixel& pixel, const int& map) const |
| 406 | 442 | * interpolation of the neighbouring pixels. If the sky direction falls |
| 407 | 443 | * outside the area covered by the skymap, a value of 0 is returned. |
| 408 | 444 | ***************************************************************************/ |
| 409 | -double GSkymap::operator() (const GSkyDir& dir, const int& map) const | |
| 445 | +double GSkymap::operator()(const GSkyDir& dir, const int& map) const | |
| 410 | 446 | { |
| 411 | 447 | // Throw an error if the map index is not in valid range |
| 412 | 448 | #if defined(G_RANGE_CHECK) |
| 413 | 449 | if (map < 0 || map >= m_num_maps) { |
| 414 | - throw GException::out_of_range(G_OP_VALUE, map, 0, m_num_maps-1); | |
| 450 | + throw GException::out_of_range(G_OP_VALUE, | |
| 451 | + "Sky map map index", | |
| 452 | + map, m_num_maps); | |
| 415 | 453 | } |
| 416 | 454 | #endif |
| 417 | 455 | |
| ... | ... | @@ -419,7 +457,7 @@ double GSkymap::operator() (const GSkyDir& dir, const int& map) const |
| 419 | 457 | double intensity = 0.0; |
| 420 | 458 | |
| 421 | 459 | // Determine sky pixel |
| 422 | - GSkyPixel pixel = dir2xy(dir); | |
| 460 | + GSkyPixel pixel = dir2pix(dir); | |
| 423 | 461 | |
| 424 | 462 | // Continue only if pixel is within the map |
| 425 | 463 | if (contains(pixel)) { |
| ... | ... | @@ -476,32 +514,6 @@ double GSkymap::operator() (const GSkyDir& dir, const int& map) const |
| 476 | 514 | } |
| 477 | 515 | |
| 478 | 516 | |
| 479 | -/***********************************************************************//** | |
| 480 | - * @brief Assignment operator | |
| 481 | - * | |
| 482 | - * @param[in] map Sky map. | |
| 483 | - ***************************************************************************/ | |
| 484 | -GSkymap& GSkymap::operator= (const GSkymap& map) | |
| 485 | -{ | |
| 486 | - // Execute only if object is not identical | |
| 487 | - if (this != &map) { | |
| 488 | - | |
| 489 | - // Free members | |
| 490 | - free_members(); | |
| 491 | - | |
| 492 | - // Initialise private members for clean destruction | |
| 493 | - init_members(); | |
| 494 | - | |
| 495 | - // Copy members | |
| 496 | - copy_members(map); | |
| 497 | - | |
| 498 | - } // endif: object was not identical | |
| 499 | - | |
| 500 | - // Return this object | |
| 501 | - return *this; | |
| 502 | -} | |
| 503 | - | |
| 504 | - | |
| 505 | 517 | /*========================================================================== |
| 506 | 518 | = = |
| 507 | 519 | = Public methods = |
| ... | ... | @@ -511,7 +523,7 @@ GSkymap& GSkymap::operator= (const GSkymap& map) |
| 511 | 523 | /***********************************************************************//** |
| 512 | 524 | * @brief Clear instance. |
| 513 | 525 | * |
| 514 | - * This method properly resets the object to an initial state. | |
| 526 | + * Resets the sky map to the initial state. | |
| 515 | 527 | ***************************************************************************/ |
| 516 | 528 | void GSkymap::clear(void) |
| 517 | 529 | { |
| ... | ... | @@ -527,7 +539,9 @@ void GSkymap::clear(void) |
| 527 | 539 | |
| 528 | 540 | |
| 529 | 541 | /***********************************************************************//** |
| 530 | - * @brief Clone instance | |
| 542 | + * @brief Clone sky map | |
| 543 | + * | |
| 544 | + * @return Pointer to deep copy of sky map. | |
| 531 | 545 | ***************************************************************************/ |
| 532 | 546 | GSkymap* GSkymap::clone(void) const |
| 533 | 547 | { |
| ... | ... | @@ -535,6 +549,368 @@ GSkymap* GSkymap::clone(void) const |
| 535 | 549 | } |
| 536 | 550 | |
| 537 | 551 | |
| 552 | +/***********************************************************************//** | |
| 553 | + * @brief Converts pixel index into sky map pixel | |
| 554 | + * | |
| 555 | + * @param[in] index Pixel index [0,...,npix()-1]. | |
| 556 | + * @return Sky map pixel. | |
| 557 | + * | |
| 558 | + * Converts the pixel @p index into a sky map pixel (GSkyPixel).The dimension | |
| 559 | + * of GSkyPixel will be identical to the dimension of the sky map (i.e. a 1D | |
| 560 | + * sky map leads to a 1D GSkyPixel object, a 2D sky map leads to a 2D | |
| 561 | + * GSkyPixel object. | |
| 562 | + ***************************************************************************/ | |
| 563 | +GSkyPixel GSkymap::inx2pix(const int& index) const | |
| 564 | +{ | |
| 565 | + // Initialise sky map pixel | |
| 566 | + GSkyPixel pixel; | |
| 567 | + | |
| 568 | + // Get x and y indices | |
| 569 | + double x; | |
| 570 | + double y; | |
| 571 | + if (m_num_x != 0) { //!< 2D sky map | |
| 572 | + pixel.x(double(index % m_num_x)); | |
| 573 | + pixel.y(double(index / m_num_x)); | |
| 574 | + } | |
| 575 | + else { //!< 1D sky map | |
| 576 | + pixel.index(index); | |
| 577 | + } | |
| 578 | + | |
| 579 | + // Return pixel | |
| 580 | + return pixel; | |
| 581 | +} | |
| 582 | + | |
| 583 | + | |
| 584 | +/***********************************************************************//** | |
| 585 | + * @brief Returns sky direction of pixel | |
| 586 | + * | |
| 587 | + * @param[in] index Pixel index [0,...,npix()-1]. | |
| 588 | + * @return Sky direction. | |
| 589 | + * | |
| 590 | + * @exception GException::invalid_value | |
| 591 | + * No valid sky projection found. | |
| 592 | + * | |
| 593 | + * Returns sky direction for a given pixel index. | |
| 594 | + ***************************************************************************/ | |
| 595 | +GSkyDir GSkymap::inx2dir(const int& index) const | |
| 596 | +{ | |
| 597 | + // Throw error if sky projection is not valid | |
| 598 | + if (m_proj == NULL) { | |
| 599 | + std::string msg = "Sky projection has not been defined."; | |
| 600 | + throw GException::invalid_value(G_INX2DIR, msg); | |
| 601 | + } | |
| 602 | + | |
| 603 | + // Determine sky direction from pixel index. | |
| 604 | + GSkyDir dir = m_proj->pix2dir(inx2pix(index)); | |
| 605 | + | |
| 606 | + // Return sky direction | |
| 607 | + return dir; | |
| 608 | +} | |
| 609 | + | |
| 610 | + | |
| 611 | +/***********************************************************************//** | |
| 612 | + * @brief Returns sky direction of pixel | |
| 613 | + * | |
| 614 | + * @param[in] pixel Sky map pixel. | |
| 615 | + * @return Sky direction. | |
| 616 | + * | |
| 617 | + * @exception GException::invalid_value | |
| 618 | + * No valid sky projection found. | |
| 619 | + * @exception GException::invalid_argument | |
| 620 | + * 2D sky map pixel used to access 1D projection. | |
| 621 | + * | |
| 622 | + * Returns sky direction for a given sky map @p pixel. | |
| 623 | + ***************************************************************************/ | |
| 624 | +GSkyDir GSkymap::pix2dir(const GSkyPixel& pixel) const | |
| 625 | +{ | |
| 626 | + // Throw error if WCS is not valid | |
| 627 | + if (m_proj == NULL) { | |
| 628 | + std::string msg = "Sky projection has not been defined."; | |
| 629 | + throw GException::invalid_value(G_PIX2DIR, msg); | |
| 630 | + } | |
| 631 | + | |
| 632 | + // Initialise sky direction | |
| 633 | + GSkyDir dir; | |
| 634 | + | |
| 635 | + // If pixel size matches the projection size then perform a straight | |
| 636 | + // forward conversion | |
| 637 | + if (m_proj->size() == pixel.size()) { | |
| 638 | + dir = m_proj->pix2dir(pixel); | |
| 639 | + } | |
| 640 | + | |
| 641 | + // ... otherwise, if we have a 2D projection but a 1D pixel then | |
| 642 | + // interpret the pixel as the linear index in the pixel array | |
| 643 | + else if (m_proj->size() == 2) { | |
| 644 | + dir = m_proj->pix2dir(GSkyPixel(inx2pix(int(pixel)))); | |
| 645 | + } | |
| 646 | + | |
| 647 | + // ... otherwise we have a 1D projection but a 2D pixel. There is | |
| 648 | + // no unambiguous way to handle this case, hence we throw an exception | |
| 649 | + else { | |
| 650 | + std::string msg = "A 2-dimensional sky map pixel "+pixel.print()+ | |
| 651 | + " is used to determine the sky direction for" | |
| 652 | + " the 1-dimensional sky projection \""+ | |
| 653 | + m_proj->name()+"\"\n" | |
| 654 | + "Please specify a 1-dimensional sky map pixel."; | |
| 655 | + throw GException::invalid_argument(G_PIX2DIR, msg); | |
| 656 | + } | |
| 657 | + | |
| 658 | + // Return sky direction | |
| 659 | + return dir; | |
| 660 | +} | |
| 661 | + | |
| 662 | + | |
| 663 | +/***********************************************************************//** | |
| 664 | + * @brief Converts sky map pixel into pixel index | |
| 665 | + * | |
| 666 | + * @param[in] pixel Sky map pixel. | |
| 667 | + * @return Pixel index [0,...,npix()-1]. | |
| 668 | + * | |
| 669 | + * Converts a sky map @p pixel into the pixel index. | |
| 670 | + ***************************************************************************/ | |
| 671 | +int GSkymap::pix2inx(const GSkyPixel& pixel) const | |
| 672 | +{ | |
| 673 | + // Initialise pixel index | |
| 674 | + int index = 0; | |
| 675 | + | |
| 676 | + // Handle 1D sky map pixel | |
| 677 | + if (pixel.is1D()) { | |
| 678 | + index = int(pixel); | |
| 679 | + } | |
| 680 | + | |
| 681 | + // Handle 2D sky map pixel | |
| 682 | + else if (pixel.is2D()) { | |
| 683 | + | |
| 684 | + // Get x and y indices by rounding the (x,y) values | |
| 685 | + int ix = int(pixel.x()+0.5); | |
| 686 | + int iy = int(pixel.y()+0.5); | |
| 687 | + | |
| 688 | + // Set index | |
| 689 | + index = ix + iy * m_num_x; | |
| 690 | + | |
| 691 | + } | |
| 692 | + | |
| 693 | + // Return index | |
| 694 | + return index; | |
| 695 | +} | |
| 696 | + | |
| 697 | + | |
| 698 | +/***********************************************************************//** | |
| 699 | + * @brief Returns pixel index for a given sky direction | |
| 700 | + * | |
| 701 | + * @param[in] dir Sky direction. | |
| 702 | + * @return Pixel index [0,...,npix()-1]. | |
| 703 | + * | |
| 704 | + * @exception GException::invalid_value | |
| 705 | + * No valid sky projection found. | |
| 706 | + * | |
| 707 | + * Returns sky map pixel index for a given sky direction. | |
| 708 | + ***************************************************************************/ | |
| 709 | +int GSkymap::dir2inx(const GSkyDir& dir) const | |
| 710 | +{ | |
| 711 | + // Throw error if WCS is not valid | |
| 712 | + if (m_proj == NULL) { | |
| 713 | + std::string msg = "Sky projection has not been defined."; | |
| 714 | + throw GException::invalid_value(G_DIR2INX, msg); | |
| 715 | + } | |
| 716 | + | |
| 717 | + // Determine pixel index for a given sky direction | |
| 718 | + int index = pix2inx(m_proj->dir2pix(dir)); | |
| 719 | + | |
| 720 | + // Return pixel index | |
| 721 | + return index; | |
| 722 | +} | |
| 723 | + | |
| 724 | + | |
| 725 | +/***********************************************************************//** | |
| 726 | + * @brief Returns sky map pixel for a given sky direction | |
| 727 | + * | |
| 728 | + * @param[in] dir Sky direction. | |
| 729 | + * @return Sky map pixel. | |
| 730 | + * | |
| 731 | + * @exception GException::invalid_value | |
| 732 | + * No valid sky projection found. | |
| 733 | + * | |
| 734 | + * Returns sky map pixel for a given sky direction. | |
| 735 | + ***************************************************************************/ | |
| 736 | +GSkyPixel GSkymap::dir2pix(const GSkyDir& dir) const | |
| 737 | +{ | |
| 738 | + // Throw error if WCS is not valid | |
| 739 | + if (m_proj == NULL) { | |
| 740 | + std::string msg = "Sky projection has not been defined."; | |
| 741 | + throw GException::invalid_value(G_DIR2PIX, msg); | |
| 742 | + } | |
| 743 | + | |
| 744 | + // Determine pixel for a given sky direction | |
| 745 | + GSkyPixel pixel = m_proj->dir2pix(dir); | |
| 746 | + | |
| 747 | + // Return pixel | |
| 748 | + return pixel; | |
| 749 | +} | |
| 750 | + | |
| 751 | + | |
| 752 | +/***********************************************************************//** | |
| 753 | + * @brief Returns solid angle of pixel | |
| 754 | + * | |
| 755 | + * @param[in] index Pixel index [0,...,npix()-1]. | |
| 756 | + * @return Solid angle (steradians) | |
| 757 | + * | |
| 758 | + * @exception GException::invalid_value | |
| 759 | + * No valid sky projection found. | |
| 760 | + * | |
| 761 | + * Returns the solid angle of the pixel with the specified @p index. | |
| 762 | + ***************************************************************************/ | |
| 763 | +double GSkymap::omega(const int& index) const | |
| 764 | +{ | |
| 765 | + // Throw error if WCS is not valid | |
| 766 | + if (m_proj == NULL) { | |
| 767 | + std::string msg = "Sky projection has not been defined."; | |
| 768 | + throw GException::invalid_value(G_OMEGA1, msg); | |
| 769 | + } | |
| 770 | + | |
| 771 | + // Determine solid angle from pixel index. | |
| 772 | + double omega = m_proj->omega(inx2pix(index)); | |
| 773 | + | |
| 774 | + // Return solid angle | |
| 775 | + return omega; | |
| 776 | +} | |
| 777 | + | |
| 778 | + | |
| 779 | +/***********************************************************************//** | |
| 780 | + * @brief Returns solid angle of pixel | |
| 781 | + * | |
| 782 | + * @param[in] pixel Sky map pixel. | |
| 783 | + * @return Solid angle (steradians) | |
| 784 | + * | |
| 785 | + * @exception GException::invalid_value | |
| 786 | + * No valid sky projection found. | |
| 787 | + * | |
| 788 | + * Returns the solid angle of the specified sky map @p pixel. | |
| 789 | + ***************************************************************************/ | |
| 790 | +double GSkymap::omega(const GSkyPixel& pixel) const | |
| 791 | +{ | |
| 792 | + // Throw error if WCS is not valid | |
| 793 | + if (m_proj == NULL) { | |
| 794 | + std::string msg = "Sky projection has not been defined."; | |
| 795 | + throw GException::invalid_value(G_OMEGA2, msg); | |
| 796 | + } | |
| 797 | + | |
| 798 | + // Initialise solid angle | |
| 799 | + double omega = 0.0; | |
| 800 | + | |
| 801 | + // If pixel size matches the projection size then perform a straight | |
| 802 | + // forward solid angle determination | |
| 803 | + if (m_proj->size() == pixel.size()) { | |
| 804 | + omega = m_proj->omega(pixel); | |
| 805 | + } | |
| 806 | + | |
| 807 | + // ... otherwise, if we have a 2D projection but a 1D pixel then | |
| 808 | + // interpret the pixel as the linear index in the pixel array | |
| 809 | + else if (m_proj->size() == 2) { | |
| 810 | + omega = m_proj->omega(GSkyPixel(inx2pix(int(pixel)))); | |
| 811 | + } | |
| 812 | + | |
| 813 | + // ... otherwise we have a 1D projection but a 2D pixel. There is | |
| 814 | + // no unambiguous way to handle this case, hence we throw an exception | |
| 815 | + else { | |
| 816 | + std::string msg = "A 2-dimensional sky map pixel "+pixel.print()+ | |
| 817 | + " is used to determine the solid angle for" | |
| 818 | + " the 1-dimensional sky projection \""+ | |
| 819 | + m_proj->name()+"\"\n" | |
| 820 | + "Please specify a 1-dimensional sky map pixel."; | |
| 821 | + throw GException::invalid_argument(G_OMEGA2, msg); | |
| 822 | + } | |
| 823 | + | |
| 824 | + // Return solid angle | |
| 825 | + return omega; | |
| 826 | +} | |
| 827 | + | |
| 828 | + | |
| 829 | +/***********************************************************************//** | |
| 830 | + * @brief Set sky projection | |
| 831 | + * | |
| 832 | + * @param[in] proj Sky projection. | |
| 833 | + * | |
| 834 | + * Sets the projection from celestial to pixel coordinates. The method | |
| 835 | + * performs a deep copy of @p proj, allowing to destroy the argument after | |
| 836 | + * using the method. | |
| 837 | + * | |
| 838 | + * Warning: this method may corrupt the GSkymap object as it allows assigning | |
| 839 | + * for example a 1D projection to a 2D skymap. Please use this method only | |
| 840 | + * when you know what you're doing. | |
| 841 | + * | |
| 842 | + * @todo We may restrict this method to not allow changing the projection | |
| 843 | + * dimension. | |
| 844 | + ***************************************************************************/ | |
| 845 | +void GSkymap::projection(const GSkyProjection& proj) | |
| 846 | +{ | |
| 847 | + // Free any existing WCS | |
| 848 | + if (m_proj != NULL) delete m_proj; | |
| 849 | + | |
| 850 | + // Clone input WCS | |
| 851 | + m_proj = proj.clone(); | |
| 852 | + | |
| 853 | + // Return | |
| 854 | + return; | |
| 855 | +} | |
| 856 | + | |
| 857 | + | |
| 858 | +/***********************************************************************//** | |
| 859 | + * @brief Verifies if sky direction falls in map | |
| 860 | + * | |
| 861 | + * @param[in] dir Sky direction. | |
| 862 | + * | |
| 863 | + * This method checks if the specified sky direction falls within the pixels | |
| 864 | + * covered by the skymap. The method uses the dir2xy method to convert the | |
| 865 | + * sky direction into 2D pixel indices, and then checks whether the pixel | |
| 866 | + * indices fall in the skymap. | |
| 867 | + ***************************************************************************/ | |
| 868 | +bool GSkymap::contains(const GSkyDir& dir) const | |
| 869 | +{ | |
| 870 | + // Convert sky direction into sky pixel | |
| 871 | + GSkyPixel pixel = dir2pix(dir); | |
| 872 | + | |
| 873 | + // Return location flag | |
| 874 | + return (contains(pixel)); | |
| 875 | +} | |
| 876 | + | |
| 877 | + | |
| 878 | +/***********************************************************************//** | |
| 879 | + * @brief Checks if sky map pixel falls in map | |
| 880 | + * | |
| 881 | + * @param[in] pixel Sky map pixel. | |
| 882 | + * @return Trus if pixels is within map, false otherwise. | |
| 883 | + * | |
| 884 | + * Checks whether the specified sky map @p pixel falls within the skymap | |
| 885 | + * or not. | |
| 886 | + ***************************************************************************/ | |
| 887 | +bool GSkymap::contains(const GSkyPixel& pixel) const | |
| 888 | +{ | |
| 889 | + // Initialise containment flag | |
| 890 | + bool inmap = false; | |
| 891 | + | |
| 892 | + // Test 1D pixels | |
| 893 | + if (pixel.is1D()) { | |
| 894 | + if (pixel.index()+0.5 >= 0.0 && pixel.index()-0.5 < m_num_pixels) { | |
| 895 | + inmap = true; | |
| 896 | + } | |
| 897 | + } | |
| 898 | + | |
| 899 | + // Test 2D pixels | |
| 900 | + else if (pixel.is2D()) { | |
| 901 | + | |
| 902 | + // If pixel is in range then set containment flag to true | |
| 903 | + if ((pixel.x()+0.5 >= 0.0 && pixel.x()-0.5 < m_num_x) && | |
| 904 | + (pixel.y()+0.5 >= 0.0 && pixel.y()-0.5 < m_num_y)) { | |
| 905 | + inmap = true; | |
| 906 | + } | |
| 907 | + | |
| 908 | + } | |
| 909 | + | |
| 910 | + // Return containment flag | |
| 911 | + return inmap; | |
| 912 | +} | |
| 913 | + | |
| 538 | 914 | |
| 539 | 915 | /***********************************************************************//** |
| 540 | 916 | * @brief Load skymap from FITS file. |
| ... | ... | @@ -544,6 +920,9 @@ GSkymap* GSkymap::clone(void) const |
| 544 | 920 | * Loads HEALPix and non HEALPix skymaps. First searches for HEALPix map in |
| 545 | 921 | * FITS file by scanning all HDUs for PIXTYPE=HEALPIX. If no HEALPix map has |
| 546 | 922 | * been found then search load first non-empty image. |
| 923 | + * | |
| 924 | + * @todo Do we have to restrict a HEALPix map to a BinTable and a WCS map | |
| 925 | + * to a Double precision image??? | |
| 547 | 926 | ***************************************************************************/ |
| 548 | 927 | void GSkymap::load(const std::string& filename) |
| 549 | 928 | { |
| ... | ... | @@ -568,16 +947,12 @@ void GSkymap::load(const std::string& filename) |
| 568 | 947 | |
| 569 | 948 | // Get pointer to HDU |
| 570 | 949 | hdu = fits.hdu(extno); |
| 571 | - | |
| 950 | + | |
| 572 | 951 | // If PIXTYPE keyword equals "HEALPIX" then load map |
| 573 | - try { | |
| 574 | - if (hdu->string("PIXTYPE") == "HEALPIX") { | |
| 575 | - read_healpix(static_cast<const GFitsBinTable*>(hdu)); | |
| 576 | - loaded = true; | |
| 577 | - break; | |
| 578 | - } | |
| 579 | - } | |
| 580 | - catch (GException::fits_key_not_found &e) { | |
| 952 | + if (hdu->hascard("PIXTYPE") && hdu->string("PIXTYPE") == "HEALPIX") { | |
| 953 | + read_healpix(static_cast<const GFitsTable*>(hdu)); | |
| 954 | + loaded = true; | |
| 955 | + break; | |
| 581 | 956 | } |
| 582 | 957 | |
| 583 | 958 | } // endfor: looped over HDUs |
| ... | ... | @@ -597,7 +972,7 @@ void GSkymap::load(const std::string& filename) |
| 597 | 972 | } |
| 598 | 973 | |
| 599 | 974 | // Load WCS map |
| 600 | - read_wcs(static_cast<const GFitsImageDouble*>(hdu)); | |
| 975 | + read_wcs(static_cast<const GFitsImage*>(hdu)); | |
| 601 | 976 | loaded = true; |
| 602 | 977 | break; |
| 603 | 978 | |
| ... | ... | @@ -674,14 +1049,10 @@ void GSkymap::read(const GFitsHDU* hdu) |
| 674 | 1049 | // Initialize load flag |
| 675 | 1050 | bool loaded = false; |
| 676 | 1051 | |
| 677 | - // Try load as HEALPix map | |
| 678 | - try { | |
| 679 | - if (hdu->string("PIXTYPE") == "HEALPIX") { | |
| 680 | - read_healpix(static_cast<const GFitsBinTable*>(hdu)); | |
| 681 | - loaded = true; | |
| 682 | - } | |
| 683 | - } | |
| 684 | - catch (GException::fits_key_not_found &e) { | |
| 1052 | + // If PIXTYPE keyword equals "HEALPIX" then load map | |
| 1053 | + if (hdu->hascard("PIXTYPE") && hdu->string("PIXTYPE") == "HEALPIX") { | |
| 1054 | + read_healpix(static_cast<const GFitsTable*>(hdu)); | |
| 1055 | + loaded = true; | |
| 685 | 1056 | } |
| 686 | 1057 | |
| 687 | 1058 | // ... otherwise try loading as non HEALPix map |
| ... | ... | @@ -689,7 +1060,7 @@ void GSkymap::read(const GFitsHDU* hdu) |
| 689 | 1060 | |
| 690 | 1061 | // Load only if HDU contains an image |
| 691 | 1062 | if (hdu->exttype() == 0) { |
| 692 | - read_wcs(static_cast<const GFitsImageDouble*>(hdu)); | |
| 1063 | + read_wcs(static_cast<const GFitsImage*>(hdu)); | |
| 693 | 1064 | loaded = true; |
| 694 | 1065 | } |
| 695 | 1066 | |
| ... | ... | @@ -741,332 +1112,6 @@ void GSkymap::write(GFits* file) const |
| 741 | 1112 | |
| 742 | 1113 | |
| 743 | 1114 | /***********************************************************************//** |
| 744 | - * @brief Returns sky direction of pixel | |
| 745 | - * | |
| 746 | - * @param[in] pix Pixel number (0,1,...,m_num_pixels). | |
| 747 | - * | |
| 748 | - * @exception GException::wcs | |
| 749 | - * No valid WCS found. | |
| 750 | - * | |
| 751 | - * Returns sky direction for a given sky map pixel. This methods works for | |
| 752 | - * sky maps that have a 1D (e.g. HEALPix) or 2D pixel indexation scheme. | |
| 753 | - * Automatic index conversion is provided so that 1D schemes need only to | |
| 754 | - * implement 1D conversion methods while 2D schemes need only to implement | |
| 755 | - * 2D conversion methods. | |
| 756 | - ***************************************************************************/ | |
| 757 | -GSkyDir GSkymap::pix2dir(const int& pix) const | |
| 758 | -{ | |
| 759 | - // Throw error if sky projection is not valid | |
| 760 | - if (m_proj == NULL) { | |
| 761 | - throw GException::wcs(G_PIX2DIR, "No valid sky projection found."); | |
| 762 | - } | |
| 763 | - | |
| 764 | - // Determine sky direction from pixel. Use 2D version if sky map is | |
| 765 | - // 2D, otherwise use 1D version. | |
| 766 | - GSkyDir dir = (m_num_x == 0) ? m_proj->pix2dir(pix) | |
| 767 | - : m_proj->xy2dir(pix2xy(pix)); | |
| 768 | - | |
| 769 | - // Return sky direction | |
| 770 | - return dir; | |
| 771 | -} | |
| 772 | - | |
| 773 | - | |
| 774 | -/***********************************************************************//** | |
| 775 | - * @brief Returns pixel index for a given sky direction | |
| 776 | - * | |
| 777 | - * @param[in] dir Sky direction. | |
| 778 | - * | |
| 779 | - * @exception GException::wcs | |
| 780 | - * No valid WCS found. | |
| 781 | - * | |
| 782 | - * Returns sky map pixel for a given sky direction. This methods works for | |
| 783 | - * sky maps that have a 1D (e.g. HEALPix) or 2D pixel indexation scheme. | |
| 784 | - * Automatic index conversion is provided so that 1D schemes need only to | |
| 785 | - * implement 1D conversion methods while 2D schemes need only to implement | |
| 786 | - * 2D conversion methods. | |
| 787 | - ***************************************************************************/ | |
| 788 | -int GSkymap::dir2pix(const GSkyDir& dir) const | |
| 789 | -{ | |
| 790 | - // Throw error if WCS is not valid | |
| 791 | - if (m_proj == NULL) { | |
| 792 | - throw GException::wcs(G_DIR2PIX, "No valid sky projection found."); | |
| 793 | - } | |
| 794 | - | |
| 795 | - // Determine 1D pixel index for a given sky direction | |
| 796 | - int pix = (m_num_x == 0) ? m_proj->dir2pix(dir) | |
| 797 | - : xy2pix(m_proj->dir2xy(dir)); | |
| 798 | - | |
| 799 | - // Return pixel index | |
| 800 | - return pix; | |
| 801 | -} | |
| 802 | - | |
| 803 | - | |
| 804 | -/***********************************************************************//** | |
| 805 | - * @brief Returns sky direction of pixel | |
| 806 | - * | |
| 807 | - * @param[in] pix Sky map pixel. | |
| 808 | - * | |
| 809 | - * @exception GException::wcs | |
| 810 | - * No valid WCS found. | |
| 811 | - * | |
| 812 | - * Returns sky direction for a given sky map pixel. This methods works for | |
| 813 | - * sky maps that have a 1D (e.g. HEALPix) or 2D pixel indexation scheme. | |
| 814 | - * Automatic index conversion is provided so that 1D schemes need only to | |
| 815 | - * implement 1D conversion methods while 2D schemes need only to implement | |
| 816 | - * 2D conversion methods. | |
| 817 | - ***************************************************************************/ | |
| 818 | -GSkyDir GSkymap::xy2dir(const GSkyPixel& pix) const | |
| 819 | -{ | |
| 820 | - // Throw error if WCS is not valid | |
| 821 | - if (m_proj == NULL) { | |
| 822 | - throw GException::wcs(G_XY2DIR, "No valid sky projection found."); | |
| 823 | - } | |
| 824 | - | |
| 825 | - // Determine sky direction from pixel. Use 2D version if sky map is | |
| 826 | - // 2D, otherwise use 1D version. | |
| 827 | - GSkyDir dir = (m_num_x == 0) ? m_proj->pix2dir(xy2pix(pix)) | |
| 828 | - : m_proj->xy2dir(pix); | |
| 829 | - | |
| 830 | - // Return sky direction | |
| 831 | - return dir; | |
| 832 | -} | |
| 833 | - | |
| 834 | - | |
| 835 | -/***********************************************************************//** | |
| 836 | - * @brief Returns sky map pixel for a given sky direction | |
| 837 | - * | |
| 838 | - * @param[in] dir Sky direction. | |
| 839 | - * | |
| 840 | - * @exception GException::wcs | |
| 841 | - * No valid WCS found. | |
| 842 | - * | |
| 843 | - * Returns sky map pixel for a given sky direction. This methods works for | |
| 844 | - * sky maps that have a 1D (e.g. HEALPix) or 2D pixel indexation scheme. | |
| 845 | - * Automatic index conversion is provided so that 1D schemes need only to | |
| 846 | - * implement 1D conversion methods while 2D schemes need only to implement | |
| 847 | - * 2D conversion methods. | |
| 848 | - ***************************************************************************/ | |
| 849 | -GSkyPixel GSkymap::dir2xy(const GSkyDir& dir) const | |
| 850 | -{ | |
| 851 | - // Throw error if WCS is not valid | |
| 852 | - if (m_proj == NULL) { | |
| 853 | - throw GException::wcs(G_DIR2XY, "No valid sky projection found."); | |
| 854 | - } | |
| 855 | - | |
| 856 | - // Determine 1D pixel index for a given sky direction | |
| 857 | - GSkyPixel pix = (m_num_x == 0) ? pix2xy(m_proj->dir2pix(dir)) | |
| 858 | - : m_proj->dir2xy(dir); | |
| 859 | - | |
| 860 | - // Return pixel index | |
| 861 | - return pix; | |
| 862 | -} | |
| 863 | - | |
| 864 | - | |
| 865 | -/***********************************************************************//** | |
| 866 | - * @brief Returns solid angle of pixel | |
| 867 | - * | |
| 868 | - * @param[in] pix Pixel number (0,1,...,m_num_pixels). | |
| 869 | - * | |
| 870 | - * @exception GException::wcs | |
| 871 | - * No valid WCS found. | |
| 872 | - ***************************************************************************/ | |
| 873 | -double GSkymap::omega(const int& pix) const | |
| 874 | -{ | |
| 875 | - // Throw error if WCS is not valid | |
| 876 | - if (m_proj == NULL) { | |
| 877 | - throw GException::wcs(G_OMEGA1, "No valid sky projection found."); | |
| 878 | - } | |
| 879 | - | |
| 880 | - // Determine solid angle from pixel. Use 2D version if sky map is | |
| 881 | - // 2D, otherwise use 1D version. | |
| 882 | - double omega = (m_num_x == 0) ? m_proj->omega(pix) | |
| 883 | - : m_proj->omega(pix2xy(pix)); | |
| 884 | - | |
| 885 | - // Return solid angle | |
| 886 | - return omega; | |
| 887 | -} | |
| 888 | - | |
| 889 | - | |
| 890 | -/***********************************************************************//** | |
| 891 | - * @brief Returns solid angle of pixel | |
| 892 | - * | |
| 893 | - * @param[in] pix Sky map pixel. | |
| 894 | - * | |
| 895 | - * @exception GException::wcs | |
| 896 | - * No valid WCS found. | |
| 897 | - ***************************************************************************/ | |
| 898 | -double GSkymap::omega(const GSkyPixel& pix) const | |
| 899 | -{ | |
| 900 | - // Throw error if WCS is not valid | |
| 901 | - if (m_proj == NULL) { | |
| 902 | - throw GException::wcs(G_OMEGA2, "No valid sky projection found."); | |
| 903 | - } | |
| 904 | - | |
| 905 | - // Determine solid angle from pixel. Use 2D version if sky map is | |
| 906 | - // 2D, otherwise use 1D version. | |
| 907 | - double omega = (m_num_x == 0) ? m_proj->omega(xy2pix(pix)) | |
| 908 | - : m_proj->omega(pix); | |
| 909 | - | |
| 910 | - // Return solid angle | |
| 911 | - return omega; | |
| 912 | -} | |
| 913 | - | |
| 914 | - | |
| 915 | -/***********************************************************************//** | |
| 916 | - * @brief Returns number of pixels | |
| 917 | - ***************************************************************************/ | |
| 918 | -int GSkymap::npix(void) const | |
| 919 | -{ | |
| 920 | - // Return number of pixels | |
| 921 | - return m_num_pixels; | |
| 922 | -} | |
| 923 | - | |
| 924 | - | |
| 925 | -/***********************************************************************//** | |
| 926 | - * @brief Returns number of pixels in x coordinate | |
| 927 | - ***************************************************************************/ | |
| 928 | -int GSkymap::nx(void) const | |
| 929 | -{ | |
| 930 | - // Return number of pixels | |
| 931 | - return m_num_x; | |
| 932 | -} | |
| 933 | - | |
| 934 | - | |
| 935 | -/***********************************************************************//** | |
| 936 | - * @brief Returns number of pixels in y coordinate | |
| 937 | - ***************************************************************************/ | |
| 938 | -int GSkymap::ny(void) const | |
| 939 | -{ | |
| 940 | - // Return number of pixels | |
| 941 | - return m_num_y; | |
| 942 | -} | |
| 943 | - | |
| 944 | - | |
| 945 | -/***********************************************************************//** | |
| 946 | - * @brief Returns number of maps | |
| 947 | - ***************************************************************************/ | |
| 948 | -int GSkymap::nmaps(void) const | |
| 949 | -{ | |
| 950 | - // Return number of maps | |
| 951 | - return m_num_maps; | |
| 952 | -} | |
| 953 | - | |
| 954 | - | |
| 955 | -/***********************************************************************//** | |
| 956 | - * @brief Converts 2D index (x,y) into 1D pixel index | |
| 957 | - * | |
| 958 | - * @param[in] pix 2D pixel index. | |
| 959 | - * | |
| 960 | - * The (x,y) value is rounded to nearest integers before conversion. The x | |
| 961 | - * axis is assumed as the most rapidely varying index. | |
| 962 | - ***************************************************************************/ | |
| 963 | -int GSkymap::xy2pix(const GSkyPixel& pix) const | |
| 964 | -{ | |
| 965 | - // Get x and y indices by rounding the (x,y) values | |
| 966 | - int ix = int(pix.x()+0.5); | |
| 967 | - int iy = int(pix.y()+0.5); | |
| 968 | - | |
| 969 | - // Return index | |
| 970 | - return (ix+iy*m_num_x); | |
| 971 | -} | |
| 972 | - | |
| 973 | - | |
| 974 | -/***********************************************************************//** | |
| 975 | - * @brief Converts 1D pixel index into 2D index (x,y) | |
| 976 | - * | |
| 977 | - * @param[in] pix 1D pixel index. | |
| 978 | - * | |
| 979 | - * If skymap is not 2D the pixel index is returned in the x element of the | |
| 980 | - * GSkyPixel object. | |
| 981 | - ***************************************************************************/ | |
| 982 | -GSkyPixel GSkymap::pix2xy(const int& pix) const | |
| 983 | -{ | |
| 984 | - // Get x and y indices | |
| 985 | - double x; | |
| 986 | - double y; | |
| 987 | - if (m_num_x != 0) { | |
| 988 | - x = double(pix % m_num_x); | |
| 989 | - y = double(pix / m_num_x); | |
| 990 | - } | |
| 991 | - else { | |
| 992 | - x = double(pix); | |
| 993 | - y = 0.0; | |
| 994 | - } | |
| 995 | - | |
| 996 | - // Set pixel | |
| 997 | - GSkyPixel pixel(x, y); | |
| 998 | - | |
| 999 | - // Return pixel | |
| 1000 | - return pixel; | |
| 1001 | -} | |
| 1002 | - | |
| 1003 | - | |
| 1004 | -/***********************************************************************//** | |
| 1005 | - * @brief Set sky projection | |
| 1006 | - * | |
| 1007 | - * @param[in] proj Sky projection. | |
| 1008 | - * | |
| 1009 | - * Sets the projection from celestial to pixel coordinates. The method | |
| 1010 | - * performs a deep copy of @p proj, allowing to destroy the argument after | |
| 1011 | - * using the method. | |
| 1012 | - ***************************************************************************/ | |
| 1013 | -void GSkymap::projection(const GSkyProjection& proj) | |
| 1014 | -{ | |
| 1015 | - // Free any existing WCS | |
| 1016 | - if (m_proj != NULL) delete m_proj; | |
| 1017 | - | |
| 1018 | - // Clone input WCS | |
| 1019 | - m_proj = proj.clone(); | |
| 1020 | - | |
| 1021 | - // Return | |
| 1022 | - return; | |
| 1023 | -} | |
| 1024 | - | |
| 1025 | - | |
| 1026 | -/***********************************************************************//** | |
| 1027 | - * @brief Verifies if sky direction falls in map | |
| 1028 | - * | |
| 1029 | - * @param[in] dir Sky direction. | |
| 1030 | - * | |
| 1031 | - * This method checks if the specified sky direction falls within the pixels | |
| 1032 | - * covered by the skymap. The method uses the dir2xy method to convert the | |
| 1033 | - * sky direction into 2D pixel indices, and then checks whether the pixel | |
| 1034 | - * indices fall in the skymap. | |
| 1035 | - ***************************************************************************/ | |
| 1036 | -bool GSkymap::contains(const GSkyDir& dir) const | |
| 1037 | -{ | |
| 1038 | - // Convert sky direction into sky pixel | |
| 1039 | - GSkyPixel pixel = dir2xy(dir); | |
| 1040 | - | |
| 1041 | - // Return location flag | |
| 1042 | - return (contains(pixel)); | |
| 1043 | -} | |
| 1044 | - | |
| 1045 | - | |
| 1046 | -/***********************************************************************//** | |
| 1047 | - * @brief Verifies if sky pixel falls in map | |
| 1048 | - * | |
| 1049 | - * @param[in] pixel Sky pixel. | |
| 1050 | - * | |
| 1051 | - * This method checks if the specified sky pixel is within the skymap. | |
| 1052 | - ***************************************************************************/ | |
| 1053 | -bool GSkymap::contains(const GSkyPixel& pixel) const | |
| 1054 | -{ | |
| 1055 | - // Initialise location flag | |
| 1056 | - bool inmap = false; | |
| 1057 | - | |
| 1058 | - // If pixel is in range then set location flag to true | |
| 1059 | - if ((pixel.x()+0.5 >= 0.0 && pixel.x()-0.5 < m_num_x) && | |
| 1060 | - (pixel.y()+0.5 >= 0.0 && pixel.y()-0.5 < m_num_y)) { | |
| 1061 | - inmap = true; | |
| 1062 | - } | |
| 1063 | - | |
| 1064 | - // Return location flag | |
| 1065 | - return inmap; | |
| 1066 | -} | |
| 1067 | - | |
| 1068 | - | |
| 1069 | -/***********************************************************************//** | |
| 1070 | 1115 | * @brief Print sky map |
| 1071 | 1116 | * |
| 1072 | 1117 | * @param[in] chatter Chattiness (defaults to NORMAL). |
| ... | ... | @@ -1088,7 +1133,7 @@ std::string GSkymap::print(const GChatter& chatter) const |
| 1088 | 1133 | result.append(gammalib::str(m_num_pixels)); |
| 1089 | 1134 | result.append("\n"+gammalib::parformat("Number of maps")); |
| 1090 | 1135 | result.append(gammalib::str(m_num_maps)); |
| 1091 | - if (m_proj != NULL && m_proj->code() != "HPX") { | |
| 1136 | + if (m_proj != NULL && m_proj->size() == 2) { | |
| 1092 | 1137 | result.append("\n"+gammalib::parformat("X axis dimension")); |
| 1093 | 1138 | result.append(gammalib::str(m_num_x)); |
| 1094 | 1139 | result.append("\n"+gammalib::parformat("Y axis dimension")); |
| ... | ... | @@ -1181,7 +1226,7 @@ void GSkymap::copy_members(const GSkymap& map) |
| 1181 | 1226 | // Copy pixels |
| 1182 | 1227 | if (size > 0 && map.m_pixels != NULL) { |
| 1183 | 1228 | alloc_pixels(); |
| 1184 | - for (int i = 0; i < size; ++i) { | |
| 1229 | + for (int i = 0; i < size; ++i) { | |
| 1185 | 1230 | m_pixels[i] = map.m_pixels[i]; |
| 1186 | 1231 | } |
| 1187 | 1232 | } | ... | ... |
src/sky/GWcs.cpp
| ... | ... | @@ -436,35 +436,9 @@ void GWcs::write(GFitsHDU* hdu) const |
| 436 | 436 | /***********************************************************************//** |
| 437 | 437 | * @brief Returns solid angle of pixel in units of steradians |
| 438 | 438 | * |
| 439 | - * @param[in] pix Pixel index. | |
| 439 | + * @param[in] pixel Pixel index (x,y) | |
| 440 | 440 | * |
| 441 | - * This dummy method throws an error when called as pixel indices are not | |
| 442 | - * implemented for a HealPix grid. Maybe we should drop this method and | |
| 443 | - * implement a general GSkyPixel class tha also handles HealPix? | |
| 444 | - * | |
| 445 | - * @todo Think about implementation of sky pixel for HealPix data. We may | |
| 446 | - * use only the first argument, and even carry a usage flag in | |
| 447 | - * GSkyPixel | |
| 448 | - ***************************************************************************/ | |
| 449 | -double GWcs::omega(const int& pix) const | |
| 450 | -{ | |
| 451 | - // Set error message | |
| 452 | - std::string message = "Method not defined for general WCS projection."; | |
| 453 | - | |
| 454 | - // Throw error | |
| 455 | - throw GException::wcs(G_OMEGA, message); | |
| 456 | - | |
| 457 | - // Return | |
| 458 | - return 0.0; | |
| 459 | -} | |
| 460 | - | |
| 461 | - | |
| 462 | -/***********************************************************************//** | |
| 463 | - * @brief Returns solid angle of pixel in units of steradians | |
| 464 | - * | |
| 465 | - * @param[in] pix Pixel index (x,y) | |
| 466 | - * | |
| 467 | - * Estimate solid angles of pixel by compuing the coordinates in the 4 pixel | |
| 441 | + * Estimate solid angles of pixel by computing the coordinates in the 4 pixel | |
| 468 | 442 | * corners. The surface is computed using a cartesian approximation: |
| 469 | 443 | * a |
| 470 | 444 | * 1-----5-----2 a+b |
| ... | ... | @@ -475,15 +449,15 @@ double GWcs::omega(const int& pix) const |
| 475 | 449 | * rotated sky maps. Something more intelligent should be implemented in |
| 476 | 450 | * the future. |
| 477 | 451 | ***************************************************************************/ |
| 478 | -double GWcs::omega(const GSkyPixel& pix) const | |
| 452 | +double GWcs::omega(const GSkyPixel& pixel) const | |
| 479 | 453 | { |
| 480 | 454 | // Get the sky directions of the 6 points |
| 481 | - GSkyDir dir1 = xy2dir(GSkyPixel(pix.x()-0.5, pix.y()-0.5)); | |
| 482 | - GSkyDir dir2 = xy2dir(GSkyPixel(pix.x()+0.5, pix.y()-0.5)); | |
| 483 | - GSkyDir dir3 = xy2dir(GSkyPixel(pix.x()+0.5, pix.y()+0.5)); | |
| 484 | - GSkyDir dir4 = xy2dir(GSkyPixel(pix.x()-0.5, pix.y()+0.5)); | |
| 485 | - GSkyDir dir5 = xy2dir(GSkyPixel(pix.x(), pix.y()-0.5)); | |
| 486 | - GSkyDir dir6 = xy2dir(GSkyPixel(pix.x(), pix.y()+0.5)); | |
| 455 | + GSkyDir dir1 = pix2dir(GSkyPixel(pixel.x()-0.5, pixel.y()-0.5)); | |
| 456 | + GSkyDir dir2 = pix2dir(GSkyPixel(pixel.x()+0.5, pixel.y()-0.5)); | |
| 457 | + GSkyDir dir3 = pix2dir(GSkyPixel(pixel.x()+0.5, pixel.y()+0.5)); | |
| 458 | + GSkyDir dir4 = pix2dir(GSkyPixel(pixel.x()-0.5, pixel.y()+0.5)); | |
| 459 | + GSkyDir dir5 = pix2dir(GSkyPixel(pixel.x(), pixel.y()-0.5)); | |
| 460 | + GSkyDir dir6 = pix2dir(GSkyPixel(pixel.x(), pixel.y()+0.5)); | |
| 487 | 461 | |
| 488 | 462 | // Compute distances between sky directions |
| 489 | 463 | double a = dir1.dist(dir2); |
| ... | ... | @@ -499,64 +473,16 @@ double GWcs::omega(const GSkyPixel& pix) const |
| 499 | 473 | |
| 500 | 474 | |
| 501 | 475 | /***********************************************************************//** |
| 502 | - * @brief Returns sky direction of pixel (DUMMY METHOD) | |
| 503 | - * | |
| 504 | - * @param[in] pix Pixel number (0,1,...,m_num_pixels). | |
| 505 | - * | |
| 506 | - * @exception GException::wcs | |
| 507 | - * Method not defined for projection. | |
| 508 | - * | |
| 509 | - * This method should be overloaded by the appropriate method of the derived | |
| 510 | - * class. It thus should never get called. | |
| 511 | - ***************************************************************************/ | |
| 512 | -GSkyDir GWcs::pix2dir(const int& pix) const | |
| 513 | -{ | |
| 514 | - // Set error message | |
| 515 | - std::string message = "Method not defined for general WCS projection."; | |
| 516 | - | |
| 517 | - // Throw error | |
| 518 | - throw GException::wcs(G_PIX2DIR, message); | |
| 519 | - | |
| 520 | - // Define direction | |
| 521 | - GSkyDir dir; | |
| 522 | - | |
| 523 | - // Return | |
| 524 | - return dir; | |
| 525 | -} | |
| 526 | - | |
| 527 | - | |
| 528 | -/***********************************************************************//** | |
| 529 | - * @brief Returns pixel for sky direction (DUMMY METHOD) | |
| 530 | - * | |
| 531 | - * @param[in] dir Sky direction. | |
| 532 | - * | |
| 533 | - * @exception GException::wcs | |
| 534 | - * Method not defined for projection. | |
| 535 | - * | |
| 536 | - * This method should be overloaded by the appropriate method of the derived | |
| 537 | - * class. It thus should never get called. | |
| 538 | - ***************************************************************************/ | |
| 539 | -int GWcs::dir2pix(const GSkyDir& dir) const | |
| 540 | -{ | |
| 541 | - // Set error message | |
| 542 | - std::string message = "Method not defined for general WCS projection."; | |
| 543 | - | |
| 544 | - // Throw error | |
| 545 | - throw GException::wcs(G_DIR2PIX, message); | |
| 546 | - | |
| 547 | - // Return | |
| 548 | - return 0; | |
| 549 | -} | |
| 550 | - | |
| 551 | - | |
| 552 | -/***********************************************************************//** | |
| 553 | - * @brief Returns sky direction of pixel | |
| 476 | + * @brief Returns sky direction of sky map pixel | |
| 554 | 477 | * |
| 555 | - * @param[in] pix Sky pixel. | |
| 478 | + * @param[in] pixel Sky map pixel. | |
| 479 | + * @return Sky direction. | |
| 556 | 480 | * |
| 557 | - * Note that pixel indices start from 0. | |
| 481 | + * Returns the sky direction of a sky map @p pixel. Note that the sky | |
| 482 | + * map pixel values start from 0 while the WCS pixel reference starts from | |
| 483 | + * 1. | |
| 558 | 484 | ***************************************************************************/ |
| 559 | -GSkyDir GWcs::xy2dir(const GSkyPixel& pix) const | |
| 485 | +GSkyDir GWcs::pix2dir(const GSkyPixel& pixel) const | |
| 560 | 486 | { |
| 561 | 487 | // Allocate memory for transformation |
| 562 | 488 | double pixcrd[2]; |
| ... | ... | @@ -568,8 +494,8 @@ GSkyDir GWcs::xy2dir(const GSkyPixel& pix) const |
| 568 | 494 | |
| 569 | 495 | // Set sky pixel. We have to add 1.0 here as the WCS pixel reference |
| 570 | 496 | // (CRPIX) starts from one while GSkyPixel starts from 0. |
| 571 | - pixcrd[0] = pix.x() + 1.0; | |
| 572 | - pixcrd[1] = pix.y() + 1.0; | |
| 497 | + pixcrd[0] = pixel.x() + 1.0; | |
| 498 | + pixcrd[1] = pixel.y() + 1.0; | |
| 573 | 499 | |
| 574 | 500 | // Trasform pixel-to-world coordinate |
| 575 | 501 | wcs_p2s(1, 2, pixcrd, imgcrd, &phi, &theta, world, &stat); |
| ... | ... | @@ -585,7 +511,7 @@ GSkyDir GWcs::xy2dir(const GSkyPixel& pix) const |
| 585 | 511 | |
| 586 | 512 | // Debug: Dump transformation steps |
| 587 | 513 | #if defined(G_XY2DIR_DEBUG) |
| 588 | - std::cout << "xy2dir: pixel=" << pix | |
| 514 | + std::cout << "xy2dir: pixel=" << pixel | |
| 589 | 515 | << " (x,y)=(" << pixcrd[0] << "," << pixcrd[1] << ")" |
| 590 | 516 | << " (phi,theta)=(" << phi << "," << theta << ")" |
| 591 | 517 | << " (lng,lat)=(" << world[0] << "," << world[1] << ")" << std::endl; |
| ... | ... | @@ -597,14 +523,16 @@ GSkyDir GWcs::xy2dir(const GSkyPixel& pix) const |
| 597 | 523 | |
| 598 | 524 | |
| 599 | 525 | /***********************************************************************//** |
| 600 | - * @brief Returns pixel of sky direction | |
| 526 | + * @brief Returns sky map pixel of sky direction | |
| 601 | 527 | * |
| 602 | 528 | * @param[in] dir Sky direction. |
| 529 | + * @return Sky map pixel. | |
| 603 | 530 | * |
| 604 | - * Note that GSkyPixel indices start from 0 while the WCS pixel reference | |
| 605 | - * starts from 1. | |
| 531 | + * Returns the sky map pixel for a given sky direction. Note that the sky | |
| 532 | + * map pixel values start from 0 while the WCS pixel reference starts from | |
| 533 | + * 1. | |
| 606 | 534 | ***************************************************************************/ |
| 607 | -GSkyPixel GWcs::dir2xy(const GSkyDir& dir) const | |
| 535 | +GSkyPixel GWcs::dir2pix(const GSkyDir& dir) const | |
| 608 | 536 | { |
| 609 | 537 | // Allocate memory for transformation |
| 610 | 538 | double pixcrd[2]; | ... | ... |
test/test_GSky.cpp
| ... | ... | @@ -106,10 +106,10 @@ double TestGSky::wcs_forth_back_pixel(GWcs* wcs, int nx, int ny, double& crpix1, |
| 106 | 106 | GSkyPixel pix_in(x,y); |
| 107 | 107 | |
| 108 | 108 | // Forth: Transform to world |
| 109 | - GSkyDir dir = wcs->xy2dir(pix_in); | |
| 109 | + GSkyDir dir = wcs->pix2dir(pix_in); | |
| 110 | 110 | |
| 111 | 111 | // Back: Transform to pixel |
| 112 | - GSkyPixel pix_out = wcs->dir2xy(dir); | |
| 112 | + GSkyPixel pix_out = wcs->dir2pix(dir); | |
| 113 | 113 | |
| 114 | 114 | // Compute distance |
| 115 | 115 | double dx = pix_in.x()-pix_out.x(); |
| ... | ... | @@ -177,7 +177,7 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double& crpix1, double& crp |
| 177 | 177 | for (int iy = -ny; iy <= ny; ++iy) { |
| 178 | 178 | |
| 179 | 179 | // Set y value |
| 180 | - double y = double(iy) + crpix2; | |
| 180 | + double y = double(iy) + crpix2; | |
| 181 | 181 | |
| 182 | 182 | // Skip pixels outside valid range (they are not expected to |
| 183 | 183 | // transform bijectively) |
| ... | ... | @@ -189,8 +189,8 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double& crpix1, double& crp |
| 189 | 189 | GSkyPixel pix_in(x,y); |
| 190 | 190 | |
| 191 | 191 | // Transform to world |
| 192 | - GSkyDir dir1 = wcs->xy2dir(pix_in); | |
| 193 | - GSkyDir dir2 = cpy->xy2dir(pix_in); | |
| 192 | + GSkyDir dir1 = wcs->pix2dir(pix_in); | |
| 193 | + GSkyDir dir2 = cpy->pix2dir(pix_in); | |
| 194 | 194 | double angle = dir1.dist_deg(dir2); |
| 195 | 195 | if (angle > angle_max) { |
| 196 | 196 | angle_max = angle; |
| ... | ... | @@ -207,8 +207,8 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double& crpix1, double& crp |
| 207 | 207 | #endif |
| 208 | 208 | |
| 209 | 209 | // Transform to pixel |
| 210 | - GSkyPixel pix_out1 = wcs->dir2xy(dir1); | |
| 211 | - GSkyPixel pix_out2 = cpy->dir2xy(dir2); | |
| 210 | + GSkyPixel pix_out1 = wcs->dir2pix(dir1); | |
| 211 | + GSkyPixel pix_out2 = cpy->dir2pix(dir2); | |
| 212 | 212 | |
| 213 | 213 | // Compute distance |
| 214 | 214 | double dx = pix_out1.x()-pix_out2.x(); |
| ... | ... | @@ -715,8 +715,8 @@ void TestGSky::test_GSkymap_wcs_construct(void) |
| 715 | 715 | for (int l = -180; l < 180; ++l) { |
| 716 | 716 | for (int b = -90; b < 90; ++b) { |
| 717 | 717 | dir.lb_deg(double(l),double(b)); |
| 718 | - GSkyPixel pixel = map1.dir2xy(dir); | |
| 719 | - GSkyDir dir_back = map1.xy2dir(pixel); | |
| 718 | + GSkyPixel pixel = map1.dir2pix(dir); | |
| 719 | + GSkyDir dir_back = map1.pix2dir(pixel); | |
| 720 | 720 | double dist = dir.dist_deg(dir_back); |
| 721 | 721 | if (dist > eps) { |
| 722 | 722 | throw exception_failure("Sky direction differs: dir="+dir.print()+" pixel="+pixel.print()+" dir_back"+ dir_back.print()+" dist="+gammalib::str(dist)+" deg"); | ... | ... |
test/test_GSky.py
| ... | ... | @@ -73,10 +73,11 @@ class Test(GPythonTestSuite): |
| 73 | 73 | # Append tests |
| 74 | 74 | self.append(self.test_skymap_healpix, "Test HEALPix map") |
| 75 | 75 | self.append(self.test_skymap_ait, "Test AIT projection map") |
| 76 | + self.append(self.test_skymap_azp, "Test AZP projection map") | |
| 76 | 77 | self.append(self.test_skymap_car, "Test CAR projection map") |
| 77 | - self.append(self.test_skymap_tan, "Test TAN projection map") | |
| 78 | + self.append(self.test_skymap_mer, "Test MER projection map") | |
| 78 | 79 | self.append(self.test_skymap_stg, "Test STG projection map") |
| 79 | - self.append(self.test_skymap_azp, "Test AZP projection map") | |
| 80 | + self.append(self.test_skymap_tan, "Test TAN projection map") | |
| 80 | 81 | self.append(self.test_fk5_to_galactic, "Test FK5 to Galactic coordinate conversion") |
| 81 | 82 | |
| 82 | 83 | # Return |
| ... | ... | @@ -87,21 +88,21 @@ class Test(GPythonTestSuite): |
| 87 | 88 | """ |
| 88 | 89 | Control coordinate and pixel transformation methods. |
| 89 | 90 | """ |
| 90 | - # Control pix2dir / dir2pix methods for all pixels | |
| 91 | + # Control inx2dir/dir2inx methods for all pixels | |
| 91 | 92 | for i in range(pixels.npix()): |
| 92 | - dir = pixels.pix2dir(i) | |
| 93 | - ipix = pixels.dir2pix(dir) | |
| 94 | - msg = map + " pix2dir/dir2pix check for pixel " + str(i) | |
| 95 | - err = map + " GSkymap trouble with pixel " + str(i) + " (" + str(ipix) + \ | |
| 93 | + dir = pixels.inx2dir(i) | |
| 94 | + inx = pixels.dir2inx(dir) | |
| 95 | + msg = map + " inx2dir/dir2inx check for pixel " + str(i) | |
| 96 | + err = map + " GSkymap trouble with pixel " + str(i) + " (" + str(inx) + \ | |
| 96 | 97 | "), RA=" + str(dir.ra() * 180 / pi) + ", Dec=" + str(dir.dec() * 180 / pi) |
| 97 | - self.test_assert(i == ipix, msg, err) | |
| 98 | + self.test_assert(i == inx, msg, err) | |
| 98 | 99 | |
| 99 | 100 | # Control SkyDir coordinate transformation for all pixels |
| 100 | 101 | for i in range(pixels.npix()): |
| 101 | - dir = pixels.pix2dir(i) | |
| 102 | + dir = pixels.inx2dir(i) | |
| 102 | 103 | dir_new = GSkyDir() |
| 103 | 104 | dir_new.lb(dir.l(), dir.b()) |
| 104 | - dra = abs(dir.ra() - dir_new.ra()) | |
| 105 | + dra = abs(dir.ra() - dir_new.ra()) | |
| 105 | 106 | if (dra >= 5.0): |
| 106 | 107 | dra -= 2.0 * pi |
| 107 | 108 | ddec = abs(dir.dec() - dir_new.dec()) |
| ... | ... | @@ -196,6 +197,17 @@ class Test(GPythonTestSuite): |
| 196 | 197 | # Return |
| 197 | 198 | return |
| 198 | 199 | |
| 200 | + # Test AZP projection | |
| 201 | + def test_skymap_azp(self): | |
| 202 | + """ | |
| 203 | + Test AZP projection. | |
| 204 | + """ | |
| 205 | + # Execute generic test | |
| 206 | + self.test_skymap_proj("AZP") | |
| 207 | + | |
| 208 | + # Return | |
| 209 | + return | |
| 210 | + | |
| 199 | 211 | # Test CAR projection |
| 200 | 212 | def test_skymap_car(self): |
| 201 | 213 | """ |
| ... | ... | @@ -207,13 +219,13 @@ class Test(GPythonTestSuite): |
| 207 | 219 | # Return |
| 208 | 220 | return |
| 209 | 221 | |
| 210 | - # Test TAN projection | |
| 211 | - def test_skymap_tan(self): | |
| 222 | + # Test MER projection | |
| 223 | + def test_skymap_mer(self): | |
| 212 | 224 | """ |
| 213 | - Test TAN projection. | |
| 225 | + Test MER projection. | |
| 214 | 226 | """ |
| 215 | 227 | # Execute generic test |
| 216 | - self.test_skymap_proj("TAN") | |
| 228 | + self.test_skymap_proj("MER") | |
| 217 | 229 | |
| 218 | 230 | # Return |
| 219 | 231 | return |
| ... | ... | @@ -229,13 +241,13 @@ class Test(GPythonTestSuite): |
| 229 | 241 | # Return |
| 230 | 242 | return |
| 231 | 243 | |
| 232 | - # Test AZP projection | |
| 233 | - def test_skymap_azp(self): | |
| 244 | + # Test TAN projection | |
| 245 | + def test_skymap_tan(self): | |
| 234 | 246 | """ |
| 235 | - Test AZP projection. | |
| 247 | + Test TAN projection. | |
| 236 | 248 | """ |
| 237 | 249 | # Execute generic test |
| 238 | - self.test_skymap_proj("AZP") | |
| 250 | + self.test_skymap_proj("TAN") | |
| 239 | 251 | |
| 240 | 252 | # Return |
| 241 | 253 | return | ... | ... |