Commit e47ea36954eda1ba469477b4662a1864b8f620f9

Authored by Jürgen Knödlseder
1 parent e9d77e48

Add ARC WCS projection (#2541)

ChangeLog
1 -2018-07-03 1 +2018-07-30
2 2
3 * Version 1.6.0 released 3 * Version 1.6.0 released
4 ======================== 4 ========================
5 5
  6 + Add ARC WCS projection (#2541)
6 Add GLog::buffer() method. 7 Add GLog::buffer() method.
7 Renamed GPhoton::mcid() to GPhoton::mc_id() 8 Renamed GPhoton::mcid() to GPhoton::mc_id()
8 Remove at() methods from Python interface (#2515) 9 Remove at() methods from Python interface (#2515)
1 New Features and Important Changes in GammaLib 1.6.0 1 New Features and Important Changes in GammaLib 1.6.0
2 2
3 -5 July 2018 3 +30 July 2018
4 4
5 5
6 1. Introduction 6 1. Introduction
@@ -13,6 +13,7 @@ made since the last release of GammaLib. @@ -13,6 +13,7 @@ made since the last release of GammaLib.
13 --------------------------------- 13 ---------------------------------
14 The following classes have been added: 14 The following classes have been added:
15 - GModelSpectralExponential 15 - GModelSpectralExponential
  16 +- GWcsARC
16 17
17 The following classes have been removed: 18 The following classes have been removed:
18 - none 19 - none
@@ -205,6 +206,10 @@ None @@ -205,6 +206,10 @@ None
205 206
206 12. Sky module 207 12. Sky module
207 -------------- 208 --------------
  209 +The class GWcsARC was added to handle ARC WCS projections (#2541). In addition
  210 +the private GWcs::prj_bchk() method was added to implement boundary checking
  211 +similar to the checking done in WCS.
  212 +
208 A precomputation cache was added to the GWcs::dir2pix() and GWcs::pix2dir() 213 A precomputation cache was added to the GWcs::dir2pix() and GWcs::pix2dir()
209 methods so that results are not recomputed for the same arguments. This should 214 methods so that results are not recomputed for the same arguments. This should
210 provide some speed-up as it avoids unnecessary coordinate transformations. 215 provide some speed-up as it avoids unnecessary coordinate transformations.
doc/source/admin/release_history/1.6.rst
@@ -34,6 +34,8 @@ Bug fixes @@ -34,6 +34,8 @@ Bug fixes
34 Improvements 34 Improvements
35 ------------ 35 ------------
36 36
  37 +* [`2541 <https://cta-redmine.irap.omp.eu/issues/2541>`_] -
  38 + Add ``ARC`` WCS projection.
37 * Add ``GLog::buffer()`` method 39 * Add ``GLog::buffer()`` method
38 * Renamed ``GPhoton::mcid()`` to ``GPhoton::mc_id()`` 40 * Renamed ``GPhoton::mcid()`` to ``GPhoton::mc_id()``
39 * [`2513 <https://cta-redmine.irap.omp.eu/issues/2513>`_] - 41 * [`2513 <https://cta-redmine.irap.omp.eu/issues/2513>`_] -
include/GWcs.hpp
@@ -146,6 +146,13 @@ protected: @@ -146,6 +146,13 @@ protected:
146 // Methods adapted from wcslib::prj.c 146 // Methods adapted from wcslib::prj.c
147 void prj_ini(void) const; 147 void prj_ini(void) const;
148 void prj_off(const double& phi0, const double& theta0) const; 148 void prj_off(const double& phi0, const double& theta0) const;
  149 + int prj_bchk(const double& tol,
  150 + const int& nphi,
  151 + const int& ntheta,
  152 + const int& spt,
  153 + double* phi,
  154 + double* theta,
  155 + int* stat) const;
149 virtual void prj_set(void) const = 0; 156 virtual void prj_set(void) const = 0;
150 virtual void prj_x2s(int nx, int ny, int sxy, int spt, 157 virtual void prj_x2s(int nx, int ny, int sxy, int spt,
151 const double* x, const double* y, 158 const double* x, const double* y,
include/GWcsARC.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * GWcsARC.hpp - Zenithal/azimuthal equidistant (ARC) projection class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2018 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GWcsARC.hpp
  23 + * @brief Zenithal/azimuthal equidistant (ARC) projection class definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef GWCSARC_HPP
  28 +#define GWCSARC_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include <string>
  32 +#include "GWcs.hpp"
  33 +
  34 +
  35 +/***********************************************************************//**
  36 + * @class GWcsARC
  37 + *
  38 + * @brief Zenithal/azimuthal equidistant (ARC) projection class definition
  39 + *
  40 + * This class implements the Zenithal/azimuthal equidistant projection for
  41 + * the World Coordinate System.
  42 + ***************************************************************************/
  43 +class GWcsARC : public GWcs {
  44 +
  45 +public:
  46 + // Constructors and destructors
  47 + GWcsARC(void);
  48 + GWcsARC(const std::string& coords,
  49 + const double& crval1, const double& crval2,
  50 + const double& crpix1, const double& crpix2,
  51 + const double& cdelt1, const double& cdelt2);
  52 + GWcsARC(const GWcsARC& wcs);
  53 + virtual ~GWcsARC(void);
  54 +
  55 + // Operators
  56 + GWcsARC& operator=(const GWcsARC& wcs);
  57 +
  58 + // Implemented pure virtual base class methods
  59 + virtual void clear(void);
  60 + virtual GWcsARC* clone(void) const;
  61 + virtual std::string classname(void) const;
  62 + virtual std::string code(void) const;
  63 + virtual std::string name(void) const;
  64 + virtual std::string print(const GChatter& chatter = NORMAL) const;
  65 +
  66 +private:
  67 + // Private methods
  68 + void init_members(void);
  69 + void copy_members(const GWcsARC& wcs);
  70 + void free_members(void);
  71 + void prj_set(void) const;
  72 + void prj_x2s(int nx, int ny, int sxy, int spt,
  73 + const double* x, const double* y,
  74 + double* phi, double* theta, int* stat) const;
  75 + void prj_s2x(int nphi, int ntheta, int spt, int sxy,
  76 + const double* phi, const double* theta,
  77 + double* x, double* y, int* stat) const;
  78 +};
  79 +
  80 +
  81 +/***********************************************************************//**
  82 + * @brief Return class name
  83 + *
  84 + * @return String containing the class name ("GWcsARC").
  85 + ***************************************************************************/
  86 +inline
  87 +std::string GWcsARC::classname(void) const
  88 +{
  89 + return ("GWcsARC");
  90 +}
  91 +
  92 +
  93 +/***********************************************************************//**
  94 + * @brief Return projection code
  95 + *
  96 + * @return Projection code.
  97 + *
  98 + * Returns the projection code "ARC".
  99 + ***************************************************************************/
  100 +inline
  101 +std::string GWcsARC::code(void) const
  102 +{
  103 + return "ARC";
  104 +}
  105 +
  106 +
  107 +/***********************************************************************//**
  108 + * @brief Return projection name
  109 + *
  110 + * @return Projection name.
  111 + *
  112 + * Returns the projection name.
  113 + ***************************************************************************/
  114 +inline
  115 +std::string GWcsARC::name(void) const
  116 +{
  117 + return "Zenithal/azimuthal equidistant";
  118 +}
  119 +
  120 +#endif /* GWCSARC_HPP */
include/GammaLib.hpp
1 /*************************************************************************** 1 /***************************************************************************
2 * GammaLib.hpp - Gamma-Ray Astronomy Library Header file * 2 * GammaLib.hpp - Gamma-Ray Astronomy Library Header file *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2006-2017 by Juergen Knoedlseder * 4 + * copyright (C) 2006-2018 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
6 * * 6 * *
7 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -155,6 +155,7 @@ @@ -155,6 +155,7 @@
155 #include "GWcsRegistry.hpp" 155 #include "GWcsRegistry.hpp"
156 #include "GWcs.hpp" 156 #include "GWcs.hpp"
157 #include "GWcsAIT.hpp" 157 #include "GWcsAIT.hpp"
  158 +#include "GWcsARC.hpp"
158 #include "GWcsAZP.hpp" 159 #include "GWcsAZP.hpp"
159 #include "GWcsCAR.hpp" 160 #include "GWcsCAR.hpp"
160 #include "GWcsGLS.hpp" 161 #include "GWcsGLS.hpp"
include/Makefile.am
1 ############################################################################# 1 #############################################################################
2 # Makefile.am for include module # 2 # Makefile.am for include module #
3 # ------------------------------------------------------------------------- # 3 # ------------------------------------------------------------------------- #
4 -# Copyright (C) 2016-2017 Juergen Knoedlseder # 4 +# Copyright (C) 2016-2018 Juergen Knoedlseder #
5 # ------------------------------------------------------------------------- # 5 # ------------------------------------------------------------------------- #
6 # # 6 # #
7 # This program is free software: you can redistribute it and/or modify # 7 # This program is free software: you can redistribute it and/or modify #
@@ -117,6 +117,7 @@ pkginclude_HEADERS = GammaLib.hpp \ @@ -117,6 +117,7 @@ pkginclude_HEADERS = GammaLib.hpp \
117 GWcsRegistry.hpp \ 117 GWcsRegistry.hpp \
118 GWcs.hpp \ 118 GWcs.hpp \
119 GWcsAIT.hpp \ 119 GWcsAIT.hpp \
  120 + GWcsARC.hpp \
120 GWcsAZP.hpp \ 121 GWcsAZP.hpp \
121 GWcsCAR.hpp \ 122 GWcsCAR.hpp \
122 GWcsGLS.hpp \ 123 GWcsGLS.hpp \
pyext/GWcsARC.i 0 → 100644
  1 +/***************************************************************************
  2 + * GWcsARC.i - Zenithal/azimuthal equidistant (ARC) projection class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2018 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GWcsARC.i
  23 + * @brief Zenithal/azimuthal equidistant (ARC) projection class definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +%{
  27 +/* Put headers and other declarations here that are needed for compilation */
  28 +#include "GWcsARC.hpp"
  29 +%}
  30 +
  31 +
  32 +/***********************************************************************//**
  33 + * @class GWcsARC
  34 + *
  35 + * @brief Zenithal/azimuthal equidistant (ARC) projection class
  36 + ***************************************************************************/
  37 +class GWcsARC : public GWcs {
  38 +public:
  39 + // Constructors and destructors
  40 + GWcsARC(void);
  41 + GWcsARC(const std::string& coords,
  42 + const double& crval1, const double& crval2,
  43 + const double& crpix1, const double& crpix2,
  44 + const double& cdelt1, const double& cdelt2);
  45 + GWcsARC(const GWcsARC& wcs);
  46 + virtual ~GWcsARC(void);
  47 +
  48 + // Implemented pure virtual methods
  49 + virtual void clear(void);
  50 + virtual GWcsARC* clone(void) const;
  51 + virtual std::string classname(void) const;
  52 + virtual std::string code(void) const;
  53 + virtual std::string name(void) const;
  54 +};
  55 +
  56 +
  57 +/***********************************************************************//**
  58 + * @brief GWcsARC class extension
  59 + ***************************************************************************/
  60 +%extend GWcsARC {
  61 + GWcsARC copy() {
  62 + return (*self);
  63 + }
  64 +};
pyext/gammalib/sky.i
1 /*************************************************************************** 1 /***************************************************************************
2 * sky.i - Sky module * 2 * sky.i - Sky module *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2011-2017 by Jurgen Knodlseder * 4 + * copyright (C) 2011-2018 by Jurgen Knodlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
6 * * 6 * *
7 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -122,6 +122,7 @@ namespace std { @@ -122,6 +122,7 @@ namespace std {
122 %include "GWcsRegistry.i" 122 %include "GWcsRegistry.i"
123 %include "GWcs.i" 123 %include "GWcs.i"
124 %include "GWcsAIT.i" 124 %include "GWcsAIT.i"
  125 +%include "GWcsARC.i"
125 %include "GWcsAZP.i" 126 %include "GWcsAZP.i"
126 %include "GWcsCAR.i" 127 %include "GWcsCAR.i"
127 %include "GWcsGLS.i" 128 %include "GWcsGLS.i"
src/sky/GWcs.cpp
@@ -3090,3 +3090,109 @@ void GWcs::prj_off(const double&amp; phi0, const double&amp; theta0) const @@ -3090,3 +3090,109 @@ void GWcs::prj_off(const double&amp; phi0, const double&amp; theta0) const
3090 // Return 3090 // Return
3091 return; 3091 return;
3092 } 3092 }
  3093 +
  3094 +
  3095 +/***********************************************************************//**
  3096 + * @brief Performs bounds checking on native spherical coordinates
  3097 + *
  3098 + * @param[in] tol Tolerance for the bounds check [deg]
  3099 + * @param[in] nphi Number of bins in phi.
  3100 + * @param[in] ntheta Number of bins in theta.
  3101 + * @param[in] spt Step size.
  3102 + * @param[in,out] phi Pointer to phi array [deg]
  3103 + * @param[in,out] theta Pointer to theta array [deg]
  3104 + * @param[in,out] stat Pointer to status array.
  3105 + *
  3106 + * Performs bounds checking on native spherical coordinates. As returned by
  3107 + * the deprojection (x2s) routines, native longitude is expected to lie in
  3108 + * the closed interval [-180,180], with latitude in [-90,90].
  3109 + *
  3110 + * A tolerance may be specified to provide a small allowance for numerical
  3111 + * imprecision. Values that lie outside the allowed range by not more than
  3112 + * the specified tolerance will be adjusted back into range.
  3113 + *
  3114 + * Code adapted from prj.c::prjbchk().
  3115 + ***************************************************************************/
  3116 +int GWcs::prj_bchk(const double& tol,
  3117 + const int& nphi,
  3118 + const int& ntheta,
  3119 + const int& spt,
  3120 + double* phi,
  3121 + double* theta,
  3122 + int* stat) const
  3123 +{
  3124 + // Initialize result
  3125 + int status = 0;
  3126 +
  3127 + // Continue only if bounds checking is requested
  3128 + if (m_bounds) {
  3129 +
  3130 + // Initialise array pointers
  3131 + register double* phip = phi;
  3132 + register double* thetap = theta;
  3133 + register int* statp = stat;
  3134 +
  3135 + // Loop over all theta bins
  3136 + for (int itheta = 0; itheta < ntheta; ++itheta) {
  3137 +
  3138 + // Loop over all phi bins
  3139 + for (int iphi = 0; iphi < nphi; ++iphi, phip += spt, thetap += spt, statp++) {
  3140 +
  3141 + // Skip values already marked as illegal
  3142 + if (*statp == 0) {
  3143 +
  3144 + // Check lower phi boundary
  3145 + if (*phip < -180.0) {
  3146 + if (*phip < -180.0-tol) {
  3147 + *statp = 1;
  3148 + status = 1;
  3149 + }
  3150 + else {
  3151 + *phip = -180.0;
  3152 + }
  3153 + }
  3154 +
  3155 + // Check upper phi boundary
  3156 + else if (180.0 < *phip) {
  3157 + if (180.0+tol < *phip) {
  3158 + *statp = 1;
  3159 + status = 1;
  3160 + }
  3161 + else {
  3162 + *phip = 180.0;
  3163 + }
  3164 + }
  3165 +
  3166 + // Check lower theta boundary
  3167 + if (*thetap < -90.0) {
  3168 + if (*thetap < -90.0-tol) {
  3169 + *statp = 1;
  3170 + status = 1;
  3171 + }
  3172 + else {
  3173 + *thetap = -90.0;
  3174 + }
  3175 + }
  3176 +
  3177 + // Check upper theta boundary
  3178 + else if (90.0 < *thetap) {
  3179 + if (90.0+tol < *thetap) {
  3180 + *statp = 1;
  3181 + status = 1;
  3182 + }
  3183 + else {
  3184 + *thetap = 90.0;
  3185 + }
  3186 + }
  3187 +
  3188 + } // endif: values were marked as valid
  3189 +
  3190 + } // endfor: looped over phi
  3191 +
  3192 + } // endfor: looped over theta
  3193 +
  3194 + } // endif: bounds checking was requested
  3195 +
  3196 + // Return status
  3197 + return status;
  3198 +}
src/sky/GWcsAIT.cpp
1 /*************************************************************************** 1 /***************************************************************************
2 - * GWcsAIT.cpp - Aitoff (AIT) projection class * 2 + * GWcsAIT.cpp - Zenithal/azimuthal equidistant (AIT) projection class *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2013-2018 by Juergen Knoedlseder * 4 * copyright (C) 2013-2018 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
@@ -306,21 +306,21 @@ void GWcsAIT::prj_set(void) const @@ -306,21 +306,21 @@ void GWcsAIT::prj_set(void) const
306 306
307 // Initialise projection parameters 307 // Initialise projection parameters
308 m_w.assign(4, 0.0); 308 m_w.assign(4, 0.0);
309 - 309 +
310 // Set undefined parameters 310 // Set undefined parameters
311 if (m_r0 == 0.0) { 311 if (m_r0 == 0.0) {
312 m_r0 = gammalib::rad2deg; 312 m_r0 = gammalib::rad2deg;
313 } 313 }
314 - 314 +
315 // Precompute 315 // Precompute
316 m_w[0] = 2.0 * m_r0 * m_r0; 316 m_w[0] = 2.0 * m_r0 * m_r0;
317 m_w[1] = 1.0 / (2.0 * m_w[0]); 317 m_w[1] = 1.0 / (2.0 * m_w[0]);
318 m_w[2] = m_w[1] / 4.0; 318 m_w[2] = m_w[1] / 4.0;
319 m_w[3] = 1.0 / (2.0 * m_r0); 319 m_w[3] = 1.0 / (2.0 * m_r0);
320 - 320 +
321 // Compute fiducial offset 321 // Compute fiducial offset
322 prj_off(0.0, 0.0); 322 prj_off(0.0, 0.0);
323 - 323 +
324 // Return 324 // Return
325 return; 325 return;
326 } 326 }
@@ -381,7 +381,7 @@ void GWcsAIT::prj_x2s(int nx, int ny, int sxy, int spt, @@ -381,7 +381,7 @@ void GWcsAIT::prj_x2s(int nx, int ny, int sxy, int spt,
381 // Initialise status code and statistics 381 // Initialise status code and statistics
382 int status = 0; 382 int status = 0;
383 int n_invalid = 0; 383 int n_invalid = 0;
384 - 384 +
385 // Do x dependence 385 // Do x dependence
386 const double* xp = x; 386 const double* xp = x;
387 int rowoff = 0; 387 int rowoff = 0;
@@ -480,6 +480,11 @@ void GWcsAIT::prj_x2s(int nx, int ny, int sxy, int spt, @@ -480,6 +480,11 @@ void GWcsAIT::prj_x2s(int nx, int ny, int sxy, int spt,
480 throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid); 480 throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid);
481 } 481 }
482 482
  483 + // Do bounds checking on the native coordinates
  484 + // if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) {
  485 + // if (!status) status = PRJERR_BAD_PIX_SET("aitx2s");
  486 + // }
  487 +
483 // Return 488 // Return
484 return; 489 return;
485 } 490 }
@@ -537,7 +542,7 @@ void GWcsAIT::prj_s2x(int nphi, int ntheta, int spt, int sxy, @@ -537,7 +542,7 @@ void GWcsAIT::prj_s2x(int nphi, int ntheta, int spt, int sxy,
537 // Initialise status code and statistics 542 // Initialise status code and statistics
538 int status = 0; 543 int status = 0;
539 int n_invalid = 0; 544 int n_invalid = 0;
540 - 545 +
541 // Do phi dependence 546 // Do phi dependence
542 const double* phip = phi; 547 const double* phip = phi;
543 int rowoff = 0; 548 int rowoff = 0;
@@ -563,7 +568,7 @@ void GWcsAIT::prj_s2x(int nphi, int ntheta, int spt, int sxy, @@ -563,7 +568,7 @@ void GWcsAIT::prj_s2x(int nphi, int ntheta, int spt, int sxy,
563 double* yp = y; 568 double* yp = y;
564 int* statp = stat; 569 int* statp = stat;
565 for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) { 570 for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) {
566 - 571 +
567 // Compute sin(theta) and cos(theta) 572 // Compute sin(theta) and cos(theta)
568 double sinthe; 573 double sinthe;
569 double costhe; 574 double costhe;
@@ -578,12 +583,12 @@ void GWcsAIT::prj_s2x(int nphi, int ntheta, int spt, int sxy, @@ -578,12 +583,12 @@ void GWcsAIT::prj_s2x(int nphi, int ntheta, int spt, int sxy,
578 } // endfor: phi 583 } // endfor: phi
579 584
580 } // endfor: theta 585 } // endfor: theta
581 - 586 +
582 // Handle status code 587 // Handle status code
583 if (status == 4) { 588 if (status == 4) {
584 throw GException::wcs_invalid_phi_theta(G_PRJ_S2X, n_invalid); 589 throw GException::wcs_invalid_phi_theta(G_PRJ_S2X, n_invalid);
585 } 590 }
586 - 591 +
587 // Return 592 // Return
588 return; 593 return;
589 } 594 }
src/sky/GWcsARC.cpp 0 → 100644
  1 +/***************************************************************************
  2 + * GWcsARC.cpp - Zenithal/azimuthal equidistant (ARC) projection class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2018 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GWcsARC.cpp
  23 + * @brief Zenithal/azimuthal equidistant (ARC) projection class implementation
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +/* __ Includes ___________________________________________________________ */
  28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
  31 +#include "GException.hpp"
  32 +#include "GMath.hpp"
  33 +#include "GTools.hpp"
  34 +#include "GWcsARC.hpp"
  35 +#include "GWcsRegistry.hpp"
  36 +
  37 +/* __ Method name definitions ____________________________________________ */
  38 +#define G_PRJ_X2S "GWcsARC::prj_x2s(int, int, int, int, double*, double*,"\
  39 + " double*, double*, int*)"
  40 +#define G_PRJ_S2X "GWcsARC::prj_s2x(int, int, int, int, double*, double*,"\
  41 + " double*, double*, int*)"
  42 +
  43 +/* __ Macros _____________________________________________________________ */
  44 +
  45 +/* __ Coding definitions _________________________________________________ */
  46 +
  47 +/* __ Debug definitions __________________________________________________ */
  48 +
  49 +/* __ Local prototypes ___________________________________________________ */
  50 +
  51 +/* __ Constants __________________________________________________________ */
  52 +
  53 +/* __ Globals ____________________________________________________________ */
  54 +const GWcsARC g_wcs_arc_seed;
  55 +const GWcsRegistry g_wcs_arc_registry(&g_wcs_arc_seed);
  56 +
  57 +
  58 +/*==========================================================================
  59 + = =
  60 + = Constructors/destructors =
  61 + = =
  62 + ==========================================================================*/
  63 +
  64 +/***********************************************************************//**
  65 + * @brief Void constructor
  66 + ***************************************************************************/
  67 +GWcsARC::GWcsARC(void) : GWcs()
  68 +{
  69 + // Initialise class members
  70 + init_members();
  71 +
  72 + // Return
  73 + return;
  74 +}
  75 +
  76 +
  77 +/***********************************************************************//**
  78 + * @brief Constructor
  79 + *
  80 + * @param[in] coords Coordinate system.
  81 + * @param[in] crval1 X value of reference pixel.
  82 + * @param[in] crval2 Y value of reference pixel.
  83 + * @param[in] crpix1 X index of reference pixel (starting from 1).
  84 + * @param[in] crpix2 Y index of reference pixel (starting from 1).
  85 + * @param[in] cdelt1 Increment in x direction at reference pixel [deg].
  86 + * @param[in] cdelt2 Increment in y direction at reference pixel [deg].
  87 + ***************************************************************************/
  88 +GWcsARC::GWcsARC(const std::string& coords,
  89 + const double& crval1, const double& crval2,
  90 + const double& crpix1, const double& crpix2,
  91 + const double& cdelt1, const double& cdelt2) :
  92 + GWcs(coords, crval1, crval2, crpix1, crpix2, cdelt1, cdelt2)
  93 +
  94 +{
  95 + // Initialise class members
  96 + init_members();
  97 +
  98 + // Setup WCS derived parameters
  99 + wcs_set();
  100 +
  101 + // Return
  102 + return;
  103 +}
  104 +
  105 +
  106 +/***********************************************************************//**
  107 + * @brief Copy constructor
  108 + *
  109 + * @param[in] wcs World Coordinate System.
  110 + ***************************************************************************/
  111 +GWcsARC::GWcsARC(const GWcsARC& wcs) : GWcs(wcs)
  112 +{
  113 + // Initialise class members for clean destruction
  114 + init_members();
  115 +
  116 + // Copy members
  117 + copy_members(wcs);
  118 +
  119 + // Return
  120 + return;
  121 +}
  122 +
  123 +
  124 +/***********************************************************************//**
  125 + * @brief Destructor
  126 + ***************************************************************************/
  127 +GWcsARC::~GWcsARC(void)
  128 +{
  129 + // Free members
  130 + free_members();
  131 +
  132 + // Return
  133 + return;
  134 +}
  135 +
  136 +
  137 +/*==========================================================================
  138 + = =
  139 + = Operators =
  140 + = =
  141 + ==========================================================================*/
  142 +
  143 +/***********************************************************************//**
  144 + * @brief Assignment operator
  145 + *
  146 + * @param[in] wcs World Coordinate System.
  147 + * @return World Coordinate System.
  148 + ***************************************************************************/
  149 +GWcsARC& GWcsARC::operator=(const GWcsARC& wcs)
  150 +{
  151 + // Execute only if object is not identical
  152 + if (this != &wcs) {
  153 +
  154 + // Copy base class members
  155 + this->GWcs::operator=(wcs);
  156 +
  157 + // Free members
  158 + free_members();
  159 +
  160 + // Initialise private members for clean destruction
  161 + init_members();
  162 +
  163 + // Copy members
  164 + copy_members(wcs);
  165 +
  166 + } // endif: object was not identical
  167 +
  168 + // Return this object
  169 + return *this;
  170 +}
  171 +
  172 +
  173 +/*==========================================================================
  174 + = =
  175 + = Public methods =
  176 + = =
  177 + ==========================================================================*/
  178 +
  179 +/***********************************************************************//**
  180 + * @brief Clear instance
  181 + *
  182 + * This method properly resets the object to an initial state.
  183 + ***************************************************************************/
  184 +void GWcsARC::clear(void)
  185 +{
  186 + // Free class members (base and derived classes, derived class first)
  187 + free_members();
  188 + this->GWcs::free_members();
  189 + this->GSkyProjection::free_members();
  190 +
  191 + // Initialise members
  192 + this->GSkyProjection::init_members();
  193 + this->GWcs::init_members();
  194 + init_members();
  195 +
  196 + // Return
  197 + return;
  198 +}
  199 +
  200 +
  201 +/***********************************************************************//**
  202 + * @brief Clone instance
  203 + *
  204 + * @return Pointer to deep copy of Zenithal/azimuthal equidistant projection.
  205 + ***************************************************************************/
  206 +GWcsARC* GWcsARC::clone(void) const
  207 +{
  208 + return new GWcsARC(*this);
  209 +}
  210 +
  211 +
  212 +
  213 +/***********************************************************************//**
  214 + * @brief Print WCS information
  215 + *
  216 + * @param[in] chatter Chattiness.
  217 + * @return String containing WCS information.
  218 + ***************************************************************************/
  219 +std::string GWcsARC::print(const GChatter& chatter) const
  220 +{
  221 + // Initialise result string
  222 + std::string result;
  223 +
  224 + // Continue only if chatter is not silent
  225 + if (chatter != SILENT) {
  226 +
  227 + // Append header
  228 + result.append("=== GWcsARC ===");
  229 +
  230 + // Append information
  231 + result.append(wcs_print(chatter));
  232 +
  233 + } // endif: chatter was not silent
  234 +
  235 + // Return result
  236 + return result;
  237 +}
  238 +
  239 +
  240 +/*==========================================================================
  241 + = =
  242 + = Private methods =
  243 + = =
  244 + ==========================================================================*/
  245 +
  246 +/***********************************************************************//**
  247 + * @brief Initialise class members
  248 + ***************************************************************************/
  249 +void GWcsARC::init_members(void)
  250 +{
  251 + // Return
  252 + return;
  253 +}
  254 +
  255 +
  256 +/***********************************************************************//**
  257 + * @brief Copy class members
  258 + *
  259 + * @param[in] wcs World Coordinate System.
  260 + ***************************************************************************/
  261 +void GWcsARC::copy_members(const GWcsARC& wcs)
  262 +{
  263 + // Return
  264 + return;
  265 +}
  266 +
  267 +
  268 +/***********************************************************************//**
  269 + * @brief Delete class members
  270 + ***************************************************************************/
  271 +void GWcsARC::free_members(void)
  272 +{
  273 + // Return
  274 + return;
  275 +}
  276 +
  277 +
  278 +/***********************************************************************//**
  279 + * @brief Setup of projection
  280 + *
  281 + * This method sets up the projection information. The method has been
  282 + * adapted from the wcslib function prj.c::arcset.
  283 + *
  284 + * Given and/or returned:
  285 + * m_r0 Reset to 180/pi if 0.
  286 + * m_phi0 Reset to 0.0 if undefined.
  287 + * m_theta0 Reset to 90.0 if undefined.
  288 + *
  289 + * Returned:
  290 + * m_x0 Fiducial offset in x.
  291 + * m_y0 Fiducial offset in y.
  292 + * m_w[0] r0*(pi/180)
  293 + * m_w[1] (180/pi)/r0
  294 + ***************************************************************************/
  295 +void GWcsARC::prj_set(void) const
  296 +{
  297 + // Signal that projection has been set (needs to be done before calling
  298 + // the prj_off() method to avoid an endless loop)
  299 + m_prjset = true;
  300 +
  301 + // Initialise projection parameters
  302 + m_w.assign(2, 0.0);
  303 +
  304 + // Set undefined parameters
  305 + if (m_r0 == 0.0) {
  306 + m_r0 = gammalib::rad2deg;
  307 + m_w[0] = 1.0;
  308 + m_w[1] = 1.0;
  309 + }
  310 + else {
  311 + m_w[0] = m_r0 * gammalib::deg2rad;
  312 + m_w[1] = 1.0/m_w[0];
  313 + }
  314 +
  315 + // Compute fiducial offset
  316 + prj_off(0.0, 0.0);
  317 +
  318 + // Return
  319 + return;
  320 +}
  321 +
  322 +
  323 +/***********************************************************************//**
  324 + * @brief Pixel-to-spherical deprojection
  325 + *
  326 + * @param[in] nx X vector length.
  327 + * @param[in] ny Y vector length (0=no replication).
  328 + * @param[in] sxy Input vector step.
  329 + * @param[in] spt Output vector step.
  330 + * @param[in] x Vector of projected x coordinates.
  331 + * @param[in] y Vector of projected y coordinates.
  332 + * @param[out] phi Longitude of the projected point in native spherical
  333 + * coordinates [deg].
  334 + * @param[out] theta Latitude of the projected point in native spherical
  335 + * coordinates [deg].
  336 + * @param[out] stat Status return value for each vector element (always 0)
  337 + *
  338 + * @exception GException::wcs_invalid_x_y
  339 + * One or more of the (x,y) coordinates were invalid, as indicated
  340 + * by the stat vector.
  341 + *
  342 + * Deproject pixel (x,y) coordinates in the plane of projection to native
  343 + * spherical coordinates (phi,theta).
  344 + *
  345 + * This method has been adapted from the wcslib function prj.c::aitx2s().
  346 + * The interface follows very closely that of wcslib. In contrast to the
  347 + * wcslib routine, however, the method assumes that the projection has been
  348 + * setup previously (as this will be done by the constructor).
  349 + ***************************************************************************/
  350 +void GWcsARC::prj_x2s(int nx, int ny, int sxy, int spt,
  351 + const double* x, const double* y,
  352 + double* phi, double* theta, int* stat) const
  353 +{
  354 + // Initialize projection if required
  355 + if (!m_prjset) {
  356 + prj_set();
  357 + }
  358 +
  359 + // Set value replication length mx,my
  360 + int mx;
  361 + int my;
  362 + if (ny > 0) {
  363 + mx = nx;
  364 + my = ny;
  365 + }
  366 + else {
  367 + mx = 1;
  368 + my = 1;
  369 + ny = nx;
  370 + }
  371 +
  372 + // Do x dependence
  373 + const double* xp = x;
  374 + int rowoff = 0;
  375 + int rowlen = nx * spt;
  376 + for (int ix = 0; ix < nx; ++ix, rowoff += spt, xp += sxy) {
  377 + double xj = *xp + m_x0;
  378 + double* phip = phi + rowoff;
  379 + for (int iy = 0; iy < my; ++iy, phip += rowlen) {
  380 + *phip = xj;
  381 + }
  382 + }
  383 +
  384 + // Do y dependence
  385 + const double* yp = y;
  386 + double* phip = phi;
  387 + double* thetap = theta;
  388 + int* statp = stat;
  389 + for (int iy = 0; iy < ny; ++iy, yp += sxy) {
  390 + double yj = *yp + m_y0;
  391 + double yj2 = yj * yj;
  392 + for (int ix = 0; ix < mx; ++ix, phip += spt, thetap += spt) {
  393 + double xj = *phip;
  394 + double r = std::sqrt(xj*xj + yj2);
  395 + if (r == 0.0) {
  396 + *phip = 0.0;
  397 + *thetap = 90.0;
  398 + }
  399 + else {
  400 + *phip = gammalib::atan2d(xj, -yj);
  401 + *thetap = 90.0 - r * m_w[1];
  402 + }
  403 + *(statp++) = 0;
  404 + }
  405 + }
  406 +
  407 + // Do boundary checking
  408 + int status = prj_bchk(1.0e-13, nx, my, spt, phi, theta, stat);
  409 +
  410 + // Handle status code
  411 + if (status != 0) {
  412 + std::string msg = "One or more of the (x, y) coordinates were invalid "
  413 + "for the "+name()+" ("+code()+") projection.";
  414 + throw GException::invalid_value(G_PRJ_X2S, msg);
  415 + }
  416 +
  417 + // Return
  418 + return;
  419 +}
  420 +
  421 +
  422 +/***********************************************************************//**
  423 + * @brief Generic spherical-to-pixel projection
  424 + *
  425 + * @param[in] nphi Longitude vector length.
  426 + * @param[in] ntheta Latitude vector length (0=no replication).
  427 + * @param[in] spt Input vector step.
  428 + * @param[in] sxy Output vector step.
  429 + * @param[in] phi Longitude vector of the projected point in native spherical
  430 + * coordinates [deg].
  431 + * @param[in] theta Latitude vector of the projected point in native spherical
  432 + * coordinates [deg].
  433 + * @param[out] x Vector of projected x coordinates.
  434 + * @param[out] y Vector of projected y coordinates.
  435 + * @param[out] stat Status return value for each vector element (always 0)
  436 + *
  437 + * @exception GException::wcs_invalid_phi_theta
  438 + * One or more of the (phi,theta) coordinates were invalid, as
  439 + * indicated by the stat vector.
  440 + *
  441 + * Project native spherical coordinates (phi,theta) to pixel (x,y)
  442 + * coordinates in the plane of projection.
  443 + *
  444 + * This method has been adapted from the wcslib function prj.c::aits2x().
  445 + * The interface follows very closely that of wcslib. In contrast to the
  446 + * wcslib routine, however, the method assumes that the projection has been
  447 + * setup previously (as this will be done by the constructor).
  448 + ***************************************************************************/
  449 +void GWcsARC::prj_s2x(int nphi, int ntheta, int spt, int sxy,
  450 + const double* phi, const double* theta,
  451 + double* x, double* y, int* stat) const
  452 +{
  453 + // Initialize projection if required
  454 + if (!m_prjset) {
  455 + prj_set();
  456 + }
  457 +
  458 + // Set value replication length mphi,mtheta
  459 + int mphi;
  460 + int mtheta;
  461 + if (ntheta > 0) {
  462 + mphi = nphi;
  463 + mtheta = ntheta;
  464 + }
  465 + else {
  466 + mphi = 1;
  467 + mtheta = 1;
  468 + ntheta = nphi;
  469 + }
  470 +
  471 + // Initialise status code and statistics
  472 + //int status = 0;
  473 + //int n_invalid = 0;
  474 +
  475 + // Do phi dependence
  476 + const double* phip = phi;
  477 + int rowoff = 0;
  478 + int rowlen = nphi * sxy;
  479 + for (int iphi = 0; iphi < nphi; ++iphi, rowoff += sxy, phip += spt) {
  480 + double sinphi;
  481 + double cosphi;
  482 + gammalib::sincosd(*phip, &sinphi, &cosphi);
  483 + double* xp = x + rowoff;
  484 + double* yp = y + rowoff;
  485 + for (int itheta = 0; itheta < mtheta; ++itheta) {
  486 + *xp = sinphi;
  487 + *yp = cosphi;
  488 + xp += rowlen;
  489 + yp += rowlen;
  490 + }
  491 + }
  492 +
  493 + // Do theta dependence
  494 + const double* thetap = theta;
  495 + double* xp = x;
  496 + double* yp = y;
  497 + int* statp = stat;
  498 + for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) {
  499 +
  500 + // Compute r
  501 + double r = m_w[0] * (90.0 - *thetap);
  502 +
  503 + // Do phi dependence
  504 + for (int iphi = 0; iphi < mphi; ++iphi, xp += sxy, yp += sxy) {
  505 + *xp = r * (*xp) - m_x0;
  506 + *yp = -r * (*yp) - m_y0;
  507 + *(statp++) = 0;
  508 + } // endfor: phi
  509 +
  510 + } // endfor: theta
  511 +
  512 + // Handle status code
  513 + /*
  514 + if (status == 4) {
  515 + throw GException::wcs_invalid_phi_theta(G_PRJ_S2X, n_invalid);
  516 + }
  517 + */
  518 +
  519 + // Return
  520 + return;
  521 +}
src/sky/GWcsCAR.cpp
@@ -34,6 +34,8 @@ @@ -34,6 +34,8 @@
34 #include "GWcsRegistry.hpp" 34 #include "GWcsRegistry.hpp"
35 35
36 /* __ Method name definitions ____________________________________________ */ 36 /* __ Method name definitions ____________________________________________ */
  37 +#define G_PRJ_X2S "GWcsCAR::prj_x2s(int, int, int, int, double*, double*,"\
  38 + " double*, double*, int*)"
37 39
38 /* __ Macros _____________________________________________________________ */ 40 /* __ Macros _____________________________________________________________ */
39 41
@@ -383,6 +385,16 @@ void GWcsCAR::prj_x2s(int nx, int ny, int sxy, int spt, @@ -383,6 +385,16 @@ void GWcsCAR::prj_x2s(int nx, int ny, int sxy, int spt,
383 } 385 }
384 } 386 }
385 387
  388 + // Do boundary checking
  389 + int status = prj_bchk(1.0e-13, nx, my, spt, phi, theta, stat);
  390 +
  391 + // Handle status code
  392 + if (status != 0) {
  393 + std::string msg = "One or more of the (x, y) coordinates were invalid "
  394 + "for the "+name()+" ("+code()+") projection.";
  395 + throw GException::invalid_value(G_PRJ_X2S, msg);
  396 + }
  397 +
386 // Return 398 // Return
387 return; 399 return;
388 } 400 }
src/sky/GWcsMER.cpp
@@ -34,6 +34,8 @@ @@ -34,6 +34,8 @@
34 #include "GWcsRegistry.hpp" 34 #include "GWcsRegistry.hpp"
35 35
36 /* __ Method name definitions ____________________________________________ */ 36 /* __ Method name definitions ____________________________________________ */
  37 +#define G_PRJ_X2S "GWcsMER::prj_x2s(int, int, int, int, double*, double*,"\
  38 + " double*, double*, int*)"
