Commit f5618c950ceb03c0949aa09c4eaa9d1b3160a74a

Authored by Jürgen Knödlseder
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".
include/GHealpix.hpp
@@ -61,16 +61,14 @@ public: @@ -61,16 +61,14 @@ public:
61 // Implemented pure virtual base class methods 61 // Implemented pure virtual base class methods
62 virtual void clear(void); 62 virtual void clear(void);
63 virtual GHealpix* clone(void) const; 63 virtual GHealpix* clone(void) const;
  64 + virtual int size(void) const;
64 virtual std::string code(void) const; 65 virtual std::string code(void) const;
65 virtual std::string name(void) const; 66 virtual std::string name(void) const;
66 virtual void read(const GFitsHDU* hdu); 67 virtual void read(const GFitsHDU* hdu);
67 virtual void write(GFitsHDU* hdu) const; 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 virtual std::string print(const GChatter& chatter = NORMAL) const; 72 virtual std::string print(const GChatter& chatter = NORMAL) const;
75 73
76 // Other methods 74 // Other methods
@@ -108,6 +106,20 @@ private: @@ -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 * @brief Return projection code 123 * @brief Return projection code
112 * 124 *
113 * @return Projection code. 125 * @return Projection code.
include/GSkyProjection.hpp
@@ -62,16 +62,14 @@ public: @@ -62,16 +62,14 @@ public:
62 // Pure virtual methods 62 // Pure virtual methods
63 virtual void clear(void) = 0; 63 virtual void clear(void) = 0;
64 virtual GSkyProjection* clone(void) const = 0; 64 virtual GSkyProjection* clone(void) const = 0;
  65 + virtual int size(void) const = 0;
