Commit b59f1ce11d099ad1d5ebf6d505dd0e5ce9e96284

Authored by Jürgen Knödlseder
1 parent 99d224a2

Add GSkyDirs container class (#3324)

ChangeLog
1   -2020-11-17
  1 +2020-11-18
2 2  
3 3 * Version 2.0.0 released
4 4 ========================
... ... @@ -14,6 +14,7 @@
14 14 Add GIntegrals class (#3328)
15 15 Remove implicit conversion warnings (#3324)
16 16 Add gammalib::tmpnam() function (#3324)
  17 + Add GSkyDirs container class (#3324)
17 18 Implement vectorised response computation (#3203)
18 19 Implement analytical gradients for the radial Gaussian model in a
19 20 stacked analysis (#3203)
... ...
1 1 New Features and Important Changes in GammaLib 2.0.0
2 2  
3   -17 November 2020
  3 +18 November 2020
4 4  
5 5  
6 6 1. Introduction
... ... @@ -15,6 +15,7 @@ The following classes have been added:
15 15 - GFunctions
16 16 - GIntegrals
17 17 - GResponseVectorCache
  18 +- GSkyDirs
18 19 - GCTAModelSkyCube
19 20  
20 21 The following classes have been removed:
... ... @@ -141,7 +142,8 @@ Added GOptimizerLM::npars() and GOptimizerLM::nfree() methods.
141 142  
142 143 12. Sky module
143 144 --------------
144   -None
  145 +Added GSkyDirs container class to hold sky directions. The GHealpix::boundaries()
  146 +method now returns an instance of GSkyDirs (#3324).
145 147  
146 148  
147 149 13. Support module
... ...
README.md
1 1 GammaLib information
2 2 ====================
3   -* Version: 2.0.0.dev (17 November 2020)
  3 +* Version: 2.0.0.dev (18 November 2020)
4 4  
5 5 [![Build Status](https://cta-jenkins.irap.omp.eu/buildStatus/icon?job=gammalib-integrate-os)](https://cta-jenkins.irap.omp.eu/job/gammalib-integrate-os/)
6 6  
... ...
doc/source/admin/release_history/2.0.rst
... ... @@ -51,6 +51,8 @@ New features
51 51 Add ``GFunctions`` abstract base class and ``GIntegrals`` class
52 52 * [`3324 <https://cta-redmine.irap.omp.eu/issues/3324>`_] -
53 53 Add ``gammalib::tmpnam()`` function
  54 +* [`3324 <https://cta-redmine.irap.omp.eu/issues/3324>`_] -
  55 + Add ``GSkyDirs`` container class
54 56 * [`3074 <https://cta-redmine.irap.omp.eu/issues/3074>`_] -
55 57 Add ``GSkyModel`` ``flux_error()`` and ``eflux_error()`` methods
56 58  
... ...
include/GHealpix.hpp
... ... @@ -34,6 +34,9 @@
34 34 #include "GSkyPixel.hpp"
35 35 #include "GBilinear.hpp"
36 36  
  37 +/* __ Forward declarations _______________________________________________ */
  38 +class GSkyDirs;
  39 +
37 40  
38 41 /***********************************************************************//**
39 42 * @class GHealpix
... ... @@ -75,13 +78,13 @@ public:
75 78 virtual std::string print(const GChatter& chatter = NORMAL) const;
76 79  
77 80 // Other methods
78   - const int& npix(void) const;
79   - const int& nside(void) const;
80   - std::string ordering(void) const;
81   - void ordering(const std::string& ordering);
82   - std::vector<int> neighbours(const GSkyPixel& pixel) const;
83   - std::vector<GSkyDir> boundaries(const GSkyPixel& pixel, const int& step = 1) const;
84   - double max_pixrad(void) const;
  81 + const int& npix(void) const;
  82 + const int& nside(void) const;
  83 + std::string ordering(void) const;
  84 + void ordering(const std::string& ordering);
  85 + std::vector<int> neighbours(const GSkyPixel& pixel) const;
  86 + GSkyDirs boundaries(const GSkyPixel& pixel, const int& step = 1) const;
  87 + double max_pixrad(void) const;
85 88  
86 89 private:
87 90 // Private methods
... ...
include/GSkyDirs.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * GSkyDirs.hpp - Sky directions container class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2020 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 GSkyDirs.hpp
  23 + * @brief Sky directions container class definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef GSKYDIRS_HPP
  28 +#define GSKYDIRS_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include <string>
  32 +#include <vector>
  33 +#include "GContainer.hpp"
  34 +#include "GSkyDir.hpp"
  35 +
  36 +/* __ Forward declarations _______________________________________________ */
  37 +
  38 +/* __ Constants __________________________________________________________ */
  39 +
  40 +
  41 +/***********************************************************************//**
  42 + * @class GSkyDirs
  43 + *
  44 + * @brief Sky directions container class
  45 + *
  46 + * This class is a container for sky directions. Sky directions are
  47 + * implemented by the GSkyDir class.
  48 + ***************************************************************************/
  49 +class GSkyDirs : public GContainer {
  50 +
  51 +public:
  52 + // Constructors and destructors
  53 + GSkyDirs(void);
  54 + explicit GSkyDirs(const GSkyDir& dir);
  55 + GSkyDirs(const GSkyDirs& dirs);
  56 + virtual ~GSkyDirs(void);
  57 +
  58 + // Operators
  59 + GSkyDirs& operator=(const GSkyDirs& dirs);
  60 + GSkyDir& operator[](const int& index);
  61 + const GSkyDir& operator[](const int& index) const;
  62 +
  63 + // Methods
  64 + void clear(void);
  65 + GSkyDirs* clone(void) const;
  66 + std::string classname(void) const;
  67 + GSkyDir& at(const int& index);
  68 + const GSkyDir& at(const int& index) const;
  69 + int size(void) const;
  70 + bool is_empty(void) const;
  71 + GSkyDir& append(const GSkyDir& dir);
  72 + GSkyDir& insert(const int& index, const GSkyDir& dir);
  73 + void remove(const int& index);
  74 + void reserve(const int& num);
  75 + void extend(const GSkyDirs& dirs);
  76 + std::string print(const GChatter& chatter = NORMAL) const;
  77 +
  78 +protected:
  79 + // Protected methods
  80 + void init_members(void);
  81 + void copy_members(const GSkyDirs& dirs);
  82 + void free_members(void);
  83 +
  84 + // Protected data members
  85 + std::vector<GSkyDir> m_dirs; //!< List of sky directions
  86 +};
  87 +
  88 +
  89 +/***********************************************************************//**
  90 + * @brief Return class name
  91 + *
  92 + * @return String containing the class name ("GSkyDirs").
  93 + ***************************************************************************/
  94 +inline
  95 +std::string GSkyDirs::classname(void) const
  96 +{
  97 + return ("GSkyDirs");
  98 +}
  99 +
  100 +
  101 +/***********************************************************************//**
  102 + * @brief Return reference to sky direction
  103 + *
  104 + * @param[in] index Sky direction index [0,...,size()-1].
  105 + *
  106 + * Returns a reference to the sky direction with the specified @p index.
  107 + ***************************************************************************/
  108 +inline
  109 +GSkyDir& GSkyDirs::operator[](const int& index)
  110 +{
  111 + return (m_dirs[index]);
  112 +}
  113 +
  114 +
  115 +/***********************************************************************//**
  116 + * @brief Return reference to sky direction (const version)
  117 + *
  118 + * @param[in] index Sky direction index [0,...,size()-1].
  119 + *
  120 + * Returns a const reference to the sky direction with the specified
  121 + * @p index.
  122 + ***************************************************************************/
  123 +inline
  124 +const GSkyDir& GSkyDirs::operator[](const int& index) const
  125 +{
  126 + return (m_dirs[index]);
  127 +}
  128 +
  129 +
  130 +/***********************************************************************//**
  131 + * @brief Return reference to sky direction
  132 + *
  133 + * @param[in] index Sky directions index [0,...,size()-1].
  134 + *
  135 + * @exception GException::out_of_range
  136 + * Sky directions index is out of range.
  137 + *
  138 + * Returns a reference to the sky directions with the specified @p index.
  139 + ***************************************************************************/
  140 +inline
  141 +GSkyDir& GSkyDirs::at(const int& index)
  142 +{
  143 + // Return child element using const method
  144 + return const_cast<GSkyDir&>((this)->at(index));
  145 +}
  146 +
  147 +
  148 +/***********************************************************************//**
  149 + * @brief Return number of sky directions in container
  150 + *
  151 + * @return Number of sky directions in container.
  152 + *
  153 + * Returns the number of sky directions in the sky directions container.
  154 + ***************************************************************************/
  155 +inline
  156 +int GSkyDirs::size(void) const
  157 +{
  158 + return ((int)m_dirs.size());
  159 +}
  160 +
  161 +
  162 +/***********************************************************************//**
  163 + * @brief Signals if there are no sky directions in container
  164 + *
  165 + * @return True if container is empty, false otherwise.
  166 + *
  167 + * Signals if the sky directions container does not contain any sky
  168 + * direction.
  169 + ***************************************************************************/
  170 +inline
  171 +bool GSkyDirs::is_empty(void) const
  172 +{
  173 + return (m_dirs.empty());
  174 +}
  175 +
  176 +
  177 +/***********************************************************************//**
  178 + * @brief Reserves space for sky directions in container
  179 + *
  180 + * @param[in] num Number of sky directions.
  181 + *
  182 + * Reserves space for @p num sky directions in the container.
  183 + ***************************************************************************/
  184 +inline
  185 +void GSkyDirs::reserve(const int& num)
  186 +{
  187 + m_dirs.reserve(num);
  188 + return;
  189 +}
  190 +
  191 +#endif /* GSKYDIRS_HPP */
... ...
include/GammaLib.hpp
... ... @@ -143,8 +143,9 @@
143 143 * Analysis support services *
144 144 ***************************************************************************/
145 145  
146   -/* __ Skymap handling ____________________________________________________ */
  146 +/* __ Sky handling _______________________________________________________ */
147 147 #include "GSkyDir.hpp"
  148 +#include "GSkyDirs.hpp"
148 149 #include "GHorizDir.hpp"
149 150 #include "GSkyPixel.hpp"
150 151 #include "GSkyMap.hpp"
... ...
include/Makefile.am
... ... @@ -107,6 +107,7 @@ pkginclude_HEADERS = GammaLib.hpp \
107 107 GTestSuites.hpp \
108 108 GTestCase.hpp \
109 109 GSkyDir.hpp \
  110 + GSkyDirs.hpp \
110 111 GHorizDir.hpp \
111 112 GSkyPixel.hpp \
112 113 GSkyMap.hpp \
... ...
pyext/GHealpix.i
1 1 /***************************************************************************
2 2 * GHealpix.i - Healpix projection class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2018 by Jurgen Knodlseder *
  4 + * copyright (C) 2010-2020 by Jurgen Knodlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -60,13 +60,13 @@ public:
60 60 virtual GBilinear interpolator(const GSkyDir& dir) const;
61 61  
62 62 // Other methods
63   - const int& npix(void) const;
64   - const int& nside(void) const;
65   - std::string ordering(void) const;
66   - void ordering(const std::string& ordering);
67   - std::vector<int> neighbours(const GSkyPixel& pixel) const;
68   - std::vector<GSkyDir> boundaries(const GSkyPixel& pixel, const int& step = 1) const;
69   - double max_pixrad(void) const;
  63 + const int& npix(void) const;
  64 + const int& nside(void) const;
  65 + std::string ordering(void) const;
  66 + void ordering(const std::string& ordering);
  67 + std::vector<int> neighbours(const GSkyPixel& pixel) const;
  68 + GSkyDirs boundaries(const GSkyPixel& pixel, const int& step = 1) const;
  69 + double max_pixrad(void) const;
70 70 };
71 71  
72 72  
... ...
pyext/GSkyDirs.i 0 → 100644
  1 +/***************************************************************************
  2 + * GSkyDirs.i - Sky directions container class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2020 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 GSkyDirs.i
  23 + * @brief Sky directions container class definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +%{
  27 +/* Put headers and other declarations here that are needed for compilation */
  28 +#include "GSkyDirs.hpp"
  29 +#include "GException.hpp"
  30 +#include "GTools.hpp"
  31 +%}
  32 +
  33 +
  34 +/***********************************************************************//**
  35 + * @class GSkyDirs
  36 + *
  37 + * @brief Sky directions container class
  38 + ***************************************************************************/
  39 +class GSkyDirs : public GContainer {
  40 +
  41 +public:
  42 + // Constructors and destructors
  43 + GSkyDirs(void);
  44 + explicit GSkyDirs(const GSkyDir& dir);
  45 + GSkyDirs(const GSkyDirs& dirs);
  46 + virtual ~GSkyDirs(void);
  47 +
  48 + // Methods
  49 + void clear(void);
  50 + GSkyDirs* clone(void) const;
  51 + std::string classname(void) const;
  52 + GSkyDir& at(const int& index);
  53 + const GSkyDir& at(const int& index) const;
  54 + int size(void) const;
  55 + bool is_empty(void) const;
  56 + GSkyDir& append(const GSkyDir& dir);
  57 + GSkyDir& insert(const int& index, const GSkyDir& dir);
  58 + void remove(const int& index);
  59 + void reserve(const int& num);
  60 + void extend(const GSkyDirs& dirs);
  61 +};
  62 +
  63 +
  64 +/***********************************************************************//**
  65 + * @brief GSkyDirs class extension
  66 + ***************************************************************************/
  67 +%extend GSkyDirs {
  68 + GSkyDir& __getitem__(const int& index) {
  69 + // Counting from start, e.g. [2]
  70 + if (index >= 0 && index < self->size()) {
  71 + return (*self)[index];
  72 + }
  73 + // Counting from end, e.g. [-1]
  74 + else if (index < 0 && self->size()+index >= 0) {
  75 + return (*self)[self->size()+index];
  76 + }
  77 + else {
  78 + throw GException::out_of_range("__getitem__(int)", index, self->size());
  79 + }
  80 + }
  81 + GSkyDirs* __getitem__(PyObject *param) {
  82 + if (PySlice_Check(param)) {
  83 + Py_ssize_t start = 0;
  84 + Py_ssize_t stop = 0;
  85 + Py_ssize_t step = 0;
  86 + Py_ssize_t len = self->size();
  87 + if (PythonSlice_GetIndices(param, len, &start, &stop, &step) == 0) {
  88 + GSkyDirs* dirs = new GSkyDirs;
  89 + if (step > 0) {
  90 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  91 + dirs->append((*self)[i]);
  92 + }
  93 + }
  94 + else {
  95 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  96 + dirs->append((*self)[i]);
  97 + }
  98 + }
  99 + return dirs;
  100 + }
  101 + else {
  102 + throw GException::invalid_argument("__getitem__(PyObject)",
  103 + "Invalid slice indices");
  104 + }
  105 + }
  106 + else {
  107 + throw GException::invalid_argument("__getitem__(PyObject)","");
  108 + }
  109 + }
  110 + void __setitem__(const int& index, const GSkyDir& val) {
  111 + // Counting from start, e.g. [2]
  112 + if (index >= 0 && index < self->size()) {
  113 + (*self)[index] = val;
  114 + }
  115 + // Counting from end, e.g. [-1]
  116 + else if (index < 0 && self->size()+index >= 0) {
  117 + (*self)[self->size()+index] = val;
  118 + }
  119 + else {
  120 + throw GException::out_of_range("__setitem__(int)", index, self->size());
  121 + }
  122 + }
  123 + GSkyDirs copy() {
  124 + return (*self);
  125 + }
  126 +%pythoncode {
  127 + def __getstate__(self):
  128 + state = tuple([x for x in self]),
  129 + return state
  130 + def __setstate__(self, state):
  131 + self.__init__()
  132 + size = len(state[0])
  133 + self.reserve(size)
  134 + for x in state[0]:
  135 + self.append(x)
  136 +}
  137 +};
... ...
pyext/gammalib/sky.i
... ... @@ -41,9 +41,8 @@
41 41 %include stl.i
42 42 %include "std_vector.i"
43 43 namespace std {
44   - %template(vectori) vector<int>;
45   - %template(vectord) vector<double>;
46   - %template(vectorskydir) vector<GSkyDir>;
  44 + %template(vectori) vector<int>;
  45 + %template(vectord) vector<double>;
47 46 };
48 47  
49 48 /* __ Include GammaLib typemaps __________________________________________ */
... ... @@ -112,6 +111,7 @@ namespace std {
112 111  
113 112 /* __ Skymap handling ____________________________________________________ */
114 113 %include "GSkyDir.i"
  114 +%include "GSkyDirs.i"
115 115 %include "GHorizDir.i"
116 116 %include "GSkyPixel.i"
117 117 %include "GSkyMap.i"
... ...
src/obs/GEnergies.cpp
... ... @@ -120,7 +120,7 @@ GEnergies::GEnergies(const GEbounds&amp; ebounds)
120 120 /***********************************************************************//**
121 121 * @brief Copy constructor
122 122 *
123   - * @param energies Energy container.
  123 + * @param energies[in] Energy container.
124 124 *
125 125 * Construct energy container by copying from another energy container.
126 126 ***************************************************************************/
... ...
src/sky/GHealpix.cpp
... ... @@ -33,6 +33,7 @@
33 33 #include "GTools.hpp"
34 34 #include "GMath.hpp"
35 35 #include "GVector.hpp"
  36 +#include "GSkyDirs.hpp"
36 37 #include "GHealpix.hpp"
37 38  
38 39 /* __ Method name definitions ____________________________________________ */
... ... @@ -696,7 +697,7 @@ std::vector&lt;int&gt; GHealpix::neighbours(const GSkyPixel&amp; pixel) const
696 697 * @param[in] step Number of returned points (4*step, defaults to 4).
697 698 * @return Array of pixel boundaries.
698 699 *
699   - * The method returns a vector with sky directions along the boundary of a
  700 + * The method returns a container of sky directions along the boundary of a
700 701 * HealPix pixel. By default, the 4 corners of HealPix pixel will be
701 702 * returned. The first point corresponds to the northernmost corner, the
702 703 * subsequent points follow the pixel boundary through west, south and east
... ... @@ -706,8 +707,7 @@ std::vector&lt;int&gt; GHealpix::neighbours(const GSkyPixel&amp; pixel) const
706 707 * This method has been adapted from the boundaries() function located in the
707 708 * file healpix_base.cc in Healpix version 3.20.
708 709 ***************************************************************************/
709   -std::vector<GSkyDir> GHealpix::boundaries(const GSkyPixel& pixel,
710   - const int& step) const
  710 +GSkyDirs GHealpix::boundaries(const GSkyPixel& pixel, const int& step) const
711 711 {
712 712 // Throw an exception if sky map pixel is not 1D
713 713 if (!pixel.is_1D()) {
... ... @@ -719,7 +719,7 @@ std::vector&lt;GSkyDir&gt; GHealpix::boundaries(const GSkyPixel&amp; pixel,
719 719 }
720 720  
721 721 // Allocate boundaries
722   - std::vector<GSkyDir> boundaries;
  722 + GSkyDirs boundaries;
723 723  
724 724 // Determine pixel index and face number
725 725 int ix;
... ... @@ -742,19 +742,19 @@ std::vector&lt;GSkyDir&gt; GHealpix::boundaries(const GSkyPixel&amp; pixel,
742 742  
743 743 // First coordinate
744 744 xyf2loc(xc+dc-i*d, yc+dc, face, &z, &phi);
745   - boundaries.push_back(loc2dir(z, phi));
  745 + boundaries.append(loc2dir(z, phi));
746 746  
747 747 // Second coordinate
748 748 xyf2loc(xc-dc, yc+dc-i*d, face, &z, &phi);
749   - boundaries.push_back(loc2dir(z, phi));
  749 + boundaries.append(loc2dir(z, phi));
750 750  
751 751 // Third coordinate
752 752 xyf2loc(xc-dc+i*d, yc-dc, face, &z, &phi);
753   - boundaries.push_back(loc2dir(z, phi));
  753 + boundaries.append(loc2dir(z, phi));
754 754  
755 755 // Forth coordinate
756 756 xyf2loc(xc+dc, yc-dc+i*d, face, &z, &phi);
757   - boundaries.push_back(loc2dir(z, phi));
  757 + boundaries.append(loc2dir(z, phi));
758 758  
759 759 } // endfor: looped over step size
760 760  
... ...
src/sky/GSkyDirs.cpp 0 → 100644
  1 +/***************************************************************************
  2 + * GSkyDirs.cpp - Sky directions container class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2020 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 GSkyDirs.cpp
  23 + * @brief Sky directions container class implementation
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +/* __ Includes ___________________________________________________________ */
  28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
  31 +#include "GTools.hpp"
  32 +#include "GException.hpp"
  33 +#include "GFilename.hpp"
  34 +#include "GSkyDirs.hpp"
  35 +/*
  36 +#include "GEbounds.hpp"
  37 +#include "GFits.hpp"
  38 +#include "GFitsTable.hpp"
  39 +#include "GFitsBinTable.hpp"
  40 +#include "GFitsTableCol.hpp"
  41 +#include "GFitsTableDoubleCol.hpp"
  42 +*/
  43 +
  44 +/* __ Method name definitions ____________________________________________ */
  45 +#define G_AT "GSkyDirs::at(int&)"
  46 +#define G_INSERT "GSkyDirs::insert(int&, GSkyDir&)"
  47 +#define G_REMOVE "GSkyDirs::remove(int&)"
  48 +
  49 +/* __ Macros _____________________________________________________________ */
  50 +
  51 +/* __ Coding definitions _________________________________________________ */
  52 +
  53 +/* __ Debug definitions __________________________________________________ */
  54 +
  55 +
  56 +/*==========================================================================
  57 + = =
  58 + = Constructors/destructors =
  59 + = =
  60 + ==========================================================================*/
  61 +
  62 +/***********************************************************************//**
  63 + * @brief Void constructor
  64 + *
  65 + * Constructs empty sky directions container.
  66 + ***************************************************************************/
  67 +GSkyDirs::GSkyDirs(void)
  68 +{
  69 + // Initialise members
  70 + init_members();
  71 +
  72 + // Return
  73 + return;
  74 +}
  75 +
  76 +
  77 +/***********************************************************************//**
  78 + * @brief Single sky direction constructor
  79 + *
  80 + * @param[in] dir Sky directions.
  81 + *
  82 + * Constructs sky directions container from a single sky direction.
  83 + ***************************************************************************/
  84 +GSkyDirs::GSkyDirs(const GSkyDir& dir)
  85 +{
  86 + // Initialise members
  87 + init_members();
  88 +
  89 + // Append sky direction
  90 + append(dir);
  91 +
  92 + // Return
  93 + return;
  94 +}
  95 +
  96 +
  97 +/***********************************************************************//**
  98 + * @brief Copy constructor
  99 + *
  100 + * @param[in] dir Sky directions.
  101 + *
  102 + * Construct sky directions container by copying from another sky directions
  103 + * container.
  104 + ***************************************************************************/
  105 +GSkyDirs::GSkyDirs(const GSkyDirs& dirs)
  106 +{
  107 + // Initialise members
  108 + init_members();
  109 +
  110 + // Copy members
  111 + copy_members(dirs);
  112 +
  113 + // Return
  114 + return;
  115 +}
  116 +
  117 +
  118 +/***********************************************************************//**
  119 + * @brief Destructor
  120 + ***************************************************************************/
  121 +GSkyDirs::~GSkyDirs(void)
  122 +{
  123 + // Free members
  124 + free_members();
  125 +
  126 + // Return
  127 + return;
  128 +}
  129 +
  130 +
  131 +/*==========================================================================
  132 + = =
  133 + = Operators =
  134 + = =
  135 + ==========================================================================*/
  136 +
  137 +/***********************************************************************//**
  138 + * @brief Assignment operator
  139 + *
  140 + * @param[in] dirs Sky direction container.
  141 + * @return Sky direction container.
  142 + ***************************************************************************/
  143 +GSkyDirs& GSkyDirs::operator=(const GSkyDirs& dirs)
  144 +{
  145 + // Execute only if object is not identical
  146 + if (this != &dirs) {
  147 +
  148 + // Free members
  149 + free_members();
  150 +
  151 + // Initialise members
  152 + init_members();
  153 +
  154 + // Copy members
  155 + copy_members(dirs);
  156 +
  157 + } // endif: object was not identical
  158 +
  159 + // Return this object
  160 + return *this;
  161 +}
  162 +
  163 +
  164 +/*==========================================================================
  165 + = =
  166 + = Public methods =
  167 + = =
  168 + ==========================================================================*/
  169 +
  170 +/***********************************************************************//**
  171 + * @brief Clear sky directions container
  172 + *
  173 + * Removes all sky directions from the container.
  174 + ***************************************************************************/
  175 +void GSkyDirs::clear(void)
  176 +{
  177 + // Free members
  178 + free_members();
  179 +
  180 + // Initialise members
  181 + init_members();
  182 +
  183 + // Return
  184 + return;
  185 +}
  186 +
  187 +
  188 +/***********************************************************************//**
  189 + * @brief Clone sky directions container
  190 + *
  191 + * @return Pointer to deep copy of sky directions container
  192 + *
  193 + * Makes a deep copy of the sky directions container instance.
  194 + ***************************************************************************/
  195 +GSkyDirs* GSkyDirs::clone(void) const
  196 +{
  197 + return new GSkyDirs(*this);
  198 +}
  199 +
  200 +
  201 +/***********************************************************************//**
  202 + * @brief Return reference to sky direction (const version)
  203 + *
  204 + * @param[in] index Sky directions index [0,...,size()-1].
  205 + *
  206 + * @exception GException::out_of_range
  207 + * Sky directions index is out of range.
  208 + *
  209 + * Returns a reference to the sky directions with the specified @p index.
  210 + ***************************************************************************/
  211 +const GSkyDir& GSkyDirs::at(const int& index) const
  212 +{
  213 + // Raise exception if index is out of range
  214 + if (index < 0 || index >= size()) {
  215 + throw GException::out_of_range(G_AT, "Sky direction", index, size());
  216 + }
  217 +
  218 + // Return reference
  219 + return m_dirs[index];
  220 +}
  221 +
  222 +
  223 +/***********************************************************************//**
  224 + * @brief Append sky direction to container
  225 + *
  226 + * @param[in] dir Sky direction.
  227 + * @return Reference to appended sky direction.
  228 + *
  229 + * Appends sky direction to the container by making a deep copy of the sky
  230 + * direction.
  231 + ***************************************************************************/
  232 +GSkyDir& GSkyDirs::append(const GSkyDir& dir)
  233 +{
  234 + // Append sky direction to list
  235 + m_dirs.push_back(dir);
  236 +
  237 + // Return reference
  238 + return m_dirs[size()-1];
  239 +}
  240 +
  241 +
  242 +/***********************************************************************//**
  243 + * @brief Insert sky direction into container
  244 + *
  245 + * @param[in] index Sky direction index (0,...,size()-1).
  246 + * @param[in] dir Sky direction.
  247 + *
  248 + * @exception GException::out_of_range
  249 + * Sky direction index is out of range.
  250 + *
  251 + * Inserts a sky direction @p dir into the container before the sky
  252 + * direction with the specified @p index.
  253 + ***************************************************************************/
  254 +GSkyDir& GSkyDirs::insert(const int& index, const GSkyDir& dir)
  255 +{
  256 + // Compile option: raise exception if index is out of range
  257 + #if defined(G_RANGE_CHECK)
  258 + if (is_empty()) {
  259 + if (index > 0) {
  260 + throw GException::out_of_range(G_INSERT, "Sky direction", index,
  261 + size());
  262 + }
  263 + }
  264 + else {
  265 + if (index < 0 || index >= size()) {
  266 + throw GException::out_of_range(G_INSERT, "Sky direction", index,
  267 + size());
  268 + }
  269 + }
  270 + #endif
  271 +
  272 + // Inserts sky direction
  273 + m_dirs.insert(m_dirs.begin()+index, dir);
  274 +
  275 + // Return reference
  276 + return m_dirs[index];
  277 +}
  278 +
  279 +
  280 +/***********************************************************************//**
  281 + * @brief Remove sky direction from container
  282 + *
  283 + * @param[in] index Sky direction index (0,...,size()-1).
  284 + *
  285 + * @exception GException::out_of_range
  286 + * Sky direction index is out of range.
  287 + *
  288 + * Remove sky direction of specified @p index from container.
  289 + ***************************************************************************/
  290 +void GSkyDirs::remove(const int& index)
  291 +{
  292 + // Compile option: raise exception if index is out of range
  293 + #if defined(G_RANGE_CHECK)
  294 + if (index < 0 || index >= size()) {
  295 + throw GException::out_of_range(G_REMOVE, "Sky direction", index, size());
  296 + }
  297 + #endif
  298 +
  299 + // Erase sky direction from container
  300 + m_dirs.erase(m_dirs.begin() + index);
  301 +
  302 + // Return
  303 + return;
  304 +}
  305 +
  306 +
  307 +/***********************************************************************//**
  308 + * @brief Append sky directions container
  309 + *
  310 + * @param[in] dirs Sky directions container.
  311 + *
  312 + * Append sky directions container to the container.
  313 + ***************************************************************************/
  314 +void GSkyDirs::extend(const GSkyDirs& dirs)
  315 +{
  316 + // Do nothing if sky directions container is empty
  317 + if (!dirs.is_empty()) {
  318 +
  319 + // Get size. Note that we extract the size first to avoid an
  320 + // endless loop that arises when a container is appended to
  321 + // itself.
  322 + int num = dirs.size();
  323 +
  324 + // Reserve enough space
  325 + reserve(size() + num);
  326 +
  327 + // Loop over all elements and append them to container
  328 + for (int i = 0; i < num; ++i) {
  329 + m_dirs.push_back(dirs[i]);
  330 + }
  331 +
  332 + } // endif: sky directions container was not empty
  333 +
  334 + // Return
  335 + return;
  336 +}
  337 +
  338 +
  339 +/***********************************************************************//**
  340 + * @brief Print sky directions container information
  341 + *
  342 + * @param[in] chatter Chattiness.
  343 + * @return String containing sky directions container information.
  344 + ***************************************************************************/
  345 +std::string GSkyDirs::print(const GChatter& chatter) const
  346 +{
  347 + // Initialise result string
  348 + std::string result;
  349 +
  350 + // Continue only if chatter is not silent
  351 + if (chatter != SILENT) {
  352 +
  353 + // Append header
  354 + result.append("=== GSkyDirs ===");
  355 +
  356 + // Append sky direction container information
  357 + result.append("\n"+gammalib::parformat("Number of directions"));
  358 + result.append(gammalib::str(size()));
  359 +
  360 + // EXPLICIT: Append sky directions
  361 + if (chatter >= EXPLICIT) {
  362 + for (int i = 0; i < size(); ++i) {
  363 + result.append("\n");
  364 + result.append(gammalib::parformat("Direction "+gammalib::str(i)));
  365 + result.append(m_dirs[i].print(chatter));
  366 + }
  367 + }
  368 +
  369 + } // endif: chatter was not silent
  370 +
  371 + // Return result
  372 + return result;
  373 +}
  374 +
  375 +
  376 +/*==========================================================================
  377 + = =
  378 + = Private methods =
  379 + = =
  380 + ==========================================================================*/
  381 +
  382 +/***********************************************************************//**
  383 + * @brief Initialise class members
  384 + ***************************************************************************/
  385 +void GSkyDirs::init_members(void)
  386 +{
  387 + // Initialise members
  388 + m_dirs.clear();
  389 +
  390 + // Return
  391 + return;
  392 +}
  393 +
  394 +
  395 +/***********************************************************************//**
  396 + * @brief Copy class members
  397 + *
  398 + * @param[in] dirs Sky directions container.
  399 + ***************************************************************************/
  400 +void GSkyDirs::copy_members(const GSkyDirs& dirs)
  401 +{
  402 + // Copy attributes
  403 + m_dirs = dirs.m_dirs;
  404 +
  405 + // Return
  406 + return;
  407 +}
  408 +
  409 +
  410 +/***********************************************************************//**
  411 + * @brief Delete class members
  412 + ***************************************************************************/
  413 +void GSkyDirs::free_members(void)
  414 +{
  415 + // Return
  416 + return;
  417 +}
... ...
src/sky/GSkyMap.cpp
... ... @@ -38,6 +38,7 @@
38 38 #include "GFitsImage.hpp"
39 39 #include "GFitsImageDouble.hpp"
40 40 #include "GFitsTableDoubleCol.hpp"
  41 +#include "GSkyDirs.hpp"
41 42 #include "GSkyMap.hpp"
42 43 #include "GHealpix.hpp"
43 44 #include "GWcsRegistry.hpp"
... ... @@ -1607,7 +1608,7 @@ double GSkyMap::flux(const GSkyPixel&amp; pixel, const int&amp; map) const
1607 1608 GSkyDir centre = healpix->pix2dir(pixel);
1608 1609  
1609 1610 // Get boundaries
1610   - std::vector<GSkyDir> boundaries = healpix->boundaries(pixel, 3);
  1611 + GSkyDirs boundaries = healpix->boundaries(pixel, 3);
1611 1612  
1612 1613 // Compute intensities
1613 1614 double i0 = this->operator()(centre, map);
... ...
src/sky/Makefile.am
1 1 #############################################################################
2 2 # Makefile.am for sky module #
3 3 # ------------------------------------------------------------------------- #
4   -# Copyright (C) 2016-2018 Juergen Knoedlseder #
  4 +# Copyright (C) 2016-2020 Juergen Knoedlseder #
5 5 # ------------------------------------------------------------------------- #
6 6 # #
7 7 # This program is free software: you can redistribute it and/or modify #
... ... @@ -26,6 +26,7 @@ INCLUDES = -I$(top_srcdir)/include \
26 26  
27 27 # Define sources for this directory
28 28 sources = GSkyDir.cpp \
  29 + GSkyDirs.cpp \
29 30 GHorizDir.cpp \
30 31 GSkyPixel.cpp \
31 32 GSkyMap.cpp \
... ...
test/test_GSky.cpp
... ... @@ -63,6 +63,8 @@ void TestGSky::set(void){
63 63 "Test GWcs");
64 64 append(static_cast<pfunction>(&TestGSky::test_GSkyDir),
65 65 "Test GSkyDir");
  66 + append(static_cast<pfunction>(&TestGSky::test_GSkyDirs),
  67 + "Test GSkyDirs");
66 68 append(static_cast<pfunction>(&TestGSky::test_GSkyPixel),
67 69 "Test GSkyPixel");
68 70 append(static_cast<pfunction>(&TestGSky::test_GSkyMap_healpix_construct),
... ... @@ -356,6 +358,65 @@ void TestGSky::test_GSkyDir(void)
356 358 }
357 359  
358 360  
  361 +/***************************************************************************
  362 + * @brief Test GSkyDirs class
  363 + ***************************************************************************/
  364 +void TestGSky::test_GSkyDirs(void)
  365 +{
  366 + // Manipulate GSkyDirs starting from an empty object
  367 + GSkyDirs dirs;
  368 + test_value(dirs.size(), 0, "GSkyDirs should have zero size.");
  369 + test_assert(dirs.is_empty(), "GSkyDirs should be empty.");
  370 +
  371 + // Add a sky direction
  372 + dirs.append(GSkyDir());
  373 + test_value(dirs.size(), 1, "GSkyDirs should have 1 sky direction.");
  374 + test_assert(!dirs.is_empty(), "GSkyDirs should not be empty.");
  375 +
  376 + // Remove sky direction
  377 + dirs.remove(0);
  378 + test_value(dirs.size(), 0, "GSkyDirs should have zero size.");
  379 + test_assert(dirs.is_empty(), "GSkyDirs should be empty.");
  380 +
  381 + // Append two sky directions
  382 + dirs.append(GSkyDir());
  383 + dirs.append(GSkyDir());
  384 + test_value(dirs.size(), 2, "GSkyDirs should have 2 sky directions.");
  385 + test_assert(!dirs.is_empty(), "GSkyDirs should not be empty.");
  386 +
  387 + // Clear object
  388 + dirs.clear();
  389 + test_value(dirs.size(), 0, "GSkyDirs should have zero size.");
  390 + test_assert(dirs.is_empty(), "GSkyDirs should be empty.");
  391 +
  392 + // Insert two sky directions
  393 + dirs.insert(0, GSkyDir());
  394 + dirs.insert(0, GSkyDir());
  395 + test_value(dirs.size(), 2, "GSkyDirs should have 2 sky directions.");
  396 + test_assert(!dirs.is_empty(), "GSkyDirs should not be empty.");
  397 +
  398 + // Extend sky directios
  399 + dirs.extend(dirs);
  400 + test_value(dirs.size(), 4, "GSkyDirs should have 4 sky directions.");
  401 + test_assert(!dirs.is_empty(), "GSkyDirs should not be empty.");
  402 +
  403 + // Create 4 sky directions
  404 + dirs.clear();
  405 + for (int i = 0; i < 4; ++i) {
  406 + GSkyDir dir;
  407 + dir.radec_deg(double(i), double(i));
  408 + dirs.append(dir);
  409 + }
  410 + for (int i = 0; i < 4; ++i) {
  411 + test_value(dirs[i].ra_deg(), double(i));
  412 + test_value(dirs[i].dec_deg(), double(i));
  413 + }
  414 +
  415 + // Return
  416 + return;
  417 +}
  418 +
  419 +
359 420 /***********************************************************************//**
360 421 * @brief Test GSkyPixel class
361 422 *
... ...
test/test_GSky.hpp
... ... @@ -43,6 +43,7 @@ public:
43 43 virtual std::string classname(void) const { return "TestGSky"; }
44 44 void test_GWcs(void);
45 45 void test_GSkyDir(void);
  46 + void test_GSkyDirs(void);
46 47 void test_GSkyPixel(void);
47 48 void test_GSkyMap_healpix_construct(void);
48 49 void test_GSkyMap_healpix_io(void);
... ...
test/test_GSky.py
... ... @@ -594,6 +594,7 @@ class Test(gammalib.GPythonTestSuite):
594 594 test_support.pickeling(self, gammalib.GHealpix())
595 595 test_support.pickeling(self, gammalib.GHorizDir())
596 596 test_support.pickeling(self, gammalib.GSkyDir())
  597 + test_support.pickeling(self, gammalib.GSkyDirs())
597 598 test_support.pickeling(self, gammalib.GSkyMap())
598 599 test_support.pickeling(self, gammalib.GSkyPixel())
599 600 test_support.pickeling(self, gammalib.GSkyRegionCircle())
... ... @@ -629,6 +630,7 @@ class Test(gammalib.GPythonTestSuite):
629 630 test_support.pickeling(self, gammalib.GHealpix(4))
630 631 test_support.pickeling(self, horizdir)
631 632 test_support.pickeling(self, gammalib.GSkyDir(dir))
  633 + test_support.pickeling(self, gammalib.GSkyDirs(dir))
632 634 test_support.pickeling(self, gammalib.GSkyMap(map))
633 635 test_support.pickeling(self, gammalib.GSkyPixel(1.0))
634 636 test_support.pickeling(self, gammalib.GSkyPixel(2.0,3.0))
... ...