37 39
38 /* __ Macros _____________________________________________________________ */ 40 /* __ Macros _____________________________________________________________ */
39 41
@@ -383,6 +385,16 @@ void GWcsMER::prj_x2s(int nx, int ny, int sxy, int spt, @@ -383,6 +385,16 @@ void GWcsMER::prj_x2s(int nx, int ny, int sxy, int spt,
383 } 385 }
384 } 386 }
385 387
  388 + // Do boundary checking
  389 + int status = prj_bchk(1.0e-13, nx, my, spt, phi, theta, stat);
  390 +
  391 + // Handle status code
  392 + if (status != 0) {
  393 + std::string msg = "One or more of the (x, y) coordinates were invalid "
  394 + "for the "+name()+" ("+code()+") projection.";
  395 + throw GException::invalid_value(G_PRJ_X2S, msg);
  396 + }
  397 +
386 // Return 398 // Return
387 return; 399 return;
388 } 400 }
src/sky/GWcsMOL.cpp
@@ -529,6 +529,16 @@ void GWcsMOL::prj_x2s(int nx, int ny, int sxy, int spt, @@ -529,6 +529,16 @@ void GWcsMOL::prj_x2s(int nx, int ny, int sxy, int spt,
529 throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid); 529 throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid);
530 } 530 }
531 531
  532 + // Do boundary checking
  533 + status = prj_bchk(1.0e-11, nx, my, spt, phi, theta, stat);
  534 +
  535 + // Handle status code
  536 + if (status != 0) {
  537 + std::string msg = "One or more of the (x, y) coordinates were invalid "
  538 + "for the "+name()+" ("+code()+") projection.";
  539 + throw GException::invalid_value(G_PRJ_X2S, msg);
  540 + }
  541 +
