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