65 virtual std::string code(void) const = 0; 66 virtual std::string code(void) const = 0;
66 virtual std::string name(void) const = 0; 67 virtual std::string name(void) const = 0;
67 virtual void read(const GFitsHDU* hdu) = 0; 68 virtual void read(const GFitsHDU* hdu) = 0;
68 virtual void write(GFitsHDU* hdu) const = 0; 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 virtual std::string print(const GChatter& chatter = NORMAL) const = 0; 73 virtual std::string print(const GChatter& chatter = NORMAL) const = 0;
76 74
77 // Virtual methods 75 // Virtual methods
include/GSkymap.hpp
@@ -45,20 +45,22 @@ @@ -45,20 +45,22 @@
45 /***********************************************************************//** 45 /***********************************************************************//**
46 * @class GSkymap 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 * the HEALPix format or in any (supported) WCS format. Skymap pixels are 51 * the HEALPix format or in any (supported) WCS format. Skymap pixels are
52 * stored in a double precision array indexed by (x,y,map), with the x 52 * stored in a double precision array indexed by (x,y,map), with the x
53 * axis being the most rapidely varying axis. 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 * where pixel implements a 2D (x,y) pixel direction. The first operator is 57 * where pixel implements a 2D (x,y) pixel direction. The first operator is
58 * the preferred access method for HEALPix maps while the second operator is 58 * the preferred access method for HEALPix maps while the second operator is
59 * the preferred access method for WCS maps. Conversion methods between the 59 * the preferred access method for WCS maps. Conversion methods between the
60 * index or sky pixel and the true physical sky direction are provided by the 60 * index or sky pixel and the true physical sky direction are provided by the
61 * pix2dir() and dir2pix() methods. 61 * pix2dir() and dir2pix() methods.
  62 + *
  63 + * @todo Rewrite class description.
62 ***************************************************************************/ 64 ***************************************************************************/
63 class GSkymap : public GBase { 65 class GSkymap : public GBase {
64 66
@@ -83,44 +85,38 @@ public: @@ -83,44 +85,38 @@ public:
83 virtual ~GSkymap(void); 85 virtual ~GSkymap(void);
84 86
85 // Operators 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 double& operator()(const GSkyPixel& pixel, const int& map = 0); 91 double& operator()(const GSkyPixel& pixel, const int& map = 0);
97 const double& operator()(const GSkyPixel& pixel, const int& map = 0) const; 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 double operator()(const GSkyDir& dir, const int& map = 0) const; 93 double operator()(const GSkyDir& dir, const int& map = 0) const;
104 94
105 // Methods 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 private: 121 private:
126 // Private methods 122 // Private methods
@@ -148,4 +144,86 @@ private: @@ -148,4 +144,86 @@ private:
148 double* m_pixels; //!< Pointer to skymap pixels 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 #endif /* GSKYMAP_HPP */ 229 #endif /* GSKYMAP_HPP */
include/GWcs.hpp
@@ -67,14 +67,12 @@ public: @@ -67,14 +67,12 @@ public:
67 virtual std::string print(const GChatter& chatter = NORMAL) const = 0; 67 virtual std::string print(const GChatter& chatter = NORMAL) const = 0;
68 68
69 // Implemented virtual base class methods 69 // Implemented virtual base class methods
  70 + virtual int size(void) const;
70 virtual void read(const GFitsHDU* hdu); 71 virtual void read(const GFitsHDU* hdu);
71 virtual void write(GFitsHDU* hdu) const; 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 // Other methods 77 // Other methods
80 void set(const std::string& coords, 78 void set(const std::string& coords,
@@ -208,4 +206,18 @@ protected: @@ -208,4 +206,18 @@ protected:
208 //struct spcprm spc 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 #endif /* GWCS_HPP */ 223 #endif /* GWCS_HPP */
inst/com/src/GCOMEventCube.cpp
@@ -504,7 +504,7 @@ int GCOMEventCube::number(void) const @@ -504,7 +504,7 @@ int GCOMEventCube::number(void) const
504 double number = 0.0; 504 double number = 0.0;
505 505
506 // Get pointer on skymap pixels 506 // Get pointer on skymap pixels
507 - double* pixels = m_map.pixels(); 507 + const double* pixels = m_map.pixels();
508 508
509 // Sum event cube 509 // Sum event cube
510 if (size() > 0 && pixels != NULL) { 510 if (size() > 0 && pixels != NULL) {
@@ -708,7 +708,7 @@ void GCOMEventCube::set_scatter_directions(void) @@ -708,7 +708,7 @@ void GCOMEventCube::set_scatter_directions(void)
708 for (int iy = 0; iy < npsi(); ++iy) { 708 for (int iy = 0; iy < npsi(); ++iy) {
709 for (int ix = 0; ix < nchi(); ++ix) { 709 for (int ix = 0; ix < nchi(); ++ix) {
710 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 m_omega.push_back(m_map.omega(pixel)); 712 m_omega.push_back(m_map.omega(pixel));
713 } 713 }
714 } 714 }
@@ -871,7 +871,7 @@ void GCOMEventCube::set_bin(const int&amp; index) @@ -871,7 +871,7 @@ void GCOMEventCube::set_bin(const int&amp; index)
871 m_dir.phibar(m_phi[iphi]); 871 m_dir.phibar(m_phi[iphi]);
872 872
873 // Set pointers 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 m_bin.m_omega = &(m_omega[ipix]); 875 m_bin.m_omega = &(m_omega[ipix]);
876 876
877 // Return 877 // Return
inst/com/src/GCOMSupport.cpp
@@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
54 void com_wcs_mer2car(GSkymap& map) 54 void com_wcs_mer2car(GSkymap& map)
55 { 55 {
56 // Get WCS poiunter 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 // Apply kluge only if the skymap is in Mercator's projection 59 // Apply kluge only if the skymap is in Mercator's projection
60 if (wcs != NULL && wcs->code() == "MER") { 60 if (wcs != NULL && wcs->code() == "MER") {
inst/cta/src/GCTAEventCube.cpp
@@ -418,7 +418,7 @@ int GCTAEventCube::number(void) const @@ -418,7 +418,7 @@ int GCTAEventCube::number(void) const
418 double number = 0.0; 418 double number = 0.0;
419 419
420 // Get pointer on skymap pixels 420 // Get pointer on skymap pixels
421 - double* pixels = m_map.pixels(); 421 + const double* pixels = m_map.pixels();
422 422
423 // Sum event cube 423 // Sum event cube
424 if (size() > 0 && pixels != NULL) { 424 if (size() > 0 && pixels != NULL) {
@@ -670,7 +670,7 @@ void GCTAEventCube::set_directions(void) @@ -670,7 +670,7 @@ void GCTAEventCube::set_directions(void)
670 for (int iy = 0; iy < ny(); ++iy) { 670 for (int iy = 0; iy < ny(); ++iy) {
671 for (int ix = 0; ix < nx(); ++ix) { 671 for (int ix = 0; ix < nx(); ++ix) {
672 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 m_omega.push_back(m_map.omega(pixel)); 674 m_omega.push_back(m_map.omega(pixel));
675 } 675 }
676 } 676 }
@@ -770,24 +770,27 @@ void GCTAEventCube::set_bin(const int&amp; index) @@ -770,24 +770,27 @@ void GCTAEventCube::set_bin(const int&amp; index)
770 { 770 {
771 // Optionally check if the index is valid 771 // Optionally check if the index is valid
772 #if defined(G_RANGE_CHECK) 772 #if defined(G_RANGE_CHECK)
773 - if (index < 0 || index >= size()) 773 + if (index < 0 || index >= size()) {
774 throw GException::out_of_range(G_SET_BIN, index, 0, size()-1); 774 throw GException::out_of_range(G_SET_BIN, index, 0, size()-1);
  775 + }
775 #endif 776 #endif
776 777
777 // Check for the existence of energies and energy widths 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 throw GCTAException::no_energies(G_SET_BIN); 780 throw GCTAException::no_energies(G_SET_BIN);
  781 + }
780 782
781 // Check for the existence of sky directions and solid angles 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 throw GCTAException::no_dirs(G_SET_BIN); 785 throw GCTAException::no_dirs(G_SET_BIN);
  786 + }
784 787
785 // Get pixel and energy bin indices. 788 // Get pixel and energy bin indices.
786 int ipix = index % npix(); 789 int ipix = index % npix();
787 int ieng = index / npix(); 790 int ieng = index / npix();
788 791
789 // Set pointers 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 m_bin.m_energy = &(m_energies[ieng]); 794 m_bin.m_energy = &(m_energies[ieng]);
792 m_bin.m_time = &m_time; 795 m_bin.m_time = &m_time;
793 m_bin.m_dir = &(m_dirs[ipix]); 796 m_bin.m_dir = &(m_dirs[ipix]);
inst/lat/src/GLATEventCube.cpp
@@ -388,7 +388,7 @@ int GLATEventCube::number(void) const @@ -388,7 +388,7 @@ int GLATEventCube::number(void) const
388 double number = 0.0; 388 double number = 0.0;
389 389
390 // Get pointer on skymap pixels 390 // Get pointer on skymap pixels
391 - double* pixels = m_map.pixels(); 391 + const double* pixels = m_map.pixels();
392 392
393 // Sum event cube 393 // Sum event cube
394 if (size() > 0 && pixels != NULL) { 394 if (size() > 0 && pixels != NULL) {
@@ -561,7 +561,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const @@ -561,7 +561,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const
561 int iy = 0; 561 int iy = 0;
562 for (int ix = 0; ix < nx(); ++ix) { 562 for (int ix = 0; ix < nx(); ++ix) {
563 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 if (distance < radius) { 565 if (distance < radius) {
566 radius = distance; 566 radius = distance;
567 } 567 }
@@ -571,7 +571,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const @@ -571,7 +571,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const
571 iy = ny()-1; 571 iy = ny()-1;
572 for (int ix = 0; ix < nx(); ++ix) { 572 for (int ix = 0; ix < nx(); ++ix) {
573 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 if (distance < radius) { 575 if (distance < radius) {
576 radius = distance; 576 radius = distance;
577 } 577 }
@@ -581,7 +581,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const @@ -581,7 +581,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const
581 int ix = 0; 581 int ix = 0;
582 for (int iy = 0; iy < ny(); ++iy) { 582 for (int iy = 0; iy < ny(); ++iy) {
583 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 if (distance < radius) { 585 if (distance < radius) {
586 radius = distance; 586 radius = distance;
587 } 587 }
@@ -591,7 +591,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const @@ -591,7 +591,7 @@ double GLATEventCube::maxrad(const GSkyDir&amp; srcDir) const
591 ix = nx()-1; 591 ix = nx()-1;
592 for (int iy = 0; iy < ny(); ++iy) { 592 for (int iy = 0; iy < ny(); ++iy) {
593 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 if (distance < radius) { 595 if (distance < radius) {
596 radius = distance; 596 radius = distance;
597 } 597 }
@@ -841,7 +841,7 @@ void GLATEventCube::set_directions(void) @@ -841,7 +841,7 @@ void GLATEventCube::set_directions(void)
841 for (int iy = 0; iy < ny(); ++iy) { 841 for (int iy = 0; iy < ny(); ++iy) {
842 for (int ix = 0; ix < nx(); ++ix) { 842 for (int ix = 0; ix < nx(); ++ix) {
843 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 m_omega.push_back(m_map.omega(pixel)); 845 m_omega.push_back(m_map.omega(pixel));
846 } 846 }
847 } 847 }
@@ -967,7 +967,7 @@ void GLATEventCube::set_bin(const int&amp; index) @@ -967,7 +967,7 @@ void GLATEventCube::set_bin(const int&amp; index)
967 967
968 // Set pointers 968 // Set pointers
969 m_bin.m_cube = this; 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 m_bin.m_energy = &(m_energies[m_bin.m_ieng]); 971 m_bin.m_energy = &(m_energies[m_bin.m_ieng]);
972 m_bin.m_time = &m_time; 972 m_bin.m_time = &m_time;
973 m_bin.m_dir = &(m_dirs[m_bin.m_ipix]); 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&amp; obs) @@ -738,7 +738,7 @@ void GLATMeanPsf::set_map_corrections(const GLATObservation&amp; obs)
738 738
739 // Compute offset angle in degrees 739 // Compute offset angle in degrees
740 GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); 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 double omega = cube->map().omega(pixel); 742 double omega = cube->map().omega(pixel);
743 743
744 // Use only pixels within maximum PSF radius 744 // Use only pixels within maximum PSF radius
inst/lat/src/GLATResponse.cpp
@@ -400,10 +400,10 @@ double GLATResponse::irf(const GLATEventBin&amp; event, @@ -400,10 +400,10 @@ double GLATResponse::irf(const GLATEventBin&amp; event,
400 nodes.set_value(srcEng.log10MeV()); 400 nodes.set_value(srcEng.log10MeV());
401 401
402 // Compute diffuse response 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 // Divide by solid angle and ontime since source maps are given in units of 408 // Divide by solid angle and ontime since source maps are given in units of
409 // counts/pixel/MeV. 409 // counts/pixel/MeV.
inst/lat/test/test_LAT.cpp
@@ -287,7 +287,7 @@ void TestGLATLtCube::test_one_ltcube(const std::string&amp; datadir, const double&amp; r @@ -287,7 +287,7 @@ void TestGLATLtCube::test_one_ltcube(const std::string&amp; datadir, const double&amp; r
287 GLATLtCube ltcube(lat_ltcube); 287 GLATLtCube ltcube(lat_ltcube);
288 GEnergy energy; 288 GEnergy energy;
289 for (int i = 0; i < map.npix(); ++i) { 289 for (int i = 0; i < map.npix(); ++i) {
290 - GSkyDir dir = map.pix2dir(i); 290 + GSkyDir dir = map.inx2dir(i);
291 map(i) = ltcube(dir, energy, test_fct1); 291 map(i) = ltcube(dir, energy, test_fct1);
292 } 292 }
293 map.save(file1, true); 293 map.save(file1, true);
@@ -304,7 +304,7 @@ void TestGLATLtCube::test_one_ltcube(const std::string&amp; datadir, const double&amp; r @@ -304,7 +304,7 @@ void TestGLATLtCube::test_one_ltcube(const std::string&amp; datadir, const double&amp; r
304 GLATLtCube ltcube(lat_ltcube); 304 GLATLtCube ltcube(lat_ltcube);
305 GEnergy energy; 305 GEnergy energy;
306 for (int i = 0; i < map.npix(); ++i) { 306 for (int i = 0; i < map.npix(); ++i) {
307 - GSkyDir dir = map.pix2dir(i); 307 + GSkyDir dir = map.inx2dir(i);
308 map(i) = ltcube(dir, energy, test_fct2); 308 map(i) = ltcube(dir, energy, test_fct2);
309 } 309 }
310 map.save(file2, true); 310 map.save(file2, true);
pyext/GHealpix.i
@@ -47,16 +47,14 @@ public: @@ -47,16 +47,14 @@ public:
47 // Implemented pure virtual methods 47 // Implemented pure virtual methods
48 virtual void clear(void); 48 virtual void clear(void);
49 virtual GHealpix* clone(void) const; 49 virtual GHealpix* clone(void) const;
  50 + virtual int size(void) const;
50 virtual std::string code(void) const; 51 virtual std::string code(void) const;
51 virtual std::string name(void) const; 52 virtual std::string name(void) const;
52 virtual void read(const GFitsHDU* hdu); 53 virtual void read(const GFitsHDU* hdu);
53 virtual void write(GFitsHDU* hdu) const; 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 // Other methods 59 // Other methods
62 const int& npix(void) const; 60 const int& npix(void) const;
pyext/GSkyProjection.i
@@ -48,16 +48,14 @@ public: @@ -48,16 +48,14 @@ public:
48 // Pure virtual methods (not implemented) 48 // Pure virtual methods (not implemented)
49 virtual void clear(void) = 0; 49 virtual void clear(void) = 0;
50 virtual GSkyProjection* clone(void) const = 0; 50 virtual GSkyProjection* clone(void) const = 0;
  51 + virtual int size(void) const = 0;
51 virtual std::string code(void) const = 0; 52 virtual std::string code(void) const = 0;
52 virtual std::string name(void) const = 0; 53 virtual std::string name(void) const = 0;
53 virtual void read(const GFitsHDU* hdu) = 0; 54 virtual void read(const GFitsHDU* hdu) = 0;
54 virtual void write(GFitsHDU* hdu) const = 0; 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 // Virtual methods 60 // Virtual methods
63 virtual std::string coordsys(void) const; 61 virtual std::string coordsys(void) const;
pyext/GSkymap.i
@@ -127,34 +127,30 @@ public: @@ -127,34 +127,30 @@ public:
127 GSkymap(const GSkymap& map); 127 GSkymap(const GSkymap& map);
128 virtual ~GSkymap(void); 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 // Methods 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,14 +53,12 @@ public:
53 virtual std::string name(void) const = 0; 53 virtual std::string name(void) const = 0;
54 54
55 // Implemented virtual methods 55 // Implemented virtual methods
  56 + virtual int size(void) const;
56 virtual void read(const GFitsHDU* hdu); 57 virtual void read(const GFitsHDU* hdu);
57 virtual void write(GFitsHDU* hdu) const; 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 // Other methods 63 // Other methods
66 void set(const std::string& coords, 64 void set(const std::string& coords,
src/model/GModelSpatialDiffuseCube.cpp
@@ -446,15 +446,15 @@ GSkyDir GModelSpatialDiffuseCube::mc(const GEnergy&amp; energy, @@ -446,15 +446,15 @@ GSkyDir GModelSpatialDiffuseCube::mc(const GEnergy&amp; 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 // Randomize pixel 452 // Randomize pixel
453 pixel.x(pixel.x() + ran.uniform() - 0.5); 453 pixel.x(pixel.x() + ran.uniform() - 0.5);
454 pixel.y(pixel.y() + ran.uniform() - 0.5); 454 pixel.y(pixel.y() + ran.uniform() - 0.5);
455 455
456 // Get sky direction 456 // Get sky direction
457 - dir = m_cube.xy2dir(pixel); 457 + dir = m_cube.pix2dir(pixel);
458 458
459 } // endif: there were pixels in sky map 459 } // endif: there were pixels in sky map
460 460
src/model/GModelSpatialDiffuseMap.cpp
@@ -350,15 +350,15 @@ GSkyDir GModelSpatialDiffuseMap::mc(const GEnergy&amp; energy, @@ -350,15 +350,15 @@ GSkyDir GModelSpatialDiffuseMap::mc(const GEnergy&amp; 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 // Randomize pixel 356 // Randomize pixel
357 pixel.x(pixel.x() + ran.uniform() - 0.5); 357 pixel.x(pixel.x() + ran.uniform() - 0.5);
358 pixel.y(pixel.y() + ran.uniform() - 0.5); 358 pixel.y(pixel.y() + ran.uniform() - 0.5);
359 359
360 // Get sky direction 360 // Get sky direction
361 - dir = m_map.xy2dir(pixel); 361 + dir = m_map.pix2dir(pixel);
362 362
363 } // endif: there were pixels in sky map 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,27 +350,14 @@ void GHealpix::write(GFitsHDU* hdu) const
350 /***********************************************************************//** 350 /***********************************************************************//**
351 * @brief Returns solid angle of pixel 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 // Return solid angle 362 // Return solid angle
376 return m_omega; 363 return m_omega;
@@ -380,28 +367,35 @@ double GHealpix::omega(const GSkyPixel&amp; pix) const @@ -380,28 +367,35 @@ double GHealpix::omega(const GSkyPixel&amp; pix) const
380 /***********************************************************************//** 367 /***********************************************************************//**
381 * @brief Returns sky direction of pixel 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 // Perform ordering dependent conversion 383 // Perform ordering dependent conversion
  384 + double theta = 0.0;
  385 + double phi = 0.0;
393 switch (m_ordering) { 386 switch (m_ordering) {
394 case 0: 387 case 0:
395 - pix2ang_ring(pix, &theta, &phi); 388 + pix2ang_ring(int(pixel), &theta, &phi);
396 break; 389 break;
397 case 1: 390 case 1:
398 - pix2ang_nest(pix, &theta, &phi); 391 + pix2ang_nest(int(pixel), &theta, &phi);
399 break; 392 break;
400 default: 393 default:
401 break; 394 break;
402 } 395 }
403 396
404 // Store coordinate system dependent result 397 // Store coordinate system dependent result
  398 + GSkyDir result;
405 switch (m_coordsys) { 399 switch (m_coordsys) {
406 case 0: 400 case 0:
407 result.radec(phi, gammalib::pihalf - theta); 401 result.radec(phi, gammalib::pihalf - theta);
@@ -412,25 +406,23 @@ GSkyDir GHealpix::pix2dir(const int&amp; pix) const @@ -412,25 +406,23 @@ GSkyDir GHealpix::pix2dir(const int&amp; pix) const
412 default: 406 default:
413 break; 407 break;
414 } 408 }
415 -  
416 - // Return result 409 +
  410 + // Return
417 return result; 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 double z; 424 double z;
431 double phi; 425 double phi;
432 -  
433 - // Compute coordinate system dependent (z,phi)  
434 switch (m_coordsys) { 426 switch (m_coordsys) {
435 case 0: 427 case 0:
436 z = cos(gammalib::pihalf - dir.dec()); 428 z = cos(gammalib::pihalf - dir.dec());
@@ -445,75 +437,20 @@ int GHealpix::dir2pix(const GSkyDir&amp; dir) const @@ -445,75 +437,20 @@ int GHealpix::dir2pix(const GSkyDir&amp; dir) const
445 } 437 }
446 438
447 // Perform ordering dependent conversion 439 // Perform ordering dependent conversion
  440 + int index;
448 switch (m_ordering) { 441 switch (m_ordering) {
449 case 0: 442 case 0:
450 - pix = ang2pix_z_phi_ring(z, phi); 443 + index = ang2pix_z_phi_ring(z, phi);
451 break; 444 break;
452 case 1: 445 case 1:
453 - pix = ang2pix_z_phi_nest(z, phi); 446 + index = ang2pix_z_phi_nest(z, phi);
454 break; 447 break;
455 default: 448 default:
456 break; 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,13 +46,13 @@
46 #define G_OP_ACCESS_1D "GSkymap::operator(int&, int&)" 46 #define G_OP_ACCESS_1D "GSkymap::operator(int&, int&)"
47 #define G_OP_ACCESS_2D "GSkymap::operator(GSkyPixel&, int&)" 47 #define G_OP_ACCESS_2D "GSkymap::operator(GSkyPixel&, int&)"
48 #define G_OP_VALUE "GSkymap::operator(GSkyDir&, int&)" 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 #define G_DIR2PIX "GSkymap::dir2pix(GSkyDir&)" 52 #define G_DIR2PIX "GSkymap::dir2pix(GSkyDir&)"
52 -#define G_XY2DIR "GSkymap::xy2dir(GSkyPixel&)"  
53 -#define G_DIR2XY "GSkymap::dir2xy(GSkyDir&)"  
54 #define G_OMEGA1 "GSkymap::omega(int&)" 53 #define G_OMEGA1 "GSkymap::omega(int&)"
55 #define G_OMEGA2 "GSkymap::omega(GSkyPixel&)" 54 #define G_OMEGA2 "GSkymap::omega(GSkyPixel&)"
  55 +#define G_READ "GSkymap::read(const GFitsHDU*)"
56 #define G_SET_WCS "GSkymap::set_wcs(std::string&, std::string&, double&,"\ 56 #define G_SET_WCS "GSkymap::set_wcs(std::string&, std::string&, double&,"\
57 " double&, double&, double&, double&, double&,"\ 57 " double&, double&, double&, double&, double&,"\
58 " GMatrix&, GVector&)" 58 " GMatrix&, GVector&)"
@@ -260,72 +260,104 @@ GSkymap::~GSkymap(void) @@ -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 * @exception GException::out_of_range 296 * @exception GException::out_of_range
269 * Pixel index and/or map index are outside valid range. 297 * Pixel index and/or map index are outside valid range.
270 * 298 *
271 * Access sky map pixel by its index, where the most quickly varying axis is 299 * Access sky map pixel by its index, where the most quickly varying axis is
272 * the x axis of the map. 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 // Throw an error if pixel index or map index is not in valid range 304 // Throw an error if pixel index or map index is not in valid range
279 #if defined(G_RANGE_CHECK) 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 if (map < 0 || map >= m_num_maps) { 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 #endif 316 #endif
287 317
288 // Return reference to pixel value 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 * @exception GException::out_of_range 329 * @exception GException::out_of_range
300 * Pixel index and/or map index are outside valid range. 330 * Pixel index and/or map index are outside valid range.
301 * 331 *
302 * Access sky map pixel by its index, where the most quickly varying axis is 332 * Access sky map pixel by its index, where the most quickly varying axis is
303 * the x axis of the map. 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 // Throw an error if pixel index or map index is not in valid range 337 // Throw an error if pixel index or map index is not in valid range
310 #if defined(G_RANGE_CHECK) 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 if (map < 0 || map >= m_num_maps) { 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 #endif 349 #endif
318 350
319 // Return reference to pixel value 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 * @exception GException::out_of_range 362 * @exception GException::out_of_range
331 * Sky pixel and/or map index are outside valid range. 363 * Sky pixel and/or map index are outside valid range.
@@ -335,7 +367,7 @@ const double&amp; GSkymap::operator() (const int&amp; pixel, const int&amp; map) const @@ -335,7 +367,7 @@ const double&amp; GSkymap::operator() (const int&amp; pixel, const int&amp; map) const
335 * 367 *
336 * @todo Implement proper skymap exception (actual is for matrix elements) 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 // Throw an error if pixel index or map index is not in valid range 372 // Throw an error if pixel index or map index is not in valid range
341 #if defined(G_RANGE_CHECK) 373 #if defined(G_RANGE_CHECK)
@@ -345,12 +377,14 @@ double&amp; GSkymap::operator() (const GSkyPixel&amp; pixel, const int&amp; map) @@ -345,12 +377,14 @@ double&amp; GSkymap::operator() (const GSkyPixel&amp; pixel, const int&amp; map)
345 m_num_x-1, m_num_y-1); 377 m_num_x-1, m_num_y-1);
346 } 378 }
347 if (map < 0 || map >= m_num_maps) { 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 #endif 384 #endif
351 385
352 // Get pixel index 386 // Get pixel index
353 - int index = xy2pix(pixel); 387 + int index = pix2inx(pixel);
354 388
355 // Return reference to pixel value 389 // Return reference to pixel value
356 return m_pixels[index+m_num_pixels*map]; 390 return m_pixels[index+m_num_pixels*map];
@@ -358,10 +392,10 @@ double&amp; GSkymap::operator() (const GSkyPixel&amp; pixel, const int&amp; map) @@ -358,10 +392,10 @@ double&amp; GSkymap::operator() (const GSkyPixel&amp; pixel, const int&amp; 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 * @exception GException::out_of_range 400 * @exception GException::out_of_range
367 * Sky pixel and/or map index are outside valid range. 401 * Sky pixel and/or map index are outside valid range.
@@ -381,12 +415,14 @@ const double&amp; GSkymap::operator()(const GSkyPixel&amp; pixel, const int&amp; map) const @@ -381,12 +415,14 @@ const double&amp; GSkymap::operator()(const GSkyPixel&amp; pixel, const int&amp; map) const
381 m_num_x-1, m_num_y-1); 415 m_num_x-1, m_num_y-1);
382 } 416 }
383 if (map < 0 || map >= m_num_maps) { 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 #endif 422 #endif
387 423
388 // Get pixel index 424 // Get pixel index
389 - int index = xy2pix(pixel); 425 + int index = pix2inx(pixel);
390 426
391 // Return reference to pixel value 427 // Return reference to pixel value
392 return m_pixels[index+m_num_pixels*map]; 428 return m_pixels[index+m_num_pixels*map];
@@ -397,7 +433,7 @@ const double&amp; GSkymap::operator()(const GSkyPixel&amp; pixel, const int&amp; map) const @@ -397,7 +433,7 @@ const double&amp; GSkymap::operator()(const GSkyPixel&amp; pixel, const int&amp; map) const
397 * @brief Return interpolated skymap value for sky direction 433 * @brief Return interpolated skymap value for sky direction
398 * 434 *
399 * @param[in] dir Sky direction. 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 * @exception GException::out_of_range 438 * @exception GException::out_of_range
403 * Map index lies outside valid range. 439 * Map index lies outside valid range.
@@ -406,12 +442,14 @@ const double&amp; GSkymap::operator()(const GSkyPixel&amp; pixel, const int&amp; map) const @@ -406,12 +442,14 @@ const double&amp; GSkymap::operator()(const GSkyPixel&amp; pixel, const int&amp; map) const
406 * interpolation of the neighbouring pixels. If the sky direction falls 442 * interpolation of the neighbouring pixels. If the sky direction falls
407 * outside the area covered by the skymap, a value of 0 is returned. 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 // Throw an error if the map index is not in valid range 447 // Throw an error if the map index is not in valid range
412 #if defined(G_RANGE_CHECK) 448 #if defined(G_RANGE_CHECK)
413 if (map < 0 || map >= m_num_maps) { 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 #endif 454 #endif
417 455
@@ -419,7 +457,7 @@ double GSkymap::operator() (const GSkyDir&amp; dir, const int&amp; map) const @@ -419,7 +457,7 @@ double GSkymap::operator() (const GSkyDir&amp; dir, const int&amp; map) const
419 double intensity = 0.0; 457 double intensity = 0.0;
420 458
421 // Determine sky pixel 459 // Determine sky pixel
422 - GSkyPixel pixel = dir2xy(dir); 460 + GSkyPixel pixel = dir2pix(dir);
423 461
424 // Continue only if pixel is within the map 462 // Continue only if pixel is within the map
425 if (contains(pixel)) { 463 if (contains(pixel)) {
@@ -476,32 +514,6 @@ double GSkymap::operator() (const GSkyDir&amp; dir, const int&amp; map) const @@ -476,32 +514,6 @@ double GSkymap::operator() (const GSkyDir&amp; dir, const int&amp; 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 = Public methods = 519 = Public methods =
@@ -511,7 +523,7 @@ GSkymap&amp; GSkymap::operator= (const GSkymap&amp; map) @@ -511,7 +523,7 @@ GSkymap&amp; GSkymap::operator= (const GSkymap&amp; map)
511 /***********************************************************************//** 523 /***********************************************************************//**
512 * @brief Clear instance. 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 void GSkymap::clear(void) 528 void GSkymap::clear(void)
517 { 529 {
@@ -527,7 +539,9 @@ void GSkymap::clear(void) @@ -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 GSkymap* GSkymap::clone(void) const 546 GSkymap* GSkymap::clone(void) const
533 { 547 {
@@ -535,6 +549,368 @@ GSkymap* GSkymap::clone(void) const @@ -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 * @brief Load skymap from FITS file. 916 * @brief Load skymap from FITS file.
@@ -544,6 +920,9 @@ GSkymap* GSkymap::clone(void) const @@ -544,6 +920,9 @@ GSkymap* GSkymap::clone(void) const
544 * Loads HEALPix and non HEALPix skymaps. First searches for HEALPix map in 920 * Loads HEALPix and non HEALPix skymaps. First searches for HEALPix map in
545 * FITS file by scanning all HDUs for PIXTYPE=HEALPIX. If no HEALPix map has 921 * FITS file by scanning all HDUs for PIXTYPE=HEALPIX. If no HEALPix map has
546 * been found then search load first non-empty image. 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 void GSkymap::load(const std::string& filename) 927 void GSkymap::load(const std::string& filename)
549 { 928 {
@@ -568,16 +947,12 @@ void GSkymap::load(const std::string&amp; filename) @@ -568,16 +947,12 @@ void GSkymap::load(const std::string&amp; filename)
568 947
569 // Get pointer to HDU 948 // Get pointer to HDU
570 hdu = fits.hdu(extno); 949 hdu = fits.hdu(extno);
571 - 950 +
572 // If PIXTYPE keyword equals "HEALPIX" then load map 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 } // endfor: looped over HDUs 958 } // endfor: looped over HDUs
@@ -597,7 +972,7 @@ void GSkymap::load(const std::string&amp; filename) @@ -597,7 +972,7 @@ void GSkymap::load(const std::string&amp; filename)
597 } 972 }
598 973
599 // Load WCS map 974 // Load WCS map
600 - read_wcs(static_cast<const GFitsImageDouble*>(hdu)); 975 + read_wcs(static_cast<const GFitsImage*>(hdu));
601 loaded = true; 976 loaded = true;
602 break; 977 break;
603 978
@@ -674,14 +1049,10 @@ void GSkymap::read(const GFitsHDU* hdu) @@ -674,14 +1049,10 @@ void GSkymap::read(const GFitsHDU* hdu)
674 // Initialize load flag 1049 // Initialize load flag
675 bool loaded = false; 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 // ... otherwise try loading as non HEALPix map 1058 // ... otherwise try loading as non HEALPix map
@@ -689,7 +1060,7 @@ void GSkymap::read(const GFitsHDU* hdu) @@ -689,7 +1060,7 @@ void GSkymap::read(const GFitsHDU* hdu)
689 1060
690 // Load only if HDU contains an image 1061 // Load only if HDU contains an image
691 if (hdu->exttype() == 0) { 1062 if (hdu->exttype() == 0) {
692 - read_wcs(static_cast<const GFitsImageDouble*>(hdu)); 1063 + read_wcs(static_cast<const GFitsImage*>(hdu));
693 loaded = true; 1064 loaded = true;
694 } 1065 }
695 1066
@@ -741,332 +1112,6 @@ void GSkymap::write(GFits* file) const @@ -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 * @brief Print sky map 1115 * @brief Print sky map
1071 * 1116 *
1072 * @param[in] chatter Chattiness (defaults to NORMAL). 1117 * @param[in] chatter Chattiness (defaults to NORMAL).
@@ -1088,7 +1133,7 @@ std::string GSkymap::print(const GChatter&amp; chatter) const @@ -1088,7 +1133,7 @@ std::string GSkymap::print(const GChatter&amp; chatter) const
1088 result.append(gammalib::str(m_num_pixels)); 1133 result.append(gammalib::str(m_num_pixels));
1089 result.append("\n"+gammalib::parformat("Number of maps")); 1134 result.append("\n"+gammalib::parformat("Number of maps"));
1090 result.append(gammalib::str(m_num_maps)); 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 result.append("\n"+gammalib::parformat("X axis dimension")); 1137 result.append("\n"+gammalib::parformat("X axis dimension"));
1093 result.append(gammalib::str(m_num_x)); 1138 result.append(gammalib::str(m_num_x));
1094 result.append("\n"+gammalib::parformat("Y axis dimension")); 1139 result.append("\n"+gammalib::parformat("Y axis dimension"));
@@ -1181,7 +1226,7 @@ void GSkymap::copy_members(const GSkymap&amp; map) @@ -1181,7 +1226,7 @@ void GSkymap::copy_members(const GSkymap&amp; map)
1181 // Copy pixels 1226 // Copy pixels
1182 if (size > 0 && map.m_pixels != NULL) { 1227 if (size > 0 && map.m_pixels != NULL) {
1183 alloc_pixels(); 1228 alloc_pixels();
1184 - for (int i = 0; i < size; ++i) { 1229 + for (int i = 0; i < size; ++i) {
1185 m_pixels[i] = map.m_pixels[i]; 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,35 +436,9 @@ void GWcs::write(GFitsHDU* hdu) const
436 /***********************************************************************//** 436 /***********************************************************************//**
437 * @brief Returns solid angle of pixel in units of steradians 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 * corners. The surface is computed using a cartesian approximation: 442 * corners. The surface is computed using a cartesian approximation:
469 * a 443 * a
470 * 1-----5-----2 a+b 444 * 1-----5-----2 a+b
@@ -475,15 +449,15 @@ double GWcs::omega(const int&amp; pix) const @@ -475,15 +449,15 @@ double GWcs::omega(const int&amp; pix) const
475 * rotated sky maps. Something more intelligent should be implemented in 449 * rotated sky maps. Something more intelligent should be implemented in
476 * the future. 450 * the future.
477 ***************************************************************************/ 451 ***************************************************************************/
478 -double GWcs::omega(const GSkyPixel& pix) const 452 +double GWcs::omega(const GSkyPixel& pixel) const
479 { 453 {
480 // Get the sky directions of the 6 points 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 // Compute distances between sky directions 462 // Compute distances between sky directions
489 double a = dir1.dist(dir2); 463 double a = dir1.dist(dir2);
@@ -499,64 +473,16 @@ double GWcs::omega(const GSkyPixel&amp; pix) const @@ -499,64 +473,16 @@ double GWcs::omega(const GSkyPixel&amp; 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 // Allocate memory for transformation 487 // Allocate memory for transformation
562 double pixcrd[2]; 488 double pixcrd[2];
@@ -568,8 +494,8 @@ GSkyDir GWcs::xy2dir(const GSkyPixel&amp; pix) const @@ -568,8 +494,8 @@ GSkyDir GWcs::xy2dir(const GSkyPixel&amp; pix) const
568 494
569 // Set sky pixel. We have to add 1.0 here as the WCS pixel reference 495 // Set sky pixel. We have to add 1.0 here as the WCS pixel reference
570 // (CRPIX) starts from one while GSkyPixel starts from 0. 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 // Trasform pixel-to-world coordinate 500 // Trasform pixel-to-world coordinate
575 wcs_p2s(1, 2, pixcrd, imgcrd, &phi, &theta, world, &stat); 501 wcs_p2s(1, 2, pixcrd, imgcrd, &phi, &theta, world, &stat);
@@ -585,7 +511,7 @@ GSkyDir GWcs::xy2dir(const GSkyPixel&amp; pix) const @@ -585,7 +511,7 @@ GSkyDir GWcs::xy2dir(const GSkyPixel&amp; pix) const
585 511
586 // Debug: Dump transformation steps 512 // Debug: Dump transformation steps
587 #if defined(G_XY2DIR_DEBUG) 513 #if defined(G_XY2DIR_DEBUG)
588 - std::cout << "xy2dir: pixel=" << pix 514 + std::cout << "xy2dir: pixel=" << pixel
589 << " (x,y)=(" << pixcrd[0] << "," << pixcrd[1] << ")" 515 << " (x,y)=(" << pixcrd[0] << "," << pixcrd[1] << ")"
590 << " (phi,theta)=(" << phi << "," << theta << ")" 516 << " (phi,theta)=(" << phi << "," << theta << ")"
591 << " (lng,lat)=(" << world[0] << "," << world[1] << ")" << std::endl; 517 << " (lng,lat)=(" << world[0] << "," << world[1] << ")" << std::endl;
@@ -597,14 +523,16 @@ GSkyDir GWcs::xy2dir(const GSkyPixel&amp; pix) const @@ -597,14 +523,16 @@ GSkyDir GWcs::xy2dir(const GSkyPixel&amp; 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 * @param[in] dir Sky direction. 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 // Allocate memory for transformation 537 // Allocate memory for transformation
610 double pixcrd[2]; 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&amp; crpix1, @@ -106,10 +106,10 @@ double TestGSky::wcs_forth_back_pixel(GWcs* wcs, int nx, int ny, double&amp; crpix1,
106 GSkyPixel pix_in(x,y); 106 GSkyPixel pix_in(x,y);
107 107
108 // Forth: Transform to world 108 // Forth: Transform to world
109 - GSkyDir dir = wcs->xy2dir(pix_in); 109 + GSkyDir dir = wcs->pix2dir(pix_in);
110 110
111 // Back: Transform to pixel 111 // Back: Transform to pixel
112 - GSkyPixel pix_out = wcs->dir2xy(dir); 112 + GSkyPixel pix_out = wcs->dir2pix(dir);
113 113
114 // Compute distance 114 // Compute distance
115 double dx = pix_in.x()-pix_out.x(); 115 double dx = pix_in.x()-pix_out.x();
@@ -177,7 +177,7 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double&amp; crpix1, double&amp; crp @@ -177,7 +177,7 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double&amp; crpix1, double&amp; crp
177 for (int iy = -ny; iy <= ny; ++iy) { 177 for (int iy = -ny; iy <= ny; ++iy) {
178 178
179 // Set y value 179 // Set y value
180 - double y = double(iy) + crpix2; 180 + double y = double(iy) + crpix2;
181 181
182 // Skip pixels outside valid range (they are not expected to 182 // Skip pixels outside valid range (they are not expected to
183 // transform bijectively) 183 // transform bijectively)
@@ -189,8 +189,8 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double&amp; crpix1, double&amp; crp @@ -189,8 +189,8 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double&amp; crpix1, double&amp; crp
189 GSkyPixel pix_in(x,y); 189 GSkyPixel pix_in(x,y);
190 190
191 // Transform to world 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 double angle = dir1.dist_deg(dir2); 194 double angle = dir1.dist_deg(dir2);
195 if (angle > angle_max) { 195 if (angle > angle_max) {
196 angle_max = angle; 196 angle_max = angle;
@@ -207,8 +207,8 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double&amp; crpix1, double&amp; crp @@ -207,8 +207,8 @@ double TestGSky::wcs_copy(GWcs* wcs, int nx, int ny, double&amp; crpix1, double&amp; crp
207 #endif 207 #endif
208 208
209 // Transform to pixel 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 // Compute distance 213 // Compute distance
214 double dx = pix_out1.x()-pix_out2.x(); 214 double dx = pix_out1.x()-pix_out2.x();
@@ -715,8 +715,8 @@ void TestGSky::test_GSkymap_wcs_construct(void) @@ -715,8 +715,8 @@ void TestGSky::test_GSkymap_wcs_construct(void)
715 for (int l = -180; l < 180; ++l) { 715 for (int l = -180; l < 180; ++l) {
716 for (int b = -90; b < 90; ++b) { 716 for (int b = -90; b < 90; ++b) {
717 dir.lb_deg(double(l),double(b)); 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 double dist = dir.dist_deg(dir_back); 720 double dist = dir.dist_deg(dir_back);
721 if (dist > eps) { 721 if (dist > eps) {
722 throw exception_failure("Sky direction differs: dir="+dir.print()+" pixel="+pixel.print()+" dir_back"+ dir_back.print()+" dist="+gammalib::str(dist)+" deg"); 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,10 +73,11 @@ class Test(GPythonTestSuite):
73 # Append tests 73 # Append tests
74 self.append(self.test_skymap_healpix, "Test HEALPix map") 74 self.append(self.test_skymap_healpix, "Test HEALPix map")
75 self.append(self.test_skymap_ait, "Test AIT projection map") 75 self.append(self.test_skymap_ait, "Test AIT projection map")
  76 + self.append(self.test_skymap_azp, "Test AZP projection map")
76 self.append(self.test_skymap_car, "Test CAR projection map") 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 self.append(self.test_skymap_stg, "Test STG projection map") 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 self.append(self.test_fk5_to_galactic, "Test FK5 to Galactic coordinate conversion") 81 self.append(self.test_fk5_to_galactic, "Test FK5 to Galactic coordinate conversion")
81 82
82 # Return 83 # Return
@@ -87,21 +88,21 @@ class Test(GPythonTestSuite): @@ -87,21 +88,21 @@ class Test(GPythonTestSuite):
87 """ 88 """
88 Control coordinate and pixel transformation methods. 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 for i in range(pixels.npix()): 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 "), RA=" + str(dir.ra() * 180 / pi) + ", Dec=" + str(dir.dec() * 180 / pi) 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 # Control SkyDir coordinate transformation for all pixels 100 # Control SkyDir coordinate transformation for all pixels
100 for i in range(pixels.npix()): 101 for i in range(pixels.npix()):
101 - dir = pixels.pix2dir(i) 102 + dir = pixels.inx2dir(i)
102 dir_new = GSkyDir() 103 dir_new = GSkyDir()
103 dir_new.lb(dir.l(), dir.b()) 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 if (dra >= 5.0): 106 if (dra >= 5.0):
106 dra -= 2.0 * pi 107 dra -= 2.0 * pi
107 ddec = abs(dir.dec() - dir_new.dec()) 108 ddec = abs(dir.dec() - dir_new.dec())
@@ -196,6 +197,17 @@ class Test(GPythonTestSuite): @@ -196,6 +197,17 @@ class Test(GPythonTestSuite):
196 # Return 197 # Return
197 return 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 # Test CAR projection 211 # Test CAR projection
200 def test_skymap_car(self): 212 def test_skymap_car(self):
201 """ 213 """
@@ -207,13 +219,13 @@ class Test(GPythonTestSuite): @@ -207,13 +219,13 @@ class Test(GPythonTestSuite):
207 # Return 219 # Return
208 return 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 # Execute generic test 227 # Execute generic test
216 - self.test_skymap_proj("TAN") 228 + self.test_skymap_proj("MER")
217 229
218 # Return 230 # Return
219 return 231 return
@@ -229,13 +241,13 @@ class Test(GPythonTestSuite): @@ -229,13 +241,13 @@ class Test(GPythonTestSuite):
229 # Return 241 # Return
230 return 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 # Execute generic test 249 # Execute generic test
238 - self.test_skymap_proj("AZP") 250 + self.test_skymap_proj("TAN")
239 251
240 # Return 252 # Return
241 return 253 return