532 // Return 542 // Return
533 return; 543 return;
534 } 544 }
src/sky/GWcsSFL.cpp
@@ -428,6 +428,16 @@ void GWcsSFL::prj_x2s(int nx, int ny, int sxy, int spt, @@ -428,6 +428,16 @@ void GWcsSFL::prj_x2s(int nx, int ny, int sxy, int spt,
428 throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid); 428 throw GException::wcs_invalid_x_y(G_PRJ_X2S, n_invalid);
429 } 429 }
430 430
  431 + // Do boundary checking
  432 + status = prj_bchk(1.0e-12, nx, my, spt, phi, theta, stat);
  433 +
  434 + // Handle status code
  435 + if (status != 0) {
  436 + std::string msg = "One or more of the (x, y) coordinates were invalid "
  437 + "for the "+name()+" ("+code()+") projection.";
  438 + throw GException::invalid_value(G_PRJ_X2S, msg);
  439 + }
  440 +
431 // Return 441 // Return
432 return; 442 return;
433 } 443 }
src/sky/Makefile.am
1 ############################################################################# 1 #############################################################################
2 # Makefile.am for sky module # 2 # Makefile.am for sky module #
3 # ------------------------------------------------------------------------- # 3 # ------------------------------------------------------------------------- #
4 -# Copyright (C) 2016-2017 Juergen Knoedlseder # 4 +# Copyright (C) 2016-2018 Juergen Knoedlseder #
5 # ------------------------------------------------------------------------- # 5 # ------------------------------------------------------------------------- #
6 # # 6 # #
7 # This program is free software: you can redistribute it and/or modify # 7 # This program is free software: you can redistribute it and/or modify #
@@ -38,6 +38,7 @@ sources = GSkyDir.cpp \ @@ -38,6 +38,7 @@ sources = GSkyDir.cpp \
38 GWcsRegistry.cpp \ 38 GWcsRegistry.cpp \
39 GWcs.cpp \ 39 GWcs.cpp \
40 GWcsAIT.cpp \ 40 GWcsAIT.cpp \
  41 + GWcsARC.cpp \
41 GWcsAZP.cpp \ 42 GWcsAZP.cpp \
42 GWcsCAR.cpp \ 43 GWcsCAR.cpp \
43 GWcsGLS.cpp \ 44 GWcsGLS.cpp \
test/test_GSky.py
@@ -358,6 +358,17 @@ class Test(gammalib.GPythonTestSuite): @@ -358,6 +358,17 @@ class Test(gammalib.GPythonTestSuite):
358 # Return 358 # Return
359 return 359 return
360 360
  361 + # Test ARC projection
  362 + def _test_skymap_arc(self):
  363 + """
  364 + Test ARC projection.
  365 + """
  366 + # Execute generic test
  367 + self._test_skymap_proj('ARC')
  368 +
  369 + # Return
  370 + return
  371 +
361 # Test AZP projection 372 # Test AZP projection
362 def _test_skymap_azp(self): 373 def _test_skymap_azp(self):
363 """ 374 """
@@ -565,6 +576,7 @@ class Test(gammalib.GPythonTestSuite): @@ -565,6 +576,7 @@ class Test(gammalib.GPythonTestSuite):
565 test_support._pickeling(self, gammalib.GSkyRegionMap()) 576 test_support._pickeling(self, gammalib.GSkyRegionMap())
566 test_support._pickeling(self, gammalib.GSkyRegions()) 577 test_support._pickeling(self, gammalib.GSkyRegions())
567 test_support._pickeling(self, gammalib.GWcsAIT()) 578 test_support._pickeling(self, gammalib.GWcsAIT())
  579 + test_support._pickeling(self, gammalib.GWcsARC())
568 test_support._pickeling(self, gammalib.GWcsAZP()) 580 test_support._pickeling(self, gammalib.GWcsAZP())
569 test_support._pickeling(self, gammalib.GWcsCAR()) 581 test_support._pickeling(self, gammalib.GWcsCAR())
570 test_support._pickeling(self, gammalib.GWcsGLS()) 582 test_support._pickeling(self, gammalib.GWcsGLS())
@@ -596,6 +608,7 @@ class Test(gammalib.GPythonTestSuite): @@ -596,6 +608,7 @@ class Test(gammalib.GPythonTestSuite):
596 test_support._pickeling(self, gammalib.GSkyRegionMap(map)) 608 test_support._pickeling(self, gammalib.GSkyRegionMap(map))
597 test_support._pickeling(self, gammalib.GSkyRegions(regions)) 609 test_support._pickeling(self, gammalib.GSkyRegions(regions))
598 test_support._pickeling(self, gammalib.GWcsAIT('GAL',1.0,2.0,1.0,1.0,0.1,0.1)) 610 test_support._pickeling(self, gammalib.GWcsAIT('GAL',1.0,2.0,1.0,1.0,0.1,0.1))
  611 + test_support._pickeling(self, gammalib.GWcsARC('GAL',1.0,2.0,1.0,1.0,0.1,0.1))
599 test_support._pickeling(self, gammalib.GWcsAZP('GAL',1.0,2.0,1.0,1.0,0.1,0.1)) 612 test_support._pickeling(self, gammalib.GWcsAZP('GAL',1.0,2.0,1.0,1.0,0.1,0.1))
600 test_support._pickeling(self, gammalib.GWcsCAR('GAL',1.0,2.0,1.0,1.0,0.1,0.1)) 613 test_support._pickeling(self, gammalib.GWcsCAR('GAL',1.0,2.0,1.0,1.0,0.1,0.1))
601 test_support._pickeling(self, gammalib.GWcsGLS('GAL',1.0,2.0,1.0,1.0,0.1,0.1)) 614 test_support._pickeling(self, gammalib.GWcsGLS('GAL',1.0,2.0,1.0,1.0,0.1,0.1))
@@ -622,6 +635,7 @@ class Test(gammalib.GPythonTestSuite): @@ -622,6 +635,7 @@ class Test(gammalib.GPythonTestSuite):
622 self.append(self._test_operators, 'Test sky map operators') 635 self.append(self._test_operators, 'Test sky map operators')
623 self.append(self._test_skymap_healpix, 'Test HEALPix map') 636 self.append(self._test_skymap_healpix, 'Test HEALPix map')
624 self.append(self._test_skymap_ait, 'Test AIT projection map') 637 self.append(self._test_skymap_ait, 'Test AIT projection map')
  638 + self.append(self._test_skymap_arc, 'Test ARC projection map')
625 self.append(self._test_skymap_azp, 'Test AZP projection map') 639 self.append(self._test_skymap_azp, 'Test AZP projection map')
626 self.append(self._test_skymap_car, 'Test CAR projection map') 640 self.append(self._test_skymap_car, 'Test CAR projection map')
627 self.append(self._test_skymap_gls, 'Test GLS projection map') 641 self.append(self._test_skymap_gls, 'Test GLS projection map')