Commit fe55dff2b1b5d44a73aae65f28a12bfc5039c9df

Authored by Jürgen Knödlseder
2 parents 187bf8ee e6d15df1

Merge branch '2128-implement-slicing' into integration

# Conflicts:
#	ChangeLog
#	NEWS
#	inst/cta/src/GCTAEventList.cpp
ChangeLog
1   -2017-07-18
  1 +2017-07-22
2 2  
3 3 * Version 1.4.0 released
4 4 =========================
5 5  
6 6 Normalise phase curves by default (#2154)
  7 + Support Python list slicing for container classes (#2128)
7 8 Add GSkyRegions::overlaps() and GSkyMap::overlaps() classes (#1980)
8 9  
9 10  
... ...
1 1 New Features and Important Changes in GammaLib 1.4.0
2 2  
3   -18 July 2017
  3 +22 July 2017
4 4  
5 5  
6 6 1. Introduction
... ... @@ -22,9 +22,16 @@ The following classes have been renamed:
22 22  
23 23 The following methods have been added:
24 24 - GSkyRegion::overlaps(GSkyRegions&)
  25 +- GSkyRegion::type(std::string&)
  26 +- GSkyRegion::name(std::string&)
  27 +- GSkyRegion::solidangle(std::string&)
25 28 - GSkyMap::overlaps(GSkyRegion&)
26 29 - GModelTemporalPhaseCurve::normalize()
27 30 - GModelTemporalPhaseCurve::value(double&)
  31 +- GOptimizerPars::append(GOptimizerPar&)
  32 +- GLATEventList::append(GLATEventAtom&)
  33 +- GLATEventList::reserve(int&)
  34 +- GLATEventList::remove(int&,int&)
28 35  
29 36 The following methods have been removed:
30 37 - n.a.
... ... @@ -84,7 +91,8 @@ None
84 91  
85 92 11. Optimization module
86 93 -----------------------
87   -None
  94 +Add GOptimizerPars::append() method to allow appending of parameters to the
  95 +container.
88 96  
89 97  
90 98 12. Sky module
... ... @@ -96,6 +104,8 @@ container (#1980).
96 104 A GSkyMap::overlaps(GSkyRegions&) method has been added to check the overlap
97 105 of a sky region with a sky map (#1980).
98 106  
  107 +Add methods to set the name, type and solid angle of a sky region.
  108 +
99 109  
100 110 13. Support module
101 111 ------------------
... ... @@ -129,7 +139,7 @@ None
129 139  
130 140 19. Fermi-LAT interface
131 141 ----------------------
132   -None
  142 +Add append(), remove() and reserve() methods to GLATEventList class.
133 143  
134 144  
135 145 20. CTA interface
... ...
include/GOptimizerPars.hpp
1 1 /***************************************************************************
2 2 * GOptimizerPars.hpp - Optimizer parameter container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2015 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -75,6 +75,7 @@ public:
75 75 int nfree(void) const;
76 76 GOptimizerPar* set(const int& index, const GOptimizerPar& par);
77 77 GOptimizerPar* set(const std::string& name, const GOptimizerPar& par);
  78 + GOptimizerPar* append(const GOptimizerPar& par);
78 79 void attach(GOptimizerPar* par);
79 80 void attach(const int& index, GOptimizerPar* par);
80 81 void attach(const std::string& name, GOptimizerPar* par);
... ...
include/GSkyRegion.hpp
1 1 /***************************************************************************
2 2 * GSkyRegion.hpp - Abstract virtual sky region base class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2013-2014 by Pierrick Martin *
  4 + * copyright (C) 2013-2017 by Pierrick Martin *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -80,6 +80,9 @@ public:
80 80 const std::string& type(void) const;
81 81 const std::string& name(void) const;
82 82 const double& solidangle(void) const;
  83 + void type(const std::string& type);
  84 + void name(const std::string& name);
  85 + void solidangle(const double& solidangle);
83 86  
84 87 protected:
85 88 // Protected methods
... ... @@ -109,6 +112,21 @@ const std::string& GSkyRegion::name(void) const
109 112  
110 113  
111 114 /***********************************************************************//**
  115 + * @brief Set region name
  116 + *
  117 + * @param[in] name Region name.
  118 + *
  119 + * Sets the region name.
  120 + ***************************************************************************/
  121 +inline
  122 +void GSkyRegion::name(const std::string& name)
  123 +{
  124 + m_name = name;
  125 + return;
  126 +}
  127 +
  128 +
  129 +/***********************************************************************//**
112 130 * @brief Return region type
113 131 *
114 132 * @return Region type
... ... @@ -123,16 +141,46 @@ const std::string& GSkyRegion::type(void) const
123 141  
124 142  
125 143 /***********************************************************************//**
126   - * @brief Return solid angle
  144 + * @brief Set region type
  145 + *
  146 + * @param[in] type Region type.
  147 + *
  148 + * Sets the region type.
  149 + ***************************************************************************/
  150 +inline
  151 +void GSkyRegion::type(const std::string& type)
  152 +{
  153 + m_type = type;
  154 + return;
  155 +}
  156 +
  157 +
  158 +/***********************************************************************//**
  159 + * @brief Return solid angle of region
127 160 *
128   - * @return Solid angle
  161 + * @return Solid angle of region.
129 162 *
130   - * Returns the solid angle subtended by the region (in steradian).
  163 + * Returns the solid angle subtended by the region (in steradians).
131 164 ***************************************************************************/
132 165 inline
133 166 const double& GSkyRegion::solidangle(void) const
134 167 {
135 168 return (m_solid);
136 169 }
137   -
  170 +
  171 +
  172 +/***********************************************************************//**
  173 + * @brief Set solid angle of region
  174 + *
  175 + * @param[in] solidangle Solid angle of region (in steradians).
  176 + *
  177 + * Sets the solid angle subtended by the region (in steradians).
  178 + ***************************************************************************/
  179 +inline
  180 +void GSkyRegion::solidangle(const double& solidangle)
  181 +{
  182 + m_solid = solidangle;
  183 + return;
  184 +}
  185 +
138 186 #endif /* GSKYREGION_HPP */
... ...
inst/cta/pyext/GCTAEventList.i
... ... @@ -90,19 +90,64 @@ public:
90 90 * @brief GCTAEventList class extension
91 91 ***************************************************************************/
92 92 %extend GCTAEventList {
93   - GCTAEventList copy() {
94   - return (*self);
95   - }
96   - GCTAEventAtom* __getitem__(int index) {
97   - if (index >= 0 && index < self->size())
  93 + GCTAEventAtom* __getitem__(const int& index) {
  94 + // Counting from start, e.g. [2]
  95 + if (index >= 0 && index < self->size()) {
98 96 return (*self)[index];
99   - else
100   - throw GException::out_of_range("__getitem__(int)", index, self->size());
  97 + }
  98 + // Counting from end, e.g. [-1]
  99 + else if (index < 0 && self->size()+index >= 0) {
  100 + return (*self)[self->size()+index];
  101 + }
  102 + else {
  103 + throw GException::out_of_range("__getitem__(int)", "Event index",
  104 + index, self->size());
  105 + }
  106 + }
  107 + GCTAEventList* __getitem__(PyObject *param) {
  108 + if (PySlice_Check(param)) {
  109 + Py_ssize_t start = 0;
  110 + Py_ssize_t stop = 0;
  111 + Py_ssize_t step = 0;
  112 + Py_ssize_t len = self->size();
  113 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  114 + GCTAEventList* list = new GCTAEventList;
  115 + if (step > 0) {
  116 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  117 + list->append(*(*self)[i]);
  118 + }
  119 + }
  120 + else {
  121 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  122 + list->append(*(*self)[i]);
  123 + }
  124 + }
  125 + return list;
  126 + }
  127 + else {
  128 + throw GException::invalid_argument("__getitem__(PyObject)",
  129 + "Invalid slice indices");
  130 + }
  131 + }
  132 + else {
  133 + throw GException::invalid_argument("__getitem__(PyObject)","");
  134 + }
101 135 }
102   - void __setitem__(int index, const GCTAEventAtom& val) {
103   - if (index>=0 && index < self->size())
104   - *((*self)[index]) = val;
105   - else
106   - throw GException::out_of_range("__setitem__(int)", index, self->size());
  136 + void __setitem__(const int& index, const GCTAEventAtom& event) {
  137 + // Counting from start, e.g. [2]
  138 + if (index >= 0 && index < self->size()) {
  139 + *(*self)[index] = event;
  140 + }
  141 + // Counting from end, e.g. [-1]
  142 + else if (index < 0 && self->size()+index >= 0) {
  143 + *(*self)[self->size()+index] = event;
  144 + }
  145 + else {
  146 + throw GException::out_of_range("__setitem__(int)", "Event index",
  147 + index, self->size());
  148 + }
  149 + }
  150 + GCTAEventList copy() {
  151 + return (*self);
107 152 }
108 153 };
... ...
inst/cta/test/test_CTA.py
... ... @@ -20,6 +20,7 @@
20 20 import os
21 21 import gammalib
22 22 import math
  23 +import test_support
23 24  
24 25  
25 26 # ================================== #
... ... @@ -27,12 +28,12 @@ import math
27 28 # ================================== #
28 29 class Test(gammalib.GPythonTestSuite):
29 30 """
30   - Test class for GammaLib CTA module.
  31 + Test class for GammaLib CTA module
31 32 """
32 33 # Constructor
33 34 def __init__(self):
34 35 """
35   - Constructor.
  36 + Constructor
36 37 """
37 38 # Call base class constructor
38 39 gammalib.GPythonTestSuite.__init__(self)
... ... @@ -44,28 +45,58 @@ class Test(gammalib.GPythonTestSuite):
44 45 # Return
45 46 return
46 47  
47   - # Set test functions
48   - def set(self):
  48 + # Setup GCTAEventList container
  49 + def _setup_eventlist(self):
49 50 """
50   - Set all test functions.
  51 + Setup GCTAEventList container
  52 +
  53 + Returns
  54 + -------
  55 + list : `~gammalib.GCTAEventList`
  56 + GCTAEventList container
51 57 """
52   - # Set test name
53   - self.name('CTA')
  58 + # Setup event list container
  59 + list = gammalib.GCTAEventList()
  60 + atom = gammalib.GCTAEventAtom()
  61 + for i in range(10):
  62 + atom.energy().MeV(float(i))
  63 + list.append(atom)
  64 +
  65 + # Return event list container
  66 + return list
  67 +
  68 + # Test GCTAEventList class access operators
  69 + def _test_eventlist_access(self):
  70 + """
  71 + Test GCTAEventList class observation access
  72 + """
  73 + # Setup event list container
  74 + list = self._setup_eventlist()
54 75  
55   - # Append tests
56   - self.append(self.test_aeff, 'Test CTA effective area classes')
57   - self.append(self.test_psf, 'Test CTA PSF classes')
58   - self.append(self.test_edisp, 'Test CTA energy dispersion classes')
59   - self.append(self.test_response, 'Test CTA response classes')
60   - self.append(self.test_onoff, 'Test CTA On/Off analysis')
  76 + # Perform event list access tests
  77 + test_support._energy_container_access_index(self, list)
  78 +
  79 + # Return
  80 + return
  81 +
  82 + # Test GCTAEventList class slicing
  83 + def _test_eventlist_slicing(self):
  84 + """
  85 + Test GCTAEventList class slicing
  86 + """
  87 + # Setup event list container
  88 + list = self._setup_eventlist()
  89 +
  90 + # Perform slicing tests
  91 + test_support._energy_container_slicing(self, list)
61 92  
62 93 # Return
63 94 return
64 95  
65 96 # Test effective area response
66   - def test_aeff(self):
  97 + def _test_aeff(self):
67 98 """
68   - Test GCTAAeff classes.
  99 + Test GCTAAeff classes
69 100 """
70 101 # Test GCTAAeff2D file constructor
71 102 filename = self._caldb + '/prod1_gauss.fits'
... ... @@ -119,9 +150,9 @@ class Test(gammalib.GPythonTestSuite):
119 150 return
120 151  
121 152 # Test point spread function response
122   - def test_psf(self):
  153 + def _test_psf(self):
123 154 """
124   - Test GCTAPsf classes.
  155 + Test GCTAPsf classes
125 156 """
126 157 # Test GCTAPsf2D file constructor
127 158 filename = self._caldb + '/prod1_gauss.fits'
... ... @@ -175,9 +206,9 @@ class Test(gammalib.GPythonTestSuite):
175 206 return
176 207  
177 208 # Test energy dispersion
178   - def test_edisp(self):
  209 + def _test_edisp(self):
179 210 """
180   - Test GCTAEdisp classes.
  211 + Test GCTAEdisp classes
181 212 """
182 213 # Test GCTAEdispRmf file constructor
183 214 filename = self._caldb + '/dc1/rmf.fits'
... ... @@ -222,7 +253,7 @@ class Test(gammalib.GPythonTestSuite):
222 253 # 0.5, 0.005)
223 254  
224 255 # Test response
225   - def test_response(self):
  256 + def _test_response(self):
226 257 """
227 258 Test response classes
228 259 """
... ... @@ -234,9 +265,9 @@ class Test(gammalib.GPythonTestSuite):
234 265 return
235 266  
236 267 # Test On/Off analysis
237   - def test_onoff(self):
  268 + def _test_onoff(self):
238 269 """
239   - Test On/Off analysis.
  270 + Test On/Off analysis
240 271 """
241 272 # Create On region
242 273 crab = gammalib.GSkyDir()
... ... @@ -271,9 +302,6 @@ class Test(gammalib.GPythonTestSuite):
271 302 lm = gammalib.GOptimizerLM()
272 303 outobs.optimize(lm)
273 304 outobs.errors(lm)
274   - #print(lm)
275   - #print(outobs)
276   - #print(outobs.models())
277 305  
278 306 # Test On/Off model fitting results
279 307 sky = outobs.models()['Crab']
... ... @@ -307,3 +335,23 @@ class Test(gammalib.GPythonTestSuite):
307 335  
308 336 # Return
309 337 return
  338 +
  339 + # Set test functions
  340 + def set(self):
  341 + """
  342 + Set all test functions.
  343 + """
  344 + # Set test name
  345 + self.name('CTA')
  346 +
  347 + # Append tests
  348 + self.append(self._test_eventlist_access, 'Test GCTAEventList event access')
  349 + self.append(self._test_eventlist_slicing, 'Test GCTAEventList slicing')
  350 + self.append(self._test_aeff, 'Test CTA effective area classes')
  351 + self.append(self._test_psf, 'Test CTA PSF classes')
  352 + self.append(self._test_edisp, 'Test CTA energy dispersion classes')
  353 + self.append(self._test_response, 'Test CTA response classes')
  354 + self.append(self._test_onoff, 'Test CTA On/Off analysis')
  355 +
  356 + # Return
  357 + return
... ...
inst/lat/include/GLATEventList.hpp
... ... @@ -61,7 +61,7 @@ public:
61 61 virtual ~GLATEventList(void);
62 62  
63 63 // Operators
64   - virtual GLATEventList& operator= (const GLATEventList& list);
  64 + virtual GLATEventList& operator=(const GLATEventList& list);
65 65 virtual GLATEventAtom* operator[](const int& index);
66 66 virtual const GLATEventAtom* operator[](const int& index) const;
67 67  
... ... @@ -81,6 +81,9 @@ public:
81 81 virtual std::string print(const GChatter& chatter = NORMAL) const;
82 82  
83 83 // Other methods
  84 + void append(const GLATEventAtom& event);
  85 + void reserve(const int& number);
  86 + void remove(const int& index, const int& number = 1);
84 87  
85 88 protected:
86 89 // Protected methods
... ... @@ -93,13 +96,13 @@ protected:
93 96 void read_ds_keys(const GFitsHDU& hdu);
94 97  
95 98 // Protected members
96   - GLATRoi m_roi; //!< Region of interest
97   - std::vector<GLATEventAtom> m_events; //!< Events
98   - std::vector<std::string> m_difrsp_label; //!< Diffuse response model labels
99   - std::vector<std::string> m_ds_type; //!< Data selection types
100   - std::vector<std::string> m_ds_unit; //!< Data selection units
101   - std::vector<std::string> m_ds_value; //!< Data selection values
102   - std::vector<std::string> m_ds_reference; //!< Data selection references
  99 + GLATRoi m_roi; //!< Region of interest
  100 + std::vector<GLATEventAtom> m_events; //!< Events
  101 + std::vector<std::string> m_difrsp_label; //!< Diffuse response model labels
  102 + std::vector<std::string> m_ds_type; //!< Data selection types
  103 + std::vector<std::string> m_ds_unit; //!< Data selection units
  104 + std::vector<std::string> m_ds_value; //!< Data selection values
  105 + std::vector<std::string> m_ds_reference; //!< Data selection references
103 106 };
104 107  
105 108  
... ... @@ -150,4 +153,19 @@ const GLATRoi&amp; GLATEventList::roi(void) const
150 153 return m_roi;
151 154 }
152 155  
  156 +
  157 +/***********************************************************************//**
  158 + * @brief Reserves space for events
  159 + *
  160 + * @param[in] number Number of events.
  161 + *
  162 + * Reserves space for number events in the event list.
  163 + ***************************************************************************/
  164 +inline
  165 +void GLATEventList::reserve(const int& number)
  166 +{
  167 + m_events.reserve(number);
  168 + return;
  169 +}
  170 +
153 171 #endif /* GLATEVENTLIST_HPP */
... ...
inst/lat/pyext/GLATEventList.i
1 1 /***************************************************************************
2 2 * GLATEventList.i - Fermi/LAT event list class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2012-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2012-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -56,6 +56,11 @@ public:
56 56 virtual int number(void) const;
57 57 virtual void roi(const GRoi& roi);
58 58 virtual const GLATRoi& roi(void) const;
  59 +
  60 + // Other methods
  61 + void append(const GLATEventAtom& event);
  62 + void reserve(const int& number);
  63 + void remove(const int& index, const int& number = 1);
59 64 };
60 65  
61 66  
... ... @@ -63,25 +68,64 @@ public:
63 68 * @brief GLATEventList class extension
64 69 ***************************************************************************/
65 70 %extend GLATEventList {
66   - GLATEventList copy() {
67   - return (*self);
68   - }
69 71 GLATEventAtom* __getitem__(const int& index) {
  72 + // Counting from start, e.g. [2]
70 73 if (index >= 0 && index < self->size()) {
71   - return ((*self)[index]);
  74 + return (*self)[index];
  75 + }
  76 + // Counting from end, e.g. [-1]
  77 + else if (index < 0 && self->size()+index >= 0) {
  78 + return (*self)[self->size()+index];
72 79 }
73 80 else {
74 81 throw GException::out_of_range("__getitem__(int)", "Event index",
75 82 index, self->size());
76 83 }
77 84 }
78   - void __setitem__(const int& index, const GLATEventAtom& value) {
79   - if (index>=0 && index < self->size()) {
80   - *((*self)[index]) = value;
  85 + GLATEventList* __getitem__(PyObject *param) {
  86 + if (PySlice_Check(param)) {
  87 + Py_ssize_t start = 0;
  88 + Py_ssize_t stop = 0;
  89 + Py_ssize_t step = 0;
  90 + Py_ssize_t len = self->size();
  91 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  92 + GLATEventList* list = new GLATEventList;
  93 + if (step > 0) {
  94 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  95 + list->append(*(*self)[i]);
  96 + }
  97 + }
  98 + else {
  99 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  100 + list->append(*(*self)[i]);
  101 + }
  102 + }
  103 + return list;
  104 + }
  105 + else {
  106 + throw GException::invalid_argument("__getitem__(PyObject)",
  107 + "Invalid slice indices");
  108 + }
  109 + }
  110 + else {
  111 + throw GException::invalid_argument("__getitem__(PyObject)","");
  112 + }
  113 + }
  114 + void __setitem__(const int& index, const GLATEventAtom& event) {
  115 + // Counting from start, e.g. [2]
  116 + if (index >= 0 && index < self->size()) {
  117 + *(*self)[index] = event;
  118 + }
  119 + // Counting from end, e.g. [-1]
  120 + else if (index < 0 && self->size()+index >= 0) {
  121 + *(*self)[self->size()+index] = event;
81 122 }
82 123 else {
83 124 throw GException::out_of_range("__setitem__(int)", "Event index",
84 125 index, self->size());
85 126 }
86 127 }
  128 + GLATEventList copy() {
  129 + return (*self);
  130 + }
87 131 };
... ...
inst/lat/src/GLATEventList.cpp
... ... @@ -384,9 +384,56 @@ void GLATEventList::roi(const GRoi&amp; roi)
384 384  
385 385  
386 386 /***********************************************************************//**
  387 + * @brief Append event to event list
  388 + *
  389 + * @param[in] event Event.
  390 + *
  391 + * Appends an event to the end of the event list.
  392 + ***************************************************************************/
  393 +void GLATEventList::append(const GLATEventAtom& event)
  394 +{
  395 + // Append event
  396 + m_events.push_back(event);
  397 +
  398 + // Return
  399 + return;
  400 +}
  401 +
  402 +
  403 +/***********************************************************************//**
  404 + * @brief Remove events from event list
  405 + *
  406 + * @param[in] index Index from which on events should be removed.
  407 + * @param[in] number Number of event to remove (default: 1).
  408 + *
  409 + * Removes events from the event list. This method does nothing if @p index
  410 + * points beyond the event list. The method does also gently accept
  411 + * @p number arguments where @p index + @p number reach beyond the event
  412 + * list. In that case, all events from event @p index on will be removed.
  413 + ***************************************************************************/
  414 +void GLATEventList::remove(const int& index, const int& number)
  415 +{
  416 + // Continue only if index is valid
  417 + if (index < size()) {
  418 +
  419 + // Determine number of elements to remove
  420 + int n_remove = (index + number > size()) ? size() - index : number;
  421 +
  422 + // Remove events
  423 + m_events.erase(m_events.begin() + index,
  424 + m_events.begin() + index + n_remove);
  425 +
  426 + } // endif: index was valid
  427 +
  428 + // Return
  429 + return;
  430 +}
  431 +
  432 +
  433 +/***********************************************************************//**
387 434 * @brief Print event list information
388 435 *
389   - * @param[in] chatter Chattiness (defaults to NORMAL).
  436 + * @param[in] chatter Chattiness.
390 437 * @return String containing event list information.
391 438 ***************************************************************************/
392 439 std::string GLATEventList::print(const GChatter& chatter) const
... ...
inst/lat/test/test_LAT.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib LAT module.
3 3 #
4   -# Copyright (C) 2012-2015 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2017 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -18,6 +18,7 @@
18 18 #
19 19 # ==========================================================================
20 20 import gammalib
  21 +import test_support
21 22  
22 23  
23 24 # ================================== #
... ... @@ -25,12 +26,12 @@ import gammalib
25 26 # ================================== #
26 27 class Test(gammalib.GPythonTestSuite):
27 28 """
28   - Test class for GammaLib LAT module.
  29 + Test class for GammaLib LAT module
29 30 """
30 31 # Constructor
31 32 def __init__(self):
32 33 """
33   - Constructor.
  34 + Constructor
34 35 """
35 36 # Call base class constructor
36 37 gammalib.GPythonTestSuite.__init__(self)
... ... @@ -38,24 +39,65 @@ class Test(gammalib.GPythonTestSuite):
38 39 # Return
39 40 return
40 41  
41   - # Set test functions
42   - def set(self):
  42 + # Setup GLATEventList container
  43 + def _setup_eventlist(self):
43 44 """
44   - Set all test functions.
  45 + Setup GLATEventList container
  46 +
  47 + Returns
  48 + -------
  49 + list : `~gammalib.GLATEventList`
  50 + GLATEventList container
45 51 """
46   - # Set test name
47   - self.name("LAT")
  52 + # Setup event list container
  53 + list = gammalib.GLATEventList()
  54 + atom = gammalib.GLATEventAtom()
  55 + for i in range(10):
  56 + atom.energy().MeV(float(i))
  57 + list.append(atom)
48 58  
49   - # Append tests
50   - self.append(self.test, "LAT dummy test")
  59 + # Return event list container
  60 + return list
  61 +
  62 + # Test GLATEventList class access operators
  63 + def _test_eventlist_access(self):
  64 + """
  65 + Test GLATEventList class observation access
  66 + """
  67 + # Setup event list container
  68 + list = self._setup_eventlist()
  69 +
  70 + # Perform event list access tests
  71 + test_support._energy_container_access_index(self, list)
  72 +
  73 + # Return
  74 + return
  75 +
  76 + # Test GLATEventList class slicing
  77 + def _test_eventlist_slicing(self):
  78 + """
  79 + Test GLATEventList class slicing
  80 + """
  81 + # Setup event list container
  82 + list = self._setup_eventlist()
  83 +
  84 + # Perform slicing tests
  85 + test_support._energy_container_slicing(self, list)
51 86  
52 87 # Return
53 88 return
54 89  
55   - # Test function
56   - def test(self):
  90 + # Set test functions
  91 + def set(self):
57 92 """
58   - Test function.
  93 + Set all test functions.
59 94 """
  95 + # Set test name
  96 + self.name('LAT')
  97 +
  98 + # Append tests
  99 + self.append(self._test_eventlist_access, 'Test GLATEventList event access')
  100 + self.append(self._test_eventlist_slicing, 'Test GLATEventList slicing')
  101 +
60 102 # Return
61 103 return
... ...
pyext/GApplicationPars.i
1 1 /***************************************************************************
2 2 * GApplicationPars.i - Application parameter container *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -36,7 +36,7 @@
36 36 *
37 37 * @brief Application parameter container class
38 38 ***************************************************************************/
39   -class GApplicationPars : public GBase {
  39 +class GApplicationPars : public GContainer {
40 40  
41 41 public:
42 42 // Constructors and destructors
... ... @@ -76,9 +76,14 @@ public:
76 76 ***************************************************************************/
77 77 %extend GApplicationPars {
78 78 GApplicationPar& __getitem__(const int& index) {
  79 + // Counting from start, e.g. [2]
79 80 if (index >= 0 && index < self->size()) {
80 81 return (*self)[index];
81 82 }
  83 + // Counting from end, e.g. [-1]
  84 + else if (index < 0 && self->size()+index >= 0) {
  85 + return (*self)[self->size()+index];
  86 + }
82 87 else {
83 88 throw GException::out_of_range("__getitem__(int)", index, self->size());
84 89 }
... ... @@ -86,11 +91,45 @@ public:
86 91 GApplicationPar& __getitem__(const std::string& name) {
87 92 return (*self)[name];
88 93 }
  94 + GApplicationPars* __getitem__(PyObject *param) {
  95 + if (PySlice_Check(param)) {
  96 + Py_ssize_t start = 0;
  97 + Py_ssize_t stop = 0;
  98 + Py_ssize_t step = 0;
  99 + Py_ssize_t len = self->size();
  100 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  101 + GApplicationPars* pars = new GApplicationPars;
  102 + if (step > 0) {
  103 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  104 + pars->append((*self)[i]);
  105 + }
  106 + }
  107 + else {
  108 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  109 + pars->append((*self)[i]);
  110 + }
  111 + }
  112 + return pars;
  113 + }
  114 + else {
  115 + throw GException::invalid_argument("__getitem__(PyObject)",
  116 + "Invalid slice indices");
  117 + }
  118 + }
  119 + else {
  120 + throw GException::invalid_argument("__getitem__(PyObject)","");
  121 + }
  122 + }
89 123 void __setitem__(const int& index, const GApplicationPar& par) {
90   - if (index>=0 && index < self->size()) {
  124 + // Counting from start, e.g. [2]
  125 + if (index >= 0 && index < self->size()) {
91 126 (*self)[index] = par;
92 127 return;
93 128 }
  129 + // Counting from end, e.g. [-1]
  130 + else if (index < 0 && self->size()+index >= 0) {
  131 + (*self)[self->size()+index] = par;
  132 + }
94 133 else {
95 134 throw GException::out_of_range("__setitem__(int)", index, self->size());
96 135 }
... ...
pyext/GEbounds.i
... ... @@ -93,6 +93,35 @@ public:
93 93 * @brief GEbounds class extension
94 94 ***************************************************************************/
95 95 %extend GEbounds {
  96 + GEbounds* __getitem__(PyObject *param) {
  97 + if (PySlice_Check(param)) {
  98 + Py_ssize_t start = 0;
  99 + Py_ssize_t stop = 0;
  100 + Py_ssize_t step = 0;
  101 + Py_ssize_t len = self->size();
  102 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  103 + GEbounds* ebounds = new GEbounds;
  104 + if (step > 0) {
  105 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  106 + ebounds->append(self->emin(i), self->emax(i));
  107 + }
  108 + }
  109 + else {
  110 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  111 + ebounds->append(self->emin(i), self->emax(i));
  112 + }
  113 + }
  114 + return ebounds;
  115 + }
  116 + else {
  117 + throw GException::invalid_argument("__getitem__(PyObject)",
  118 + "Invalid slice indices");
  119 + }
  120 + }
  121 + else {
  122 + throw GException::invalid_argument("__getitem__(PyObject)","");
  123 + }
  124 + }
96 125 GEbounds copy() {
97 126 return (*self);
98 127 }
... ...
pyext/GEnergies.i
... ... @@ -79,17 +79,55 @@ public:
79 79 ***************************************************************************/
80 80 %extend GEnergies {
81 81 GEnergy& __getitem__(const int& index) {
  82 + // Counting from start, e.g. [2]
82 83 if (index >= 0 && index < self->size()) {
83 84 return (*self)[index];
84 85 }
  86 + // Counting from end, e.g. [-1]
  87 + else if (index < 0 && self->size()+index >= 0) {
  88 + return (*self)[self->size()+index];
  89 + }
85 90 else {
86 91 throw GException::out_of_range("__getitem__(int)", index, self->size());
87 92 }
88 93 }
  94 + GEnergies* __getitem__(PyObject *param) {
  95 + if (PySlice_Check(param)) {
  96 + Py_ssize_t start = 0;
  97 + Py_ssize_t stop = 0;
  98 + Py_ssize_t step = 0;
  99 + Py_ssize_t len = self->size();
  100 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  101 + GEnergies* energies = new GEnergies;
  102 + if (step > 0) {
  103 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  104 + energies->append((*self)[i]);
  105 + }
  106 + }
  107 + else {
  108 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  109 + energies->append((*self)[i]);
  110 + }
  111 + }
  112 + return energies;
  113 + }
  114 + else {
  115 + throw GException::invalid_argument("__getitem__(PyObject)",
  116 + "Invalid slice indices");
  117 + }
  118 + }
  119 + else {
  120 + throw GException::invalid_argument("__getitem__(PyObject)","");
  121 + }
  122 + }
89 123 void __setitem__(const int& index, const GEnergy& val) {
90   - if (index>=0 && index < self->size()) {
  124 + // Counting from start, e.g. [2]
  125 + if (index >= 0 && index < self->size()) {
91 126 (*self)[index] = val;
92   - return;
  127 + }
  128 + // Counting from end, e.g. [-1]
  129 + else if (index < 0 && self->size()+index >= 0) {
  130 + (*self)[self->size()+index] = val;
93 131 }
94 132 else {
95 133 throw GException::out_of_range("__setitem__(int)", index, self->size());
... ...
pyext/GFits.i
1 1 /***************************************************************************
2 2 * GFits.i - FITS file class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2008-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2008-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -100,9 +100,14 @@ public:
100 100 ***************************************************************************/
101 101 %extend GFits {
102 102 GFitsHDU* __getitem__(const int& extno) {
  103 + // Counting from start, e.g. [2]
103 104 if (extno >= 0 && extno < self->size()) {
104 105 return (*self)[extno];
105 106 }
  107 + // Counting from end, e.g. [-1]
  108 + else if (extno < 0 && self->size()+extno >= 0) {
  109 + return (*self)[self->size()+extno];
  110 + }
106 111 else {
107 112 throw GException::out_of_range("__getitem__(int)",
108 113 "Extension number",
... ... @@ -112,10 +117,43 @@ public:
112 117 GFitsHDU* __getitem__(const std::string& extname) {
113 118 return (*self)[extname];
114 119 }
  120 + GFits* __getitem__(PyObject *param) {
  121 + if (PySlice_Check(param)) {
  122 + Py_ssize_t start = 0;
  123 + Py_ssize_t stop = 0;
  124 + Py_ssize_t step = 0;
  125 + Py_ssize_t len = self->size();
  126 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  127 + GFits* fits = new GFits;
  128 + if (step > 0) {
  129 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  130 + fits->append(*(*self)[i]);
  131 + }
  132 + }
  133 + else {
  134 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  135 + fits->append(*(*self)[i]);
  136 + }
  137 + }
  138 + return fits;
  139 + }
  140 + else {
  141 + throw GException::invalid_argument("__getitem__(PyObject)",
  142 + "Invalid slice indices");
  143 + }
  144 + }
  145 + else {
  146 + throw GException::invalid_argument("__getitem__(PyObject)","");
  147 + }
  148 + }
115 149 void __setitem__(const int& extno, const GFitsHDU& hdu) {
  150 + // Counting from start, e.g. [2]
116 151 if (extno >= 0 && extno < self->size()) {
117 152 self->set(extno, hdu);
118   - return;
  153 + }
  154 + // Counting from end, e.g. [-1]
  155 + else if (extno < 0 && self->size()+extno >= 0) {
  156 + self->set(self->size()+extno, hdu);
119 157 }
120 158 else {
121 159 throw GException::out_of_range("__setitem__(int)",
... ...
pyext/GFitsHeader.i
1 1 /***************************************************************************
2   - * GFitsHeader.i - FITS header cards container class *
  2 + * GFitsHeader.i - FITS header cards container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2008-2015 by Juergen Knoedlseder *
  4 + * copyright (C) 2008-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -29,15 +29,13 @@
29 29 #include "GTools.hpp"
30 30 %}
31 31  
32   -//%include stl.i
33   -
34 32  
35 33 /***********************************************************************//**
36 34 * @class GFitsHeader
37 35 *
38 36 * @brief Interface for FITS header class
39 37 ***************************************************************************/
40   -class GFitsHeader : public GBase {
  38 +class GFitsHeader : public GContainer {
41 39 public:
42 40 // Constructors and destructors
43 41 GFitsHeader(void);
... ... @@ -77,9 +75,14 @@ public:
77 75 ***************************************************************************/
78 76 %extend GFitsHeader {
79 77 GFitsHeaderCard& __getitem__(const int& cardno) {
  78 + // Counting from start, e.g. [2]
80 79 if (cardno >= 0 && cardno < self->size()) {
81 80 return (*self)[cardno];
82 81 }
  82 + // Counting from end, e.g. [-1]
  83 + else if (cardno < 0 && self->size()+cardno >= 0) {
  84 + return (*self)[self->size()+cardno];
  85 + }
83 86 else {
84 87 throw GException::out_of_range("__getitem__(int)",
85 88 "Header card number",
... ... @@ -89,10 +92,43 @@ public:
89 92 GFitsHeaderCard& __getitem__(const std::string& keyname) {
90 93 return (*self)[keyname];
91 94 }
  95 + GFitsHeader* __getitem__(PyObject *param) {
  96 + if (PySlice_Check(param)) {
  97 + Py_ssize_t start = 0;
  98 + Py_ssize_t stop = 0;
  99 + Py_ssize_t step = 0;
  100 + Py_ssize_t len = self->size();
  101 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  102 + GFitsHeader* header = new GFitsHeader;
  103 + if (step > 0) {
  104 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  105 + header->append((*self)[i]);
  106 + }
  107 + }
  108 + else {
  109 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  110 + header->append((*self)[i]);
  111 + }
  112 + }
  113 + return header;
  114 + }
  115 + else {
  116 + throw GException::invalid_argument("__getitem__(PyObject)",
  117 + "Invalid slice indices");
  118 + }
  119 + }
  120 + else {
  121 + throw GException::invalid_argument("__getitem__(PyObject)","");
  122 + }
  123 + }
92 124 void __setitem__(const int& cardno, const GFitsHeaderCard& card) {
  125 + // Counting from start, e.g. [2]
93 126 if (cardno >= 0 && cardno < self->size()) {
94 127 (*self)[cardno] = card;
95   - return;
  128 + }
  129 + // Counting from end, e.g. [-1]
  130 + else if (cardno < 0 && self->size()+cardno >= 0) {
  131 + (*self)[self->size()+cardno] = card;
96 132 }
97 133 else {
98 134 throw GException::out_of_range("__setitem__(int)",
... ...
pyext/GGti.i
... ... @@ -85,8 +85,34 @@ public:
85 85 * @brief GGti class extension
86 86 ***************************************************************************/
87 87 %extend GGti {
88   - int __len__() {
89   - return (self->size());
  88 + GGti* __getitem__(PyObject *param) {
  89 + if (PySlice_Check(param)) {
  90 + Py_ssize_t start = 0;
  91 + Py_ssize_t stop = 0;
  92 + Py_ssize_t step = 0;
  93 + Py_ssize_t len = self->size();
  94 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  95 + GGti* gti = new GGti;
  96 + if (step > 0) {
  97 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  98 + gti->append(self->tstart(i), self->tstop(i));
  99 + }
  100 + }
  101 + else {
  102 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  103 + gti->append(self->tstart(i), self->tstop(i));
  104 + }
  105 + }
  106 + return gti;
  107 + }
  108 + else {
  109 + throw GException::invalid_argument("__getitem__(PyObject)",
  110 + "Invalid slice indices");
  111 + }
  112 + }
  113 + else {
  114 + throw GException::invalid_argument("__getitem__(PyObject)","");
  115 + }
90 116 }
91 117 GGti copy() {
92 118 return (*self);
... ...
pyext/GModels.i
1 1 /***************************************************************************
2 2 * GModels.i - Model container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -79,9 +79,14 @@ public:
79 79 ***************************************************************************/
80 80 %extend GModels {
81 81 GModel* __getitem__(const int& index) {
  82 + // Counting from start, e.g. [2]
82 83 if (index >= 0 && index < self->size()) {
83 84 return (*self)[index];
84 85 }
  86 + // Counting from end, e.g. [-1]
  87 + else if (index < 0 && self->size()+index >= 0) {
  88 + return (*self)[self->size()+index];
  89 + }
85 90 else {
86 91 throw GException::out_of_range("__getitem__(int)", "Model index",
87 92 index, self->size());
... ... @@ -90,10 +95,43 @@ public:
90 95 GModel* __getitem__(const std::string& name) {
91 96 return (*self)[name];
92 97 }
  98 + GModels* __getitem__(PyObject *param) {
  99 + if (PySlice_Check(param)) {
  100 + Py_ssize_t start = 0;
  101 + Py_ssize_t stop = 0;
  102 + Py_ssize_t step = 0;
  103 + Py_ssize_t len = self->size();
  104 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  105 + GModels* models = new GModels;
  106 + if (step > 0) {
  107 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  108 + models->append(*(*self)[i]);
  109 + }
  110 + }
  111 + else {
  112 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  113 + models->append(*(*self)[i]);
  114 + }
  115 + }
  116 + return models;
  117 + }
  118 + else {
  119 + throw GException::invalid_argument("__getitem__(PyObject)",
  120 + "Invalid slice indices");
  121 + }
  122 + }
  123 + else {
  124 + throw GException::invalid_argument("__getitem__(PyObject)","");
  125 + }
  126 + }
93 127 void __setitem__(const int& index, const GModel& val) {
  128 + // Counting from start, e.g. [2]
94 129 if (index >= 0 && index < self->size()) {
95 130 self->set(index, val);
96   - return;
  131 + }
  132 + // Counting from end, e.g. [-1]
  133 + else if (index < 0 && self->size()+index >= 0) {
  134 + self->set(self->size()+index, val);
97 135 }
98 136 else {
99 137 throw GException::out_of_range("__setitem__(int)", "Model index",
... ...
pyext/GNodeArray.i
... ... @@ -86,17 +86,55 @@ public:
86 86 ***************************************************************************/
87 87 %extend GNodeArray {
88 88 double __getitem__(const int& index) {
  89 + // Counting from start, e.g. [2]
89 90 if (index >= 0 && index < self->size()) {
90 91 return (*self)[index];
91 92 }
  93 + // Counting from end, e.g. [-1]
  94 + else if (index < 0 && self->size()+index >= 0) {
  95 + return (*self)[self->size()+index];
  96 + }
92 97 else {
93 98 throw GException::out_of_range("__getitem__(int)", index, self->size());
94 99 }
95 100 }
  101 + GNodeArray* __getitem__(PyObject *param) {
  102 + if (PySlice_Check(param)) {
  103 + Py_ssize_t start = 0;
  104 + Py_ssize_t stop = 0;
  105 + Py_ssize_t step = 0;
  106 + Py_ssize_t len = self->size();
  107 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  108 + GNodeArray* nodes = new GNodeArray;
  109 + if (step > 0) {
  110 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  111 + nodes->append((*self)[i]);
  112 + }
  113 + }
  114 + else {
  115 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  116 + nodes->append((*self)[i]);
  117 + }
  118 + }
  119 + return nodes;
  120 + }
  121 + else {
  122 + throw GException::invalid_argument("__getitem__(PyObject)",
  123 + "Invalid slice indices");
  124 + }
  125 + }
  126 + else {
  127 + throw GException::invalid_argument("__getitem__(PyObject)","");
  128 + }
  129 + }
96 130 void __setitem__(const int& index, const double& val) {
97   - if (index>=0 && index < self->size()) {
  131 + // Counting from start, e.g. [2]
  132 + if (index >= 0 && index < self->size()) {
98 133 (*self)[index] = val;
99   - return;
  134 + }
  135 + // Counting from end, e.g. [-1]
  136 + else if (index < 0 && self->size()+index >= 0) {
  137 + (*self)[self->size()+index] = val;
100 138 }
101 139 else {
102 140 throw GException::out_of_range("__setitem__(int)", index, self->size());
... ...
pyext/GObservations.i
1 1 /***************************************************************************
2 2 * GObservations.i - Observations container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2008-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2008-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -108,17 +108,56 @@ typedef GObservations::likelihood likelihood;
108 108 ***************************************************************************/
109 109 %extend GObservations {
110 110 GObservation* __getitem__(const int& index) {
  111 + // Counting from start, e.g. [2]
111 112 if (index >= 0 && index < self->size()) {
112 113 return (*self)[index];
113 114 }
  115 + // Counting from end, e.g. [-1]
  116 + else if (index < 0 && self->size()+index >= 0) {
  117 + return (*self)[self->size()+index];
  118 + }
114 119 else {
115 120 throw GException::out_of_range("__getitem__(int)", index, self->size());
116 121 }
117 122 }
  123 + GObservations* __getitem__(PyObject *param) {
  124 + if (PySlice_Check(param)) {
  125 + Py_ssize_t start = 0;
  126 + Py_ssize_t stop = 0;
  127 + Py_ssize_t step = 0;
  128 + Py_ssize_t len = self->size();
  129 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  130 + GObservations* obs = new GObservations;
  131 + obs->models(self->models()); // Copy over model container
  132 + if (step > 0) {
  133 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  134 + obs->append(*(*self)[i]);
  135 + }
  136 + }
  137 + else {
  138 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  139 + obs->append(*(*self)[i]);
  140 + }
  141 + }
  142 + return obs;
  143 + }
  144 + else {
  145 + throw GException::invalid_argument("__getitem__(PyObject)",
  146 + "Invalid slice indices");
  147 + }
  148 + }
  149 + else {
  150 + throw GException::invalid_argument("__getitem__(PyObject)","");
  151 + }
  152 + }
118 153 void __setitem__(const int& index, const GObservation& val) {
119   - if (index>=0 && index < self->size()) {
  154 + // Counting from start, e.g. [2]
  155 + if (index >= 0 && index < self->size()) {
120 156 self->set(index, val);
121   - return;
  157 + }
  158 + // Counting from end, e.g. [-1]
  159 + else if (index < 0 && self->size()+index >= 0) {
  160 + self->set(self->size()+index, val);
122 161 }
123 162 else {
124 163 throw GException::out_of_range("__setitem__(int)", index, self->size());
... ...
pyext/GOptimizerPars.i
1 1 /***************************************************************************
2 2 * GOptimizerPars.i - Optimizer parameter container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2015 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -52,6 +52,7 @@ public:
52 52 int nfree(void) const;
53 53 GOptimizerPar* set(const int& index, const GOptimizerPar& par);
54 54 GOptimizerPar* set(const std::string& name, const GOptimizerPar& par);
  55 + GOptimizerPar* append(const GOptimizerPar& par);
55 56 void attach(GOptimizerPar *par);
56 57 void attach(const int& index, GOptimizerPar* par);
57 58 void attach(const std::string& name, GOptimizerPar* par);
... ... @@ -70,9 +71,14 @@ public:
70 71 ***************************************************************************/
71 72 %extend GOptimizerPars {
72 73 GOptimizerPar* __getitem__(const int& index) {
  74 + // Counting from start, e.g. [2]
73 75 if (index >= 0 && index < self->size()) {
74 76 return (*self)[index];
75 77 }
  78 + // Counting from end, e.g. [-1]
  79 + else if (index < 0 && self->size()+index >= 0) {
  80 + return (*self)[self->size()+index];
  81 + }
76 82 else {
77 83 throw GException::out_of_range("__getitem__(int)", "Parameter index",
78 84 index, self->size());
... ... @@ -81,10 +87,43 @@ public:
81 87 GOptimizerPar* __getitem__(const std::string& name) {
82 88 return (*self)[name];
83 89 }
  90 + GOptimizerPars* __getitem__(PyObject *param) {
  91 + if (PySlice_Check(param)) {
  92 + Py_ssize_t start = 0;
  93 + Py_ssize_t stop = 0;
  94 + Py_ssize_t step = 0;
  95 + Py_ssize_t len = self->size();
  96 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  97 + GOptimizerPars* pars = new GOptimizerPars;
  98 + if (step > 0) {
  99 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  100 + pars->attach((*self)[i]);
  101 + }
  102 + }
  103 + else {
  104 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  105 + pars->attach((*self)[i]);
  106 + }
  107 + }
  108 + return pars;
  109 + }
  110 + else {
  111 + throw GException::invalid_argument("__getitem__(PyObject)",
  112 + "Invalid slice indices");
  113 + }
  114 + }
  115 + else {
  116 + throw GException::invalid_argument("__getitem__(PyObject)","");
  117 + }
  118 + }
84 119 void __setitem__(const int& index, GOptimizerPar* par) {
  120 + // Counting from start, e.g. [2]
85 121 if (index >= 0 && index < self->size()) {
86 122 self->attach(index, par);
87   - return;
  123 + }
  124 + // Counting from end, e.g. [-1]
  125 + else if (index < 0 && self->size()+index >= 0) {
  126 + self->attach(self->size()+index, par);
88 127 }
89 128 else {
90 129 throw GException::out_of_range("__setitem__(int)", "Parameter index",
... ...
pyext/GPhases.i
... ... @@ -63,8 +63,34 @@ public:
63 63 * @brief GPhases class extension
64 64 ***************************************************************************/
65 65 %extend GPhases {
66   - int __len__() {
67   - return (self->size());
  66 + GPhases* __getitem__(PyObject *param) {
  67 + if (PySlice_Check(param)) {
  68 + Py_ssize_t start = 0;
  69 + Py_ssize_t stop = 0;
  70 + Py_ssize_t step = 0;
  71 + Py_ssize_t len = self->size();
  72 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  73 + GPhases* phases = new GPhases;
  74 + if (step > 0) {
  75 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  76 + phases->append(self->pmin(i), self->pmax(i));
  77 + }
  78 + }
  79 + else {
  80 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  81 + phases->append(self->pmin(i), self->pmax(i));
  82 + }
  83 + }
  84 + return phases;
  85 + }
  86 + else {
  87 + throw GException::invalid_argument("__getitem__(PyObject)",
  88 + "Invalid slice indices");
  89 + }
  90 + }
  91 + else {
  92 + throw GException::invalid_argument("__getitem__(PyObject)","");
  93 + }
68 94 }
69 95 GPhases copy() {
70 96 return (*self);
... ...
pyext/GPhotons.i
... ... @@ -60,17 +60,55 @@ public:
60 60 ***************************************************************************/
61 61 %extend GPhotons {
62 62 GPhoton& __getitem__(const int& index) {
  63 + // Counting from start, e.g. [2]
63 64 if (index >= 0 && index < self->size()) {
64 65 return (*self)[index];
65 66 }
  67 + // Counting from end, e.g. [-1]
  68 + else if (index < 0 && self->size()+index >= 0) {
  69 + return (*self)[self->size()+index];
  70 + }
66 71 else {
67 72 throw GException::out_of_range("__getitem__(int)", index, self->size());
68 73 }
69 74 }
  75 + GPhotons* __getitem__(PyObject *param) {
  76 + if (PySlice_Check(param)) {
  77 + Py_ssize_t start = 0;
  78 + Py_ssize_t stop = 0;
  79 + Py_ssize_t step = 0;
  80 + Py_ssize_t len = self->size();
  81 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  82 + GPhotons* photons = new GPhotons;
  83 + if (step > 0) {
  84 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  85 + photons->append((*self)[i]);
  86 + }
  87 + }
  88 + else {
  89 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  90 + photons->append((*self)[i]);
  91 + }
  92 + }
  93 + return photons;
  94 + }
  95 + else {
  96 + throw GException::invalid_argument("__getitem__(PyObject)",
  97 + "Invalid slice indices");
  98 + }
  99 + }
  100 + else {
  101 + throw GException::invalid_argument("__getitem__(PyObject)","");
  102 + }
  103 + }
70 104 void __setitem__(const int& index, const GPhoton& val) {
71   - if (index>=0 && index < self->size()) {
  105 + // Counting from start, e.g. [2]
  106 + if (index >= 0 && index < self->size()) {
72 107 (*self)[index] = val;
73   - return;
  108 + }
  109 + // Counting from end, e.g. [-1]
  110 + else if (index < 0 && self->size()+index >= 0) {
  111 + (*self)[self->size()+index] = val;
74 112 }
75 113 else {
76 114 throw GException::out_of_range("__setitem__(int)", index, self->size());
... ...
pyext/GSkyRegion.i
1 1 /***************************************************************************
2 2 * GSkyRegion.i - Sky region class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2013-2015 by Michael Mayer *
  4 + * copyright (C) 2013-2017 by Michael Mayer *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -55,6 +55,9 @@ public:
55 55 const std::string& type(void) const;
56 56 const std::string& name(void) const;
57 57 const double& solidangle(void) const;
  58 + void type(const std::string& type);
  59 + void name(const std::string& name);
  60 + void solidangle(const double& solidangle);
58 61 };
59 62  
60 63  
... ...
pyext/GSkyRegions.i
... ... @@ -68,17 +68,55 @@ public:
68 68 ***************************************************************************/
69 69 %extend GSkyRegions {
70 70 GSkyRegion* __getitem__(const int& index) {
  71 + // Counting from start, e.g. [2]
71 72 if (index >= 0 && index < self->size()) {
72 73 return (*self)[index];
73 74 }
  75 + // Counting from end, e.g. [-1]
  76 + else if (index < 0 && self->size()+index >= 0) {
  77 + return (*self)[self->size()+index];
  78 + }
74 79 else {
75 80 throw GException::out_of_range("__getitem__(int)", index, self->size());
76 81 }
77 82 }
  83 + GSkyRegions* __getitem__(PyObject *param) {
  84 + if (PySlice_Check(param)) {
  85 + Py_ssize_t start = 0;
  86 + Py_ssize_t stop = 0;
  87 + Py_ssize_t step = 0;
  88 + Py_ssize_t len = self->size();
  89 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  90 + GSkyRegions* regions = new GSkyRegions;
  91 + if (step > 0) {
  92 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  93 + regions->append(*(*self)[i]);
  94 + }
  95 + }
  96 + else {
  97 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  98 + regions->append(*(*self)[i]);
  99 + }
  100 + }
  101 + return regions;
  102 + }
  103 + else {
  104 + throw GException::invalid_argument("__getitem__(PyObject)",
  105 + "Invalid slice indices");
  106 + }
  107 + }
  108 + else {
  109 + throw GException::invalid_argument("__getitem__(PyObject)","");
  110 + }
  111 + }
78 112 void __setitem__(const int& index, const GSkyRegion& val) {
79   - if (index>=0 && index < self->size()) {
  113 + // Counting from start, e.g. [2]
  114 + if (index >= 0 && index < self->size()) {
80 115 self->set(index, val);
81   - return;
  116 + }
  117 + // Counting from end, e.g. [-1]
  118 + else if (index < 0 && self->size()+index >= 0) {
  119 + self->set(self->size()+index, val);
82 120 }
83 121 else {
84 122 throw GException::out_of_range("__setitem__(int)", index, self->size());
... ...
pyext/GTestSuites.i
1 1 /***************************************************************************
2 2 * GTestSuites.i - Test suite container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2012-2016 Jean-Baptiste Cayrou *
  4 + * copyright (C) 2012-2017 Jean-Baptiste Cayrou *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -73,17 +73,55 @@ public:
73 73 ***************************************************************************/
74 74 %extend GTestSuites {
75 75 GTestSuite* __getitem__(const int& index) {
  76 + // Counting from start, e.g. [2]
76 77 if (index >= 0 && index < self->size()) {
77 78 return (*self)[index];
78 79 }
  80 + // Counting from end, e.g. [-1]
  81 + else if (index < 0 && self->size()+index >= 0) {
  82 + return (*self)[self->size()+index];
  83 + }
79 84 else {
80 85 throw GException::out_of_range("__getitem__(int)", index, self->size());
81 86 }
82 87 }
  88 + GTestSuites* __getitem__(PyObject *param) {
  89 + if (PySlice_Check(param)) {
  90 + Py_ssize_t start = 0;
  91 + Py_ssize_t stop = 0;
  92 + Py_ssize_t step = 0;
  93 + Py_ssize_t len = self->size();
  94 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  95 + GTestSuites* tests = new GTestSuites(self->name());
  96 + if (step > 0) {
  97 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  98 + tests->append(*(*self)[i]);
  99 + }
  100 + }
  101 + else {
  102 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  103 + tests->append(*(*self)[i]);
  104 + }
  105 + }
  106 + return tests;
  107 + }
  108 + else {
  109 + throw GException::invalid_argument("__getitem__(PyObject)",
  110 + "Invalid slice indices");
  111 + }
  112 + }
  113 + else {
  114 + throw GException::invalid_argument("__getitem__(PyObject)","");
  115 + }
  116 + }
83 117 void __setitem__(const int& index, const GTestSuite& suite) {
  118 + // Counting from start, e.g. [2]
84 119 if (index >= 0 && index < self->size()) {
85 120 self->set(index, suite);
86   - return;
  121 + }
  122 + // Counting from end, e.g. [-1]
  123 + else if (index < 0 && self->size()+index >= 0) {
  124 + self->set(self->size()+index, suite);
87 125 }
88 126 else {
89 127 throw GException::out_of_range("__setitem__(int)", index, self->size());
... ...
pyext/GTimes.i
1 1 /***************************************************************************
2 2 * GTimes.i - Time container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2012-2015 by Juergen Knoedlseder *
  4 + * copyright (C) 2012-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -62,17 +62,55 @@ public:
62 62 ***************************************************************************/
63 63 %extend GTimes {
64 64 GTime& __getitem__(const int& index) {
  65 + // Counting from start, e.g. [2]
65 66 if (index >= 0 && index < self->size()) {
66 67 return (*self)[index];
67 68 }
  69 + // Counting from end, e.g. [-1]
  70 + else if (index < 0 && self->size()+index >= 0) {
  71 + return (*self)[self->size()+index];
  72 + }
68 73 else {
69 74 throw GException::out_of_range("__getitem__(int)", index, self->size());
70 75 }
71 76 }
  77 + GTimes* __getitem__(PyObject *param) {
  78 + if (PySlice_Check(param)) {
  79 + Py_ssize_t start = 0;
  80 + Py_ssize_t stop = 0;
  81 + Py_ssize_t step = 0;
  82 + Py_ssize_t len = self->size();
  83 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  84 + GTimes* times = new GTimes;
  85 + if (step > 0) {
  86 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  87 + times->append((*self)[i]);
  88 + }
  89 + }
  90 + else {
  91 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  92 + times->append((*self)[i]);
  93 + }
  94 + }
  95 + return times;
  96 + }
  97 + else {
  98 + throw GException::invalid_argument("__getitem__(PyObject)",
  99 + "Invalid slice indices");
  100 + }
  101 + }
  102 + else {
  103 + throw GException::invalid_argument("__getitem__(PyObject)","");
  104 + }
  105 + }
72 106 void __setitem__(const int& index, const GTime& val) {
73   - if (index>=0 && index < self->size()) {
  107 + // Counting from start, e.g. [2]
  108 + if (index >= 0 && index < self->size()) {
74 109 (*self)[index] = val;
75   - return;
  110 + }
  111 + // Counting from end, e.g. [-1]
  112 + else if (index < 0 && self->size()+index >= 0) {
  113 + (*self)[self->size()+index] = val;
76 114 }
77 115 else {
78 116 throw GException::out_of_range("__setitem__(int)", index, self->size());
... ...
pyext/GXml.i
1 1 /***************************************************************************
2 2 * GXml.i - XML class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -74,27 +74,60 @@ public:
74 74 ***************************************************************************/
75 75 %extend GXml {
76 76 GXmlNode* __getitem__(const int& index) {
  77 + // Counting from start, e.g. [2]
77 78 if (index >= 0 && index < self->size()) {
78 79 return (*self)[index];
79 80 }
  81 + // Counting from end, e.g. [-1]
  82 + else if (index < 0 && self->size()+index >= 0) {
  83 + return (*self)[self->size()+index];
  84 + }
80 85 else {
81   - throw GException::out_of_range("__getitem__(int)", index,
82   - 0, self->size()-1);
  86 + throw GException::out_of_range("__getitem__(int)", index, self->size());
  87 + }
  88 + }
  89 + GXml* __getitem__(PyObject *param) {
  90 + if (PySlice_Check(param)) {
  91 + Py_ssize_t start = 0;
  92 + Py_ssize_t stop = 0;
  93 + Py_ssize_t step = 0;
  94 + Py_ssize_t len = self->size();
  95 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  96 + GXml* xml = new GXml;
  97 + if (step > 0) {
  98 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  99 + xml->append(*(*self)[i]);
  100 + }
  101 + }
  102 + else {
  103 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  104 + xml->append(*(*self)[i]);
  105 + }
  106 + }
  107 + return xml;
  108 + }
  109 + else {
  110 + throw GException::invalid_argument("__getitem__(PyObject)",
  111 + "Invalid slice indices");
  112 + }
  113 + }
  114 + else {
  115 + throw GException::invalid_argument("__getitem__(PyObject)","");
83 116 }
84 117 }
85 118 void __setitem__(const int& index, const GXmlNode& node) {
  119 + // Counting from start, e.g. [2]
86 120 if (index >= 0 && index < self->size()) {
87 121 self->set(index, node);
88   - return;
  122 + }
  123 + // Counting from end, e.g. [-1]
  124 + else if (index < 0 && self->size()+index >= 0) {
  125 + self->set(self->size()+index, node);
89 126 }
90 127 else {
91   - throw GException::out_of_range("__setitem__(int)", index,
92   - 0, self->size()-1);
  128 + throw GException::out_of_range("__setitem__(int)", index, self->size());
93 129 }
94 130 }
95   - int __len__() {
96   - return (self->size());
97   - }
98 131 GXml copy() {
99 132 return (*self);
100 133 }
... ...
pyext/GXmlElement.i
1 1 /***************************************************************************
2 2 * GXmlElement.i - XML element node class definition *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -61,6 +61,61 @@ public:
61 61 * @brief GXmlElement class extension
62 62 ***************************************************************************/
63 63 %extend GXmlElement {
  64 + GXmlNode* __getitem__(const int& index) {
  65 + // Counting from start, e.g. [2]
  66 + if (index >= 0 && index < self->size()) {
  67 + return (*self)[index];
  68 + }
  69 + // Counting from end, e.g. [-1]
  70 + else if (index < 0 && self->size()+index >= 0) {
  71 + return (*self)[self->size()+index];
  72 + }
  73 + else {
  74 + throw GException::out_of_range("__getitem__(int)", index, self->size());
  75 + }
  76 + }
  77 + void __setitem__(const int& index, const GXmlNode& node) {
  78 + // Counting from start, e.g. [2]
  79 + if (index >= 0 && index < self->size()) {
  80 + self->set(index, node);
  81 + }
  82 + // Counting from end, e.g. [-1]
  83 + else if (index < 0 && self->size()+index >= 0) {
  84 + self->set(self->size()+index, node);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__setitem__(int)", index, self->size());
  88 + }
  89 + }
  90 + GXmlElement* __getitem__(PyObject *param) {
  91 + if (PySlice_Check(param)) {
  92 + Py_ssize_t start = 0;
  93 + Py_ssize_t stop = 0;
  94 + Py_ssize_t step = 0;
  95 + Py_ssize_t len = self->size();
  96 + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) {
  97 + GXmlElement* element = new GXmlElement;
  98 + if (step > 0) {
  99 + for (int i = (int)start; i < (int)stop; i += (int)step) {
  100 + element->append(*(*self)[i]);
  101 + }
  102 + }
  103 + else {
  104 + for (int i = (int)start; i > (int)stop; i += (int)step) {
  105 + element->append(*(*self)[i]);
  106 + }
  107 + }
  108 + return element;
  109 + }
  110 + else {
  111 + throw GException::invalid_argument("__getitem__(PyObject)",
  112 + "Invalid slice indices");
  113 + }
  114 + }
  115 + else {
  116 + throw GException::invalid_argument("__getitem__(PyObject)","");
  117 + }
  118 + }
64 119 GXmlElement copy() {
65 120 return (*self);
66 121 }
... ...
pyext/GXmlNode.i
1 1 /***************************************************************************
2 2 * GXmlNode.i - Abstract XML node base class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -36,7 +36,7 @@
36 36 *
37 37 * @brief Abstract XML node base class
38 38 ***************************************************************************/
39   -class GXmlNode : public GBase {
  39 +class GXmlNode : public GContainer {
40 40 public:
41 41 // Constructors and destructors
42 42 GXmlNode(void);
... ... @@ -89,25 +89,29 @@ public:
89 89 return gammalib::tochar(self->print(NORMAL, 0));
90 90 }
91 91 GXmlNode* __getitem__(const int& index) {
  92 + // Counting from start, e.g. [2]
92 93 if (index >= 0 && index < self->size()) {
93 94 return (*self)[index];
94 95 }
  96 + // Counting from end, e.g. [-1]
  97 + else if (index < 0 && self->size()+index >= 0) {
  98 + return (*self)[self->size()+index];
  99 + }
95 100 else {
96   - throw GException::out_of_range("__getitem__(int)", index,
97   - 0, self->size()-1);
  101 + throw GException::out_of_range("__getitem__(int)", index, self->size());
98 102 }
99 103 }
100 104 void __setitem__(const int& index, const GXmlNode& node) {
  105 + // Counting from start, e.g. [2]
101 106 if (index >= 0 && index < self->size()) {
102 107 self->set(index, node);
103   - return;
  108 + }
  109 + // Counting from end, e.g. [-1]
  110 + else if (index < 0 && self->size()+index >= 0) {
  111 + self->set(self->size()+index, node);
104 112 }
105 113 else {
106   - throw GException::out_of_range("__setitem__(int)", index,
107   - 0, self->size()-1);
  114 + throw GException::out_of_range("__setitem__(int)", index, self->size());
108 115 }
109 116 }
110   - int __len__() {
111   - return (self->size());
112   - }
113 117 };
... ...
src/model/GModels.cpp
1 1 /***************************************************************************
2 2 * GModels.cpp - Model container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -324,11 +324,11 @@ GModel* GModels::set(const int&amp; index, const GModel&amp; model)
324 324 int inx = get_index(model.name());
325 325 if (inx != -1 && inx != index) {
326 326 std::string msg =
327   - "Attempt to set model with name \""+model.name()+"\" in model"
328   - " container at index "+gammalib::str(index)+", but a model with"
329   - " the same name exists already at index "+gammalib::str(inx)+
330   - " in the container.\n"
331   - "Every model in the model container needs a unique name.";
  327 + "Attempt to set model with name \""+model.name()+"\" in model "
  328 + "container at index "+gammalib::str(index)+", but a model with "
  329 + "the same name exists already at index "+gammalib::str(inx)+
  330 + " in the container. Every model in the model container needs a "
  331 + "unique name.";
332 332 throw GException::invalid_value(G_SET1, msg);
333 333 }
334 334  
... ...
src/opt/GOptimizerPar.cpp
1 1 /***************************************************************************
2 2 * GOptimizerPar.cpp - Optimizer parameter class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2013-2015 by Juergen Knoedlseder *
  4 + * copyright (C) 2013-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -700,8 +700,8 @@ std::string GOptimizerPar::print(const GChatter&amp; chatter) const
700 700 void GOptimizerPar::init_members(void)
701 701 {
702 702 // Initialise members
703   - m_name = "";
704   - m_unit = "";
  703 + m_name.clear();
  704 + m_unit.clear();
705 705 m_factor_value = 0.0;
706 706 m_factor_error = 0.0;
707 707 m_factor_gradient = 0.0;
... ...
src/opt/GOptimizerPars.cpp
1 1 /***************************************************************************
2 2 * GOptimizerPars.cpp - Optimizer parameter container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2013 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2017 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -392,6 +392,30 @@ GOptimizerPar* GOptimizerPars::set(const std::string&amp; name, const GOptimizerPar&amp;
392 392  
393 393  
394 394 /***********************************************************************//**
  395 + * @brief Append parameter to container
  396 + *
  397 + * @param[in] par Parameter reference.
  398 + * @return Pointer to appended parameter.
  399 + *
  400 + * Appends a parameter to the container. The method stores a copy of the
  401 + * parameter in the container, hence the client may delete the parameter
  402 + * after the method is called.
  403 + ***************************************************************************/
  404 +GOptimizerPar* GOptimizerPars::append(const GOptimizerPar& par)
  405 +{
  406 + // Clone parameter
  407 + GOptimizerPar* ptr = par.clone();
  408 +
  409 + // Inserts deep copy of parameter
  410 + m_alloc.push_back(true);
  411 + m_pars.push_back(ptr);
  412 +
  413 + // Return parameter pointer
  414 + return ptr;
  415 +}
  416 +
  417 +
  418 +/***********************************************************************//**
395 419 * @brief Attach parameter to container
396 420 *
397 421 * @param[in] par Parameter pointer.
... ... @@ -680,6 +704,7 @@ std::string GOptimizerPars::print(const GChatter&amp; chatter) const
680 704  
681 705 // Append parameters
682 706 for (int i = 0; i < size(); ++i) {
  707 +std::cout << i << " " << m_pars[i] << std::endl;
683 708 result.append("\n"+m_pars[i]->print(chatter));
684 709 }
685 710  
... ...
test/Makefile.am
... ... @@ -120,7 +120,8 @@ EXTRA_DIST = data reports testinst \
120 120 test_GXml.py \
121 121 test_GXspec.py \
122 122 test_examples.py \
123   - test_python.py
  123 + test_python.py \
  124 + test_support.py
124 125  
125 126 # Standard test sources and links
126 127 test_GSupport_SOURCES = test_GSupport.cpp test_GSupport.hpp
... ...
test/test_GApplication.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib application module
3 3 #
4   -# Copyright (C) 2012-2016 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2017 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -19,6 +19,7 @@
19 19 # ==========================================================================
20 20 import os
21 21 import gammalib
  22 +import test_support
22 23  
23 24  
24 25 # ========================================== #
... ... @@ -42,8 +43,7 @@ class Test(gammalib.GPythonTestSuite):
42 43 # Return
43 44 return
44 45  
45   -
46   - # Private methods
  46 + # Check log file versus a reference
47 47 def _check_log_file(self, ref, calls):
48 48 """
49 49 Check log file versus a reference
... ... @@ -74,24 +74,28 @@ class Test(gammalib.GPythonTestSuite):
74 74 # Return
75 75 return
76 76  
77   -
78   - # Public methods
79   - def set(self):
80   - """
81   - Set all test functions
  77 + # Setup GApplicationPars container
  78 + def _setup_pars(self):
82 79 """
83   - # Set test name
84   - self.name('app')
  80 + Setup GApplicationPars container
85 81  
86   - # Append tests
87   - self.append(self.test_log, 'Test GLog')
88   - self.append(self.test_app, 'Test GApplication')
89   - self.append(self.test_pars, 'Test GApplicationPars')
  82 + Returns
  83 + -------
  84 + pars : `~gammalib.GApplicationPars`
  85 + Parameter container
  86 + """
  87 + # Setup application parameter container
  88 + pars = gammalib.GApplicationPars()
  89 + for i in range(10):
  90 + name = '%s' % i
  91 + par = gammalib.GApplicationPar(name,'r','a','1.0','0.0','2.0','Dummy')
  92 + pars.append(par)
90 93  
91   - # Return
92   - return
  94 + # Return application parameter container
  95 + return pars
93 96  
94   - def test_log(self):
  97 + # Test GLog class
  98 + def _test_log(self):
95 99 """
96 100 Test GLog class
97 101 """
... ... @@ -192,7 +196,8 @@ class Test(gammalib.GPythonTestSuite):
192 196 # Return
193 197 return
194 198  
195   - def test_app(self):
  199 + # Test GApplication class
  200 + def _test_app(self):
196 201 """
197 202 Test GApplication class
198 203 """
... ... @@ -224,7 +229,8 @@ class Test(gammalib.GPythonTestSuite):
224 229 # Return
225 230 return
226 231  
227   - def test_pars(self):
  232 + # Test GApplicationPars class
  233 + def _test_pars(self):
228 234 """
229 235 Test GApplicationPars class
230 236 """
... ... @@ -240,3 +246,59 @@ class Test(gammalib.GPythonTestSuite):
240 246  
241 247 # Return
242 248 return
  249 +
  250 + # Test GApplicationPars class access operators
  251 + def _test_pars_access(self):
  252 + """
  253 + Test GApplicationPars class model access
  254 + """
  255 + # Setup application parameter container
  256 + pars = self._setup_pars()
  257 +
  258 + # Perform application parameter access tests
  259 + test_support._container_access_index(self, pars)
  260 +
  261 + # Check application parameter setting by index from start
  262 + par = gammalib.GApplicationPar('98','r','a','1.0','0.0','2.0','Dummy')
  263 + pars[3] = par
  264 + self.test_value(pars[3].name(), '98')
  265 +
  266 + # Check application parameter setting by index from end
  267 + par = gammalib.GApplicationPar('99','r','a','1.0','0.0','2.0','Dummy')
  268 + pars[-2] = par
  269 + self.test_value(pars[-2].name(), '99')
  270 +
  271 + # Return
  272 + return
  273 +
  274 + # Test GApplicationPars class slicing
  275 + def _test_pars_slicing(self):
  276 + """
  277 + Test GApplicationPars class slicing
  278 + """
  279 + # Setup application parameter container
  280 + pars = self._setup_pars()
  281 +
  282 + # Perform slicing tests
  283 + test_support._container_slicing(self, pars)
  284 +
  285 + # Return
  286 + return
  287 +
  288 + # Set test functions
  289 + def set(self):
  290 + """
  291 + Set all test functions
  292 + """
  293 + # Set test name
  294 + self.name('app')
  295 +
  296 + # Append tests
  297 + self.append(self._test_log, 'Test GLog')
  298 + self.append(self._test_app, 'Test GApplication')
  299 + self.append(self._test_pars, 'Test GApplicationPars')
  300 + self.append(self._test_pars_access, 'Test GApplicationPars parameter access')
  301 + self.append(self._test_pars_access, 'Test GApplicationPars slicing')
  302 +
  303 + # Return
  304 + return
... ...
test/test_GFits.py
... ... @@ -27,11 +27,12 @@ import gammalib
27 27 # =================================== #
28 28 class Test(gammalib.GPythonTestSuite):
29 29 """
30   - Test class for GammaLib FITS module.
  30 + Test class for GammaLib FITS module
31 31 """
  32 + # Constructor
32 33 def __init__(self):
33 34 """
34   - Constructor.
  35 + Constructor
35 36 """
36 37 # Call base class constructor
37 38 gammalib.GPythonTestSuite.__init__(self)
... ... @@ -39,25 +40,236 @@ class Test(gammalib.GPythonTestSuite):
39 40 # Return
40 41 return
41 42  
42   - def set(self):
  43 + # Setup GFits container
  44 + def _setup_fits(self):
  45 + """
  46 + Setup GFits container
  47 +
  48 + Returns
  49 + -------
  50 + fits : `~gammalib.GFits`
  51 + GFits container
43 52 """
44   - Set all test functions.
  53 + # Setup GFits container
  54 + fits = gammalib.GFits()
  55 + image = gammalib.GFitsImageDouble()
  56 + for i in range(10):
  57 + image.extname('%s' % i)
  58 + fits.append(image)
  59 +
  60 + # Return GFits container
  61 + return fits
  62 +
  63 + # Setup GFitsHeader container
  64 + def _setup_header(self):
45 65 """
46   - # Set test name
47   - self.name("fits")
  66 + Setup GFitsHeader container
48 67  
49   - # Append tests
50   - self.append(self.test_fits, "Test GFits class")
51   - self.append(self.test_fits_image, "Test GFitsImage class")
52   - self.append(self.test_fits_table, "Test GFitsTable class")
53   - self.append(self.test_fits_table_columns, "Test GFitsTableCol classes")
  68 + Returns
  69 + -------
  70 + header : `~gammalib.GFitsHeader`
  71 + GFitsHeader container
  72 + """
  73 + # Setup GFitsHeader container
  74 + header = gammalib.GFitsHeader()
  75 + card = gammalib.GFitsHeaderCard()
  76 + for i in range(10):
  77 + card.keyname('%s' % i)
  78 + header.append(card)
  79 +
  80 + # Return GFitsHeader container
  81 + return header
  82 +
  83 + # Test GFits class access operators
  84 + def _test_fits_access(self):
  85 + """
  86 + Test GFits class parameter access
  87 + """
  88 + # Setup GFits container and element
  89 + fits = self._setup_fits()
  90 + image = gammalib.GFitsImageDouble()
  91 +
  92 + # Loop over all elements using the container iterator and count the
  93 + # number of iterations
  94 + niter = 0
  95 + for hdu in fits:
  96 + self.test_value(hdu.extname(), '%s' % niter)
  97 + niter += 1
  98 +
  99 + # Check that looping was successful
  100 + self.test_value(fits.size(), 10, 'Check container size')
  101 + self.test_value(niter, 10, 'Check container iterator')
  102 +
  103 + # Test access from start
  104 + self.test_value(fits[3].extname(), '3')
  105 +
  106 + # Check access from end
  107 + self.test_value(fits[-2].extname(), '8')
  108 +
  109 + # Check parameter setting by index from start
  110 + image.extname('98')
  111 + fits[3] = image
  112 + self.test_value(fits[3].extname(), '98')
  113 +
  114 + # Check parameter setting by index from end
  115 + image.extname('99')
  116 + fits[-2] = image
  117 + self.test_value(fits[-2].extname(), '99')
  118 +
  119 + # Return
  120 + return
  121 +
  122 + # Test GFits class slicing
  123 + def _test_fits_slicing(self):
  124 + """
  125 + Test GFits class slicing
  126 + """
  127 + # Setup XML container
  128 + fits = self._setup_fits()
  129 +
  130 + # Test fits[start:end]
  131 + self.test_value(len(fits[3:5]), 2)
  132 + self.test_value(fits[3:5][0].extname(), '3')
  133 + self.test_value(fits[3:5][1].extname(), '4')
  134 +
  135 + # Test fits[start:]
  136 + self.test_value(len(fits[7:]), 3)
  137 + self.test_value(fits[7:][0].extname(), '7')
  138 + self.test_value(fits[7:][1].extname(), '8')
  139 + self.test_value(fits[7:][2].extname(), '9')
  140 +
  141 + # Test fits[:end]
  142 + self.test_value(len(fits[:2]), 2)
  143 + self.test_value(fits[:2][0].extname(), '0')
  144 + self.test_value(fits[:2][1].extname(), '1')
  145 +
  146 + # Test fits[:]
  147 + self.test_value(len(fits[:]), 10)
  148 + for i in range(10):
  149 + self.test_value(fits[:][i].extname(), '%s' % i)
  150 +
  151 + # Test fits[start:end:step]
  152 + self.test_value(len(fits[3:7:2]), 2)
  153 + self.test_value(fits[3:7:2][0].extname(), '3')
  154 + self.test_value(fits[3:7:2][1].extname(), '5')
  155 +
  156 + # Test fits[start:end:step]
  157 + self.test_value(len(fits[6:3:-2]), 2)
  158 + self.test_value(fits[6:3:-2][0].extname(), '6')
  159 + self.test_value(fits[6:3:-2][1].extname(), '4')
  160 +
  161 + # Test fits[-start:]
  162 + self.test_value(len(fits[-2:]), 2)
  163 + self.test_value(fits[-2:][0].extname(), '8')
  164 + self.test_value(fits[-2:][1].extname(), '9')
  165 +
  166 + # Test fits[:-end]
  167 + self.test_value(len(fits[:-7]), 3)
  168 + self.test_value(fits[:-7][0].extname(), '0')
  169 + self.test_value(fits[:-7][1].extname(), '1')
  170 + self.test_value(fits[:-7][2].extname(), '2')
  171 +
  172 + # Return
  173 + return
  174 +
  175 + # Test GFitsHeader class access operators
  176 + def _test_header_access(self):
  177 + """
  178 + Test GFitsHeader class parameter access
  179 + """
  180 + # Setup FITS header
  181 + header = self._setup_header()
  182 +
  183 + # Loop over all elements using the container iterator and count the
  184 + # number of iterations
  185 + niter = 0
  186 + for card in header:
  187 + self.test_value(card.keyname(), '%s' % niter)
  188 + niter += 1
  189 +
  190 + # Check that looping was successful
  191 + self.test_value(header.size(), 10, 'Check container size')
  192 + self.test_value(niter, 10, 'Check container iterator')
  193 +
  194 + # Test access from start
  195 + self.test_value(header[3].keyname(), '3')
  196 +
  197 + # Check access from end
  198 + self.test_value(header[-2].keyname(), '8')
  199 +
  200 + # Setup header card
  201 + card = gammalib.GFitsHeaderCard()
  202 +
  203 + # Check parameter setting by index from start
  204 + card.keyname('98')
  205 + header[3] = card
  206 + self.test_value(header[3].keyname(), '98')
  207 +
  208 + # Check parameter setting by index from end
  209 + card.keyname('99')
  210 + header[-2] = card
  211 + self.test_value(header[-2].keyname(), '99')
54 212  
55 213 # Return
56 214 return
57 215  
58   - def test_fits(self):
  216 + # Test GFitsHeader class slicing
  217 + def _test_header_slicing(self):
  218 + """
  219 + Test GFitsHeader class slicing
59 220 """
60   - Test GFile class interface.
  221 + # Setup FITS header
  222 + header = self._setup_header()
  223 +
  224 + # Test header[start:end]
  225 + self.test_value(len(header[3:5]), 2)
  226 + self.test_value(header[3:5][0].keyname(), '3')
  227 + self.test_value(header[3:5][1].keyname(), '4')
  228 +
  229 + # Test header[start:]
  230 + self.test_value(len(header[7:]), 3)
  231 + self.test_value(header[7:][0].keyname(), '7')
  232 + self.test_value(header[7:][1].keyname(), '8')
  233 + self.test_value(header[7:][2].keyname(), '9')
  234 +
  235 + # Test header[:end]
  236 + self.test_value(len(header[:2]), 2)
  237 + self.test_value(header[:2][0].keyname(), '0')
  238 + self.test_value(header[:2][1].keyname(), '1')
  239 +
  240 + # Test header[:]
  241 + self.test_value(len(header[:]), 10)
  242 + for i in range(10):
  243 + self.test_value(header[:][i].keyname(), '%s' % i)
  244 +
  245 + # Test header[start:end:step]
  246 + self.test_value(len(header[3:7:2]), 2)
  247 + self.test_value(header[3:7:2][0].keyname(), '3')
  248 + self.test_value(header[3:7:2][1].keyname(), '5')
  249 +
  250 + # Test header[start:end:step]
  251 + self.test_value(len(header[6:3:-2]), 2)
  252 + self.test_value(header[6:3:-2][0].keyname(), '6')
  253 + self.test_value(header[6:3:-2][1].keyname(), '4')
  254 +
  255 + # Test header[-start:]
  256 + self.test_value(len(header[-2:]), 2)
  257 + self.test_value(header[-2:][0].keyname(), '8')
  258 + self.test_value(header[-2:][1].keyname(), '9')
  259 +
  260 + # Test header[:-end]
  261 + self.test_value(len(header[:-7]), 3)
  262 + self.test_value(header[:-7][0].keyname(), '0')
  263 + self.test_value(header[:-7][1].keyname(), '1')
  264 + self.test_value(header[:-7][2].keyname(), '2')
  265 +
  266 + # Return
  267 + return
  268 +
  269 + # Test GFile class interface
  270 + def _test_fits(self):
  271 + """
  272 + Test GFile class interface
61 273 """
62 274 # Get test data directory
63 275 datadir = os.environ['TEST_DATA'] + '/'
... ... @@ -66,33 +278,33 @@ class Test(gammalib.GPythonTestSuite):
66 278 file = gammalib.GFilename(datadir+'file.fits')
67 279  
68 280 # Test loading of FITS file
69   - self.test_try("Test GFits file load constructor")
  281 + self.test_try('Test GFits file load constructor')
70 282 try:
71 283 fits = gammalib.GFits(file)
72 284 self.test_try_success()
73 285 except:
74   - self.test_try_failure("Unable to load FITS file.")
  286 + self.test_try_failure('Unable to load FITS file.')
75 287  
76 288 # Test creation of FITS file
77   - self.test_try("Test GFits file creation constructor")
  289 + self.test_try('Test GFits file creation constructor')
78 290 try:
79   - fits = gammalib.GFits("test_file.fits", True)
  291 + fits = gammalib.GFits('test_file.fits', True)
80 292 self.test_try_success()
81 293 except:
82   - self.test_try_failure("Unable to create FITS file.")
  294 + self.test_try_failure('Unable to create FITS file.')
83 295  
84 296 # Open FITS file
85 297 fits = gammalib.GFits(file)
86   - self.test_value(fits["EVENTS"].nrows(), 1231, "Check number of rows")
  298 + self.test_value(fits['EVENTS'].nrows(), 1231, 'Check number of rows')
87 299  
88 300 # Open FITS file with event selection
89   - fits = gammalib.GFits(file+"[EVENTS][ENERGY>1.0]")
90   - self.test_value(fits["EVENTS"].nrows(), 152, "Check number of rows")
  301 + fits = gammalib.GFits(file+'[EVENTS][ENERGY>1.0]')
  302 + self.test_value(fits['EVENTS'].nrows(), 152, 'Check number of rows')
91 303  
92 304 # Open FITS file with non-existing extension name
93   - self.test_try("Test non-existing extension name")
  305 + self.test_try('Test non-existing extension name')
94 306 try:
95   - fits = gammalib.GFits(file+"[DUMMY][ENERGY>1.0]")
  307 + fits = gammalib.GFits(file+'[DUMMY][ENERGY>1.0]')
96 308 self.test_try_failure()
97 309 except:
98 310 self.test_try_success()
... ... @@ -100,13 +312,14 @@ class Test(gammalib.GPythonTestSuite):
100 312 # Return
101 313 return
102 314  
103   - def test_fits_image(self):
  315 + # Test GFitsImage class interface
  316 + def _test_fits_image(self):
104 317 """
105   - Test GFitsImage class interface.
  318 + Test GFitsImage class interface
106 319 """
107 320 # Set test file names
108   - file1 = gammalib.GFilename("test_python_fits_image_v1.fits")
109   - file2 = gammalib.GFilename("test_python_fits_image_v2.fits")
  321 + file1 = gammalib.GFilename('test_python_fits_image_v1.fits')
  322 + file2 = gammalib.GFilename('test_python_fits_image_v2.fits')
110 323  
111 324 # Remove test files
112 325 file1.remove()
... ... @@ -138,15 +351,15 @@ class Test(gammalib.GPythonTestSuite):
138 351 img7[x, y] = x + y * nx
139 352 img8[x, y] = x + y * nx
140 353 img9[x, y] = x + y * nx
141   - img1.extname("Byte")
142   - img2.extname("Double")
143   - img3.extname("Float")
144   - img4.extname("Long")
145   - img5.extname("LongLong")
146   - img6.extname("SByte")
147   - img7.extname("Short")
148   - img8.extname("ULong")
149   - img9.extname("UShort")
  354 + img1.extname('Byte')
  355 + img2.extname('Double')
  356 + img3.extname('Float')
  357 + img4.extname('Long')
  358 + img5.extname('LongLong')
  359 + img6.extname('SByte')
  360 + img7.extname('Short')
  361 + img8.extname('ULong')
  362 + img9.extname('UShort')
150 363  
151 364 # Test image types by checking the bitpix values
152 365 self.test_value(img1.bitpix(), 8)
... ... @@ -172,9 +385,9 @@ class Test(gammalib.GPythonTestSuite):
172 385  
173 386 # Set header keywords
174 387 img_byte = fits.image(0)
175   - img_byte.card("test", "test-value", "this is for testing")
176   - img_byte.card("real", 3.1415, "a real value")
177   - img_byte.card("int", 41, "an integer value")
  388 + img_byte.card('test', 'test-value', 'this is for testing')
  389 + img_byte.card('real', 3.1415, 'a real value')
  390 + img_byte.card('int', 41, 'an integer value')
178 391  
179 392 # Save FITS file
180 393 fits.save()
... ... @@ -198,7 +411,7 @@ class Test(gammalib.GPythonTestSuite):
198 411  
199 412 # Get double precision image, take square root of pixel and save in
200 413 # another file
201   - img_double = fits.image("Double")
  414 + img_double = fits.image('Double')
202 415 for x in range(nx):
203 416 for y in range(ny):
204 417 img_double[x, y] = math.sqrt(img_double[x, y])
... ... @@ -232,13 +445,14 @@ class Test(gammalib.GPythonTestSuite):
232 445 # Return
233 446 return
234 447  
235   - def test_fits_table(self):
  448 + # Test GFitsTable class interface
  449 + def _test_fits_table(self):
236 450 """
237   - Test GFitsTable class interface.
  451 + Test GFitsTable class interface
238 452 """
239 453 # Set test file names
240   - file1 = gammalib.GFilename("test_python_fits_table_v1.fits")
241   - file2 = gammalib.GFilename("test_python_fits_table_v2.fits")
  454 + file1 = gammalib.GFilename('test_python_fits_table_v1.fits')
  455 + file2 = gammalib.GFilename('test_python_fits_table_v2.fits')
242 456  
243 457 # Remove test files
244 458 file1.remove()
... ... @@ -249,17 +463,17 @@ class Test(gammalib.GPythonTestSuite):
249 463  
250 464 # Create table columns
251 465 nrows = 10
252   - col1 = gammalib.GFitsTableBitCol("BIT", nrows)
253   - col2 = gammalib.GFitsTableBoolCol("BOOLEAN", nrows)
254   - col3 = gammalib.GFitsTableByteCol("BYTE", nrows)
255   - col4 = gammalib.GFitsTableDoubleCol("DOUBLE", nrows)
256   - col5 = gammalib.GFitsTableFloatCol("FLOAT", nrows)
257   - col6 = gammalib.GFitsTableLongCol("LONG", nrows)
258   - col7 = gammalib.GFitsTableLongLongCol("LONGLONG", nrows)
259   - col8 = gammalib.GFitsTableShortCol("SHORT", nrows)
260   - col9 = gammalib.GFitsTableStringCol("STRING", nrows, 20)
261   - col10 = gammalib.GFitsTableULongCol("ULONG", nrows)
262   - col11 = gammalib.GFitsTableUShortCol("USHORT", nrows)
  466 + col1 = gammalib.GFitsTableBitCol('BIT', nrows)
  467 + col2 = gammalib.GFitsTableBoolCol('BOOLEAN', nrows)
  468 + col3 = gammalib.GFitsTableByteCol('BYTE', nrows)
  469 + col4 = gammalib.GFitsTableDoubleCol('DOUBLE', nrows)
  470 + col5 = gammalib.GFitsTableFloatCol('FLOAT', nrows)
  471 + col6 = gammalib.GFitsTableLongCol('LONG', nrows)
  472 + col7 = gammalib.GFitsTableLongLongCol('LONGLONG', nrows)
  473 + col8 = gammalib.GFitsTableShortCol('SHORT', nrows)
  474 + col9 = gammalib.GFitsTableStringCol('STRING', nrows, 20)
  475 + col10 = gammalib.GFitsTableULongCol('ULONG', nrows)
  476 + col11 = gammalib.GFitsTableUShortCol('USHORT', nrows)
263 477 for i in range(nrows):
264 478 #col1[i] = i % 2 # Old swig version
265 479 #col2[i] = i % 2 # Old swig version
... ... @@ -288,7 +502,7 @@ class Test(gammalib.GPythonTestSuite):
288 502 tbl_ascii.append(col9)
289 503 tbl_ascii.append(col10)
290 504 tbl_ascii.append(col11)
291   - tbl_ascii.extname("ASCII table")
  505 + tbl_ascii.extname('ASCII table')
292 506 fits.append(tbl_ascii)
293 507  
294 508 # Set binary table
... ... @@ -304,7 +518,7 @@ class Test(gammalib.GPythonTestSuite):
304 518 tbl_bin.append(col9)
305 519 tbl_bin.append(col10)
306 520 tbl_bin.append(col11)
307   - tbl_bin.extname("Binary table")
  521 + tbl_bin.extname('Binary table')
308 522 fits.append(tbl_bin)
309 523  
310 524 # Save FITS file
... ... @@ -316,36 +530,37 @@ class Test(gammalib.GPythonTestSuite):
316 530 # Return
317 531 return
318 532  
319   - def test_fits_table_columns(self):
  533 + # Test FITS table columns
  534 + def _test_fits_table_columns(self):
320 535 """
321 536 Test FITS table columns
322 537 """
323 538 # Create table columns
324 539 nrows = 10
325   - col1 = gammalib.GFitsTableBitCol("BIT", nrows)
326   - col2 = gammalib.GFitsTableBoolCol("BOOLEAN", nrows)
327   - col3 = gammalib.GFitsTableByteCol("BYTE", nrows)
328   - col4 = gammalib.GFitsTableDoubleCol("DOUBLE", nrows)
329   - col5 = gammalib.GFitsTableFloatCol("FLOAT", nrows)
330   - col6 = gammalib.GFitsTableLongCol("LONG", nrows)
331   - col7 = gammalib.GFitsTableLongLongCol("LONGLONG", nrows)
332   - col8 = gammalib.GFitsTableShortCol("SHORT", nrows)
333   - col9 = gammalib.GFitsTableStringCol("STRING", nrows, 20)
334   - col10 = gammalib.GFitsTableULongCol("ULONG", nrows)
335   - col11 = gammalib.GFitsTableUShortCol("USHORT", nrows)
  540 + col1 = gammalib.GFitsTableBitCol('BIT', nrows)
  541 + col2 = gammalib.GFitsTableBoolCol('BOOLEAN', nrows)
  542 + col3 = gammalib.GFitsTableByteCol('BYTE', nrows)
  543 + col4 = gammalib.GFitsTableDoubleCol('DOUBLE', nrows)
  544 + col5 = gammalib.GFitsTableFloatCol('FLOAT', nrows)
  545 + col6 = gammalib.GFitsTableLongCol('LONG', nrows)
  546 + col7 = gammalib.GFitsTableLongLongCol('LONGLONG', nrows)
  547 + col8 = gammalib.GFitsTableShortCol('SHORT', nrows)
  548 + col9 = gammalib.GFitsTableStringCol('STRING', nrows, 20)
  549 + col10 = gammalib.GFitsTableULongCol('ULONG', nrows)
  550 + col11 = gammalib.GFitsTableUShortCol('USHORT', nrows)
336 551  
337 552 # Test number of rows
338   - self.test_value(col1.nrows(), nrows, "Check number of rows in Bit column")
339   - self.test_value(col2.nrows(), nrows, "Check number of rows in Boolean column")
340   - self.test_value(col3.nrows(), nrows, "Check number of rows in Byte column")
341   - self.test_value(col4.nrows(), nrows, "Check number of rows in Double column")
342   - self.test_value(col5.nrows(), nrows, "Check number of rows in Float column")
343   - self.test_value(col6.nrows(), nrows, "Check number of rows in Long column")
344   - self.test_value(col7.nrows(), nrows, "Check number of rows in LongLong column")
345   - self.test_value(col8.nrows(), nrows, "Check number of rows in Short column")
346   - self.test_value(col9.nrows(), nrows, "Check number of rows in String column")
347   - self.test_value(col10.nrows(), nrows, "Check number of rows in ULong column")
348   - self.test_value(col11.nrows(), nrows, "Check number of rows in UShort column")
  553 + self.test_value(col1.nrows(), nrows, 'Check number of rows in Bit column')
  554 + self.test_value(col2.nrows(), nrows, 'Check number of rows in Boolean column')
  555 + self.test_value(col3.nrows(), nrows, 'Check number of rows in Byte column')
  556 + self.test_value(col4.nrows(), nrows, 'Check number of rows in Double column')
  557 + self.test_value(col5.nrows(), nrows, 'Check number of rows in Float column')
  558 + self.test_value(col6.nrows(), nrows, 'Check number of rows in Long column')
  559 + self.test_value(col7.nrows(), nrows, 'Check number of rows in LongLong column')
  560 + self.test_value(col8.nrows(), nrows, 'Check number of rows in Short column')
  561 + self.test_value(col9.nrows(), nrows, 'Check number of rows in String column')
  562 + self.test_value(col10.nrows(), nrows, 'Check number of rows in ULong column')
  563 + self.test_value(col11.nrows(), nrows, 'Check number of rows in UShort column')
349 564  
350 565 # Test iterators
351 566 for row in col1:
... ... @@ -373,28 +588,48 @@ class Test(gammalib.GPythonTestSuite):
373 588  
374 589 # Test setting and retrieving of values
375 590 col1[5] = True
376   - self.test_assert(col1[5], "Check Bit column setting and retrieving")
  591 + self.test_assert(col1[5], 'Check Bit column setting and retrieving')
377 592 col2[5] = True
378   - self.test_assert(col2[5], "Check Boolean column setting and retrieving")
  593 + self.test_assert(col2[5], 'Check Boolean column setting and retrieving')
379 594 col3[5] = 5
380   - self.test_value(col3[5], 5, "Check Byte column setting and retrieving")
  595 + self.test_value(col3[5], 5, 'Check Byte column setting and retrieving')
381 596 col4[5] = 3.14
382   - self.test_value(col4[5], 3.14, 1.0e-6, "Check Double column setting and retrieving")
  597 + self.test_value(col4[5], 3.14, 1.0e-6, 'Check Double column setting and retrieving')
383 598 col5[5] = 3.14
384   - self.test_value(col5[5], 3.14, 1.0e-6, "Check Float column setting and retrieving")
  599 + self.test_value(col5[5], 3.14, 1.0e-6, 'Check Float column setting and retrieving')
385 600 col6[5] = 314
386   - self.test_value(col6[5], 314, "Check Long column setting and retrieving")
  601 + self.test_value(col6[5], 314, 'Check Long column setting and retrieving')
387 602 col7[5] = 314
388   - self.test_value(col7[5], 314, "Check LongLong column setting and retrieving")
  603 + self.test_value(col7[5], 314, 'Check LongLong column setting and retrieving')
389 604 col8[5] = 314
390   - self.test_value(col8[5], 314, "Check Short column setting and retrieving")
391   - col9[5] = "Hallo"
392   - self.test_assert(col9[5] == "Hallo", "Check String column setting and retrieving")
  605 + self.test_value(col8[5], 314, 'Check Short column setting and retrieving')
  606 + col9[5] = 'Hallo'
  607 + self.test_assert(col9[5] == 'Hallo', 'Check String column setting and retrieving')
393 608 col10[5] = 314
394   - self.test_value(col10[5], 314, "Check ULong column setting and retrieving")
  609 + self.test_value(col10[5], 314, 'Check ULong column setting and retrieving')
395 610 col11[5] = 314
396   - self.test_value(col11[5], 314, "Check UShort column setting and retrieving")
  611 + self.test_value(col11[5], 314, 'Check UShort column setting and retrieving')
  612 +
  613 + # Return
  614 + return
  615 +
  616 + # Set test functions
  617 + def set(self):
  618 + """
  619 + Set all test functions
  620 + """
  621 + # Set test name
  622 + self.name('fits')
  623 +
  624 + # Append tests
  625 + self.append(self._test_fits, 'Test GFits')
  626 + self.append(self._test_fits_access, 'Test GFits parameter access')
  627 + self.append(self._test_fits_slicing, 'Test GFits slicing')
  628 + self.append(self._test_header_access, 'Test GFitsHeader parameter access')
  629 + self.append(self._test_header_slicing, 'Test GFitsHeader slicing')
  630 + self.append(self._test_fits_image, 'Test GFitsImage')
  631 + self.append(self._test_fits_table, 'Test GFitsTable')
  632 + self.append(self._test_fits_table_columns, 'Test GFitsTableCol')
397 633  
398 634 # Return
399 635 return
400   -
... ...
test/test_GModel.py
... ... @@ -17,8 +17,8 @@
17 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18 #
19 19 # ==========================================================================
20   -import os
21 20 import gammalib
  21 +import test_support
22 22  
23 23  
24 24 # ==================================== #
... ... @@ -36,58 +36,87 @@ class Test(gammalib.GPythonTestSuite):
36 36 # Call base class constructor
37 37 gammalib.GPythonTestSuite.__init__(self)
38 38  
39   - # Set test data directory
40   - self._datadir = os.environ['TEST_DATA']
41   -
42 39 # Return
43 40 return
44 41  
45   - # Set test functions
46   - def set(self):
  42 + # Setup GModels container
  43 + def _setup_models(self):
47 44 """
48   - Set all test functions
  45 + Setup GModels container
  46 +
  47 + Returns
  48 + -------
  49 + models : `~gammalib.GModels`
  50 + Models container
49 51 """
50   - # Set test name
51   - self.name('model')
  52 + # Setup model container
  53 + models = gammalib.GModels()
  54 + model = gammalib.GModelSky()
  55 + for i in range(10):
  56 + model.name('%s' % i)
  57 + models.append(model)
52 58  
53   - # Append tests
54   - self.append(self.test_models, 'Test GModels')
  59 + # Return model container
  60 + return models
  61 +
  62 + # Test GModels class access operators
  63 + def _test_models_access(self):
  64 + """
  65 + Test GModels class model access
  66 + """
  67 + # Setup model container and sky model
  68 + models = self._setup_models()
  69 + model = gammalib.GModelSky()
  70 +
  71 + # Perform model access tests
  72 + test_support._container_access_index(self, models)
  73 +
  74 + # Check model getting by name
  75 + self.test_value(models['7'].name(), '7')
  76 +
  77 + # Check model setting by name
  78 + model.name('Test name')
  79 + models['3'] = model
  80 + self.test_value(models['Test name'].name(), 'Test name')
  81 +
  82 + # Check model setting by index from start
  83 + model.name('Test index from start')
  84 + models[1] = model
  85 + self.test_value(models[1].name(), 'Test index from start')
  86 +
  87 + # Check model setting by index from end
  88 + model.name('Test index from end')
  89 + models[-2] = model
  90 + self.test_value(models[-2].name(), 'Test index from end')
55 91  
56 92 # Return
57 93 return
58 94  
59   - # Test function
60   - def test_models(self):
  95 + # Test GModels class slicing
  96 + def _test_models_slicing(self):
61 97 """
62   - Test GModels class
  98 + Test GModels class slicing
63 99 """
64   - # Set model filename
65   - filename = self._datadir + '/model_point_plaw.xml'
  100 + # Setup models container
  101 + models = self._setup_models()
66 102  
67   - # Read model container and create a copy of its first model (the
68   - # copy is needed since the model container will go out of scope
69   - # later)
70   - models = gammalib.GModels(filename)
71   - model = models[0].copy()
72   - name = model.name()
  103 + # Perform slicing tests
  104 + test_support._container_slicing(self, models)
73 105  
74   - # Create an empty model container
75   - models = gammalib.GModels()
  106 + # Return
  107 + return
  108 +
  109 + # Set test functions
  110 + def set(self):
  111 + """
  112 + Set all test functions
  113 + """
  114 + # Set test name
  115 + self.name('model')
  116 +
  117 + # Append tests
  118 + self.append(self._test_models_access, 'Test GModels model access')
  119 + self.append(self._test_models_slicing, 'Test GModels slicing')
76 120  
77   - # Append 10 identical models to model container
78   - for i in range(10):
79   - model.name(name+'_'+str(i))
80   - models.append(model)
81   -
82   - # Loop over all models using the container iterator and count the
83   - # number of iterations
84   - nmodels = 0
85   - for model in models:
86   - nmodels += 1
87   -
88   - # Check that looping was successful
89   - self.test_value(models.size(), 10, 'Check model container size')
90   - self.test_value(nmodels, 10, 'Check model iterator')
91   -
92 121 # Return
93 122 return
... ...
test/test_GObservation.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib observation module.
3 3 #
4   -# Copyright (C) 2012-2016 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2017 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -18,6 +18,7 @@
18 18 #
19 19 # ==========================================================================
20 20 import gammalib
  21 +import test_support
21 22  
22 23  
23 24 # ========================================== #
... ... @@ -38,24 +39,119 @@ class Test(gammalib.GPythonTestSuite):
38 39 # Return
39 40 return
40 41  
41   - # Set test functions
42   - def set(self):
  42 + # Setup GObservations container
  43 + def _setup_obs(self):
43 44 """
44   - Set all test functions
  45 + Setup GObservations container
  46 +
  47 + Returns
  48 + -------
  49 + obs : `~gammalib.GObservations`
  50 + Observation container
45 51 """
46   - # Set test name
47   - self.name('obs')
  52 + # Setup observation container
  53 + obs = gammalib.GObservations()
  54 + run = gammalib.GCTAObservation()
  55 + for i in range(10):
  56 + run.name('%s' % i)
  57 + run.id('%s' % i)
  58 + obs.append(run)
  59 +
  60 + # Setup model container
  61 + models = gammalib.GModels()
  62 + model = gammalib.GModelSky()
  63 + for i in range(10):
  64 + model.name('%s' % i)
  65 + models.append(model)
  66 +
  67 + # Set observation's model container
  68 + obs.models(models)
  69 +
  70 + # Return observations container
  71 + return obs
  72 +
  73 + # Setup GTimes container
  74 + def _setup_times(self):
  75 + """
  76 + Setup GTimes container
48 77  
49   - # Append tests
50   - self.append(self.test_energy, 'Test GEnergy class')
51   - self.append(self.test_energies, 'Test GEnergies class')
52   - self.append(self.test_time, 'Test GTime class')
  78 + Returns
  79 + -------
  80 + times : `~gammalib.GTimes`
  81 + GTime container
  82 + """
  83 + # Setup time container
  84 + times = gammalib.GTimes()
  85 + time = gammalib.GTime()
  86 + for i in range(10):
  87 + time.secs(float(i))
  88 + times.append(time)
  89 +
  90 + # Return times container
  91 + return times
  92 +
  93 + # Setup GGti container
  94 + def _setup_gti(self):
  95 + """
  96 + Setup GGti container
53 97  
54   - # Return
55   - return
  98 + Returns
  99 + -------
  100 + gti : `~gammalib.GGti`
  101 + GGti container
  102 + """
  103 + # Setup GTI container
  104 + gti = gammalib.GGti()
  105 + for i in range(10):
  106 + tstart = gammalib.GTime(float(i), 'sec')
  107 + tstop = gammalib.GTime(float(i+1), 'sec')
  108 + gti.append(tstart, tstop)
  109 +
  110 + # Return GTI container
  111 + return gti
  112 +
  113 + # Setup GPhases container
  114 + def _setup_phases(self):
  115 + """
  116 + Setup GPhases container
  117 +
  118 + Returns
  119 + -------
  120 + phases : `~gammalib.GPhases`
  121 + GPhases container
  122 + """
  123 + # Setup phases container
  124 + phases = gammalib.GPhases()
  125 + for i in range(10):
  126 + pmin = float(i)
  127 + pmax = float(i+1)
  128 + phases.append(pmin, pmax)
  129 +
  130 + # Return phases container
  131 + return phases
  132 +
  133 + # Setup GPhotons container
  134 + def _setup_photons(self):
  135 + """
  136 + Setup GPhotons container
  137 +
  138 + Returns
  139 + -------
  140 + photons : `~gammalib.GPhotons`
  141 + GPhoton container
  142 + """
  143 + # Setup photon container
  144 + photons = gammalib.GPhotons()
  145 + photon = gammalib.GPhoton()
  146 + for i in range(10):
  147 + photon.energy().MeV(float(i))
  148 + photons.append(photon)
  149 +
  150 + # Return photons container
  151 + return photons
56 152  
57 153 # Test GEnergy class
58   - def test_energy(self):
  154 + def _test_energy(self):
59 155 """
60 156 Test GEnergy class
61 157 """
... ... @@ -129,13 +225,15 @@ class Test(gammalib.GPythonTestSuite):
129 225 return
130 226  
131 227 # Test GEnergies class
132   - def test_energies(self):
  228 + def _test_energies(self):
133 229 """
134 230 Test GEnergies class
135 231 """
136   - # Setup 3 logarithmic energies
  232 + # Setup energies container
137 233 energies = gammalib.GEnergies(3, gammalib.GEnergy(1.0, 'MeV'),
138 234 gammalib.GEnergy(100.0, 'MeV'))
  235 +
  236 + # Check energies container
139 237 self.test_value(energies[0].MeV(), 1.0, 1.0e-7,
140 238 'Check energy value access')
141 239 self.test_value(energies[1].MeV(), 10.0, 1.0e-7,
... ... @@ -146,8 +244,147 @@ class Test(gammalib.GPythonTestSuite):
146 244 # Return
147 245 return
148 246  
  247 + # Test GEnergies class access operators
  248 + def _test_energies_access(self):
  249 + """
  250 + Test GEnergies class observation access
  251 + """
  252 + # Setup energies container
  253 + energies = gammalib.GEnergies(10, gammalib.GEnergy(1.0, 'MeV'),
  254 + gammalib.GEnergy(10.0, 'MeV'), False)
  255 +
  256 + # Loop over all elements using the container iterator and count the
  257 + # number of iterations
  258 + nenergies = 0
  259 + reference = 1.0
  260 + for energy in energies:
  261 + self.test_value(energy.MeV(), reference)
  262 + nenergies += 1
  263 + reference += 1.0
  264 +
  265 + # Check that looping was successful
  266 + self.test_value(energies.size(), 10, 'Check container size')
  267 + self.test_value(nenergies, 10, 'Check container iterator')
  268 +
  269 + # Test access from start
  270 + self.test_value(energies[3].MeV(), 4.0)
  271 +
  272 + # Check access from end
  273 + self.test_value(energies[-2].MeV(), 9.0)
  274 +
  275 + # Return
  276 + return
  277 +
  278 + # Test GEnergies class slicing
  279 + def _test_energies_slicing(self):
  280 + """
  281 + Test GEnergies class slicing
  282 + """
  283 + # Setup energies container
  284 + energies = gammalib.GEnergies(10, gammalib.GEnergy(1.0, 'MeV'),
  285 + gammalib.GEnergy(10.0, 'MeV'), False)
  286 +
  287 + # Test energies[start:end]
  288 + self.test_value(len(energies[3:5]), 2)
  289 + self.test_value(energies[3:5][0].MeV(), 4.0)
  290 + self.test_value(energies[3:5][1].MeV(), 5.0)
  291 +
  292 + # Test energies[start:]
  293 + self.test_value(len(energies[7:]), 3)
  294 + self.test_value(energies[7:][0].MeV(), 8.0)
  295 + self.test_value(energies[7:][1].MeV(), 9.0)
  296 + self.test_value(energies[7:][2].MeV(), 10.0)
  297 +
  298 + # Test energies[:end]
  299 + self.test_value(len(energies[:2]), 2)
  300 + self.test_value(energies[:2][0].MeV(), 1.0)
  301 + self.test_value(energies[:2][1].MeV(), 2.0)
  302 +
  303 + # Test energies[:]
  304 + self.test_value(len(energies[:]), 10)
  305 + for i in range(10):
  306 + self.test_value(energies[:][i].MeV(), float(i+1))
  307 +
  308 + # Test energies[start:end:step]
  309 + self.test_value(len(energies[3:7:2]), 2)
  310 + self.test_value(energies[3:7:2][0].MeV(), 4.0)
  311 + self.test_value(energies[3:7:2][1].MeV(), 6.0)
  312 +
  313 + # Test energies[start:end:step]
  314 + self.test_value(len(energies[6:3:-2]), 2)
  315 + self.test_value(energies[6:3:-2][0].MeV(), 7.0)
  316 + self.test_value(energies[6:3:-2][1].MeV(), 5.0)
  317 +
  318 + # Test energies[-start:]
  319 + self.test_value(len(energies[-2:]), 2)
  320 + self.test_value(energies[-2:][0].MeV(), 9.0)
  321 + self.test_value(energies[-2:][1].MeV(), 10.0)
  322 +
  323 + # Test energies[:-end]
  324 + self.test_value(len(energies[:-7]), 3)
  325 + self.test_value(energies[:-7][0].MeV(), 1.0)
  326 + self.test_value(energies[:-7][1].MeV(), 2.0)
  327 + self.test_value(energies[:-7][2].MeV(), 3.0)
  328 +
  329 + # Return
  330 + return
  331 +
  332 + # Test GEbounds class slicing
  333 + def _test_ebounds_slicing(self):
  334 + """
  335 + Test GEbounds class slicing
  336 + """
  337 + # Setup energies container
  338 + ebounds = gammalib.GEbounds(10, gammalib.GEnergy(1.0, 'MeV'),
  339 + gammalib.GEnergy(11.0, 'MeV'), False)
  340 +
  341 + # Test ebounds[start:end]
  342 + self.test_value(len(ebounds[3:5]), 2)
  343 + self.test_value(ebounds[3:5].emin(0).MeV(), 4.0)
  344 + self.test_value(ebounds[3:5].emin(1).MeV(), 5.0)
  345 +
  346 + # Test ebounds[start:]
  347 + self.test_value(len(ebounds[7:]), 3)
  348 + self.test_value(ebounds[7:].emin(0).MeV(), 8.0)
  349 + self.test_value(ebounds[7:].emin(1).MeV(), 9.0)
  350 + self.test_value(ebounds[7:].emin(2).MeV(), 10.0)
  351 +
  352 + # Test ebounds[:end]
  353 + self.test_value(len(ebounds[:2]), 2)
  354 + self.test_value(ebounds[:2].emin(0).MeV(), 1.0)
  355 + self.test_value(ebounds[:2].emin(1).MeV(), 2.0)
  356 +
  357 + # Test ebounds[:]
  358 + self.test_value(len(ebounds[:]), 10)
  359 + for i in range(10):
  360 + self.test_value(ebounds[:].emin(i).MeV(), float(i+1))
  361 +
  362 + # Test ebounds[start:end:step]
  363 + self.test_value(len(ebounds[3:7:2]), 2)
  364 + self.test_value(ebounds[3:7:2].emin(0).MeV(), 4.0)
  365 + self.test_value(ebounds[3:7:2].emin(1).MeV(), 6.0)
  366 +
  367 + # Test ebounds[start:end:step]
  368 + self.test_value(len(ebounds[6:3:-2]), 2)
  369 + self.test_value(ebounds[6:3:-2].emin(0).MeV(), 7.0)
  370 + self.test_value(ebounds[6:3:-2].emin(1).MeV(), 5.0)
  371 +
  372 + # Test ebounds[-start:]
  373 + self.test_value(len(ebounds[-2:]), 2)
  374 + self.test_value(ebounds[-2:].emin(0).MeV(), 9.0)
  375 + self.test_value(ebounds[-2:].emin(1).MeV(), 10.0)
  376 +
  377 + # Test ebounds[:-end]
  378 + self.test_value(len(ebounds[:-7]), 3)
  379 + self.test_value(ebounds[:-7].emin(0).MeV(), 1.0)
  380 + self.test_value(ebounds[:-7].emin(1).MeV(), 2.0)
  381 + self.test_value(ebounds[:-7].emin(2).MeV(), 3.0)
  382 +
  383 + # Return
  384 + return
  385 +
149 386 # Test GTime class
150   - def test_time(self):
  387 + def _test_time(self):
151 388 """
152 389 Test GTime class
153 390 """
... ... @@ -214,3 +451,284 @@ class Test(gammalib.GPythonTestSuite):
214 451  
215 452 # Return
216 453 return
  454 +
  455 + # Test GTimes class access operators
  456 + def _test_times_access(self):
  457 + """
  458 + Test GTimes class observation access
  459 + """
  460 + # Setup times container
  461 + times = self._setup_times()
  462 +
  463 + # Loop over all elements using the container iterator and count the
  464 + # number of iterations
  465 + ntimes = 0
  466 + reference = 0.0
  467 + for time in times:
  468 + self.test_value(time.secs(), reference)
  469 + ntimes += 1
  470 + reference += 1.0
  471 +
  472 + # Check that looping was successful
  473 + self.test_value(times.size(), 10, 'Check container size')
  474 + self.test_value(ntimes, 10, 'Check container iterator')
  475 +
  476 + # Test access from start
  477 + self.test_value(times[3].secs(), 3.0)
  478 +
  479 + # Check access from end
  480 + self.test_value(times[-2].secs(), 8.0)
  481 +
  482 + # Return
  483 + return
  484 +
  485 + # Test GTimes class slicing
  486 + def _test_times_slicing(self):
  487 + """
  488 + Test GTimes class slicing
  489 + """
  490 + # Setup times container
  491 + times = self._setup_times()
  492 +
  493 + # Test times[start:end]
  494 + self.test_value(len(times[3:5]), 2)
  495 + self.test_value(times[3:5][0].secs(), 3.0)
  496 + self.test_value(times[3:5][1].secs(), 4.0)
  497 +
  498 + # Test times[start:]
  499 + self.test_value(len(times[7:]), 3)
  500 + self.test_value(times[7:][0].secs(), 7.0)
  501 + self.test_value(times[7:][1].secs(), 8.0)
  502 + self.test_value(times[7:][2].secs(), 9.0)
  503 +
  504 + # Test times[:end]
  505 + self.test_value(len(times[:2]), 2)
  506 + self.test_value(times[:2][0].secs(), 0.0)
  507 + self.test_value(times[:2][1].secs(), 1.0)
  508 +
  509 + # Test times[:]
  510 + self.test_value(len(times[:]), 10)
  511 + for i in range(10):
  512 + self.test_value(times[:][i].secs(), float(i))
  513 +
  514 + # Test times[start:end:step]
  515 + self.test_value(len(times[3:7:2]), 2)
  516 + self.test_value(times[3:7:2][0].secs(), 3.0)
  517 + self.test_value(times[3:7:2][1].secs(), 5.0)
  518 +
  519 + # Test times[start:end:step]
  520 + self.test_value(len(times[6:3:-2]), 2)
  521 + self.test_value(times[6:3:-2][0].secs(), 6.0)
  522 + self.test_value(times[6:3:-2][1].secs(), 4.0)
  523 +
  524 + # Test times[-start:]
  525 + self.test_value(len(times[-2:]), 2)
  526 + self.test_value(times[-2:][0].secs(), 8.0)
  527 + self.test_value(times[-2:][1].secs(), 9.0)
  528 +
  529 + # Test times[:-end]
  530 + self.test_value(len(times[:-7]), 3)
  531 + self.test_value(times[:-7][0].secs(), 0.0)
  532 + self.test_value(times[:-7][1].secs(), 1.0)
  533 + self.test_value(times[:-7][2].secs(), 2.0)
  534 +
  535 + # Return
  536 + return
  537 +
  538 + # Test GGti class slicing
  539 + def _test_gti_slicing(self):
  540 + """
  541 + Test GGti class slicing
  542 + """
  543 + # Setup GTI container
  544 + gti = self._setup_gti()
  545 +
  546 + # Test gti[start:end]
  547 + self.test_value(len(gti[3:5]), 2)
  548 + self.test_value(gti[3:5].tstop(0).secs(), 4.0)
  549 + self.test_value(gti[3:5].tstop(1).secs(), 5.0)
  550 +
  551 + # Test gti[start:]
  552 + self.test_value(len(gti[7:]), 3)
  553 + self.test_value(gti[7:].tstop(0).secs(), 8.0)
  554 + self.test_value(gti[7:].tstop(1).secs(), 9.0)
  555 + self.test_value(gti[7:].tstop(2).secs(), 10.0)
  556 +
  557 + # Test gti[:end]
  558 + self.test_value(len(gti[:2]), 2)
  559 + self.test_value(gti[:2].tstop(0).secs(), 1.0)
  560 + self.test_value(gti[:2].tstop(1).secs(), 2.0)
  561 +
  562 + # Test gti[:]
  563 + self.test_value(len(gti[:]), 10)
  564 + for i in range(10):
  565 + self.test_value(gti[:].tstop(i).secs(), float(i+1))
  566 +
  567 + # Test gti[start:end:step]
  568 + self.test_value(len(gti[3:7:2]), 2)
  569 + self.test_value(gti[3:7:2].tstop(0).secs(), 4.0)
  570 + self.test_value(gti[3:7:2].tstop(1).secs(), 6.0)
  571 +
  572 + # Test gti[start:end:step]
  573 + self.test_value(len(gti[6:3:-2]), 2)
  574 + self.test_value(gti[6:3:-2].tstop(0).secs(), 7.0)
  575 + self.test_value(gti[6:3:-2].tstop(1).secs(), 5.0)
  576 +
  577 + # Test gti[-start:]
  578 + self.test_value(len(gti[-2:]), 2)
  579 + self.test_value(gti[-2:].tstop(0).secs(), 9.0)
  580 + self.test_value(gti[-2:].tstop(1).secs(), 10.0)
  581 +
  582 + # Test gti[:-end]
  583 + self.test_value(len(gti[:-7]), 3)
  584 + self.test_value(gti[:-7].tstop(0).secs(), 1.0)
  585 + self.test_value(gti[:-7].tstop(1).secs(), 2.0)
  586 + self.test_value(gti[:-7].tstop(2).secs(), 3.0)
  587 +
  588 + # Return
  589 + return
  590 +
  591 + # Test GPhases class slicing
  592 + def _test_phases_slicing(self):
  593 + """
  594 + Test GPhases class slicing
  595 + """
  596 + # Setup phase container
  597 + phases = self._setup_phases()
  598 +
  599 + # Test phases[start:end]
  600 + self.test_value(len(phases[3:5]), 2)
  601 + self.test_value(phases[3:5].pmax(0), 4.0)
  602 + self.test_value(phases[3:5].pmax(1), 5.0)
  603 +
  604 + # Test phases[start:]
  605 + self.test_value(len(phases[7:]), 3)
  606 + self.test_value(phases[7:].pmax(0), 8.0)
  607 + self.test_value(phases[7:].pmax(1), 9.0)
  608 + self.test_value(phases[7:].pmax(2), 10.0)
  609 +
  610 + # Test phases[:end]
  611 + self.test_value(len(phases[:2]), 2)
  612 + self.test_value(phases[:2].pmax(0), 1.0)
  613 + self.test_value(phases[:2].pmax(1), 2.0)
  614 +
  615 + # Test phases[:]
  616 + self.test_value(len(phases[:]), 10)
  617 + for i in range(10):
  618 + self.test_value(phases[:].pmax(i), float(i+1))
  619 +
  620 + # Test phases[start:end:step]
  621 + self.test_value(len(phases[3:7:2]), 2)
  622 + self.test_value(phases[3:7:2].pmax(0), 4.0)
  623 + self.test_value(phases[3:7:2].pmax(1), 6.0)
  624 +
  625 + # Test phases[start:end:step]
  626 + self.test_value(len(phases[6:3:-2]), 2)
  627 + self.test_value(phases[6:3:-2].pmax(0), 7.0)
  628 + self.test_value(phases[6:3:-2].pmax(1), 5.0)
  629 +
  630 + # Test phases[-start:]
  631 + self.test_value(len(phases[-2:]), 2)
  632 + self.test_value(phases[-2:].pmax(0), 9.0)
  633 + self.test_value(phases[-2:].pmax(1), 10.0)
  634 +
  635 + # Test phases[:-end]
  636 + self.test_value(len(phases[:-7]), 3)
  637 + self.test_value(phases[:-7].pmax(0), 1.0)
  638 + self.test_value(phases[:-7].pmax(1), 2.0)
  639 + self.test_value(phases[:-7].pmax(2), 3.0)
  640 +
  641 + # Return
  642 + return
  643 +
  644 + # Test GPhotons class access operators
  645 + def _test_photons_access(self):
  646 + """
  647 + Test GPhotons class observation access
  648 + """
  649 + # Setup photons container
  650 + photons = self._setup_photons()
  651 +
  652 + # Perform photons access tests
  653 + test_support._energy_container_access_index(self, photons)
  654 +
  655 + # Return
  656 + return
  657 +
  658 + # Test GPhotons class slicing
  659 + def _test_photons_slicing(self):
  660 + """
  661 + Test GPhotons class slicing
  662 + """
  663 + # Setup photons container
  664 + photons = self._setup_photons()
  665 +
  666 + # Perform slicing tests
  667 + test_support._energy_container_slicing(self, photons)
  668 +
  669 + # Return
  670 + return
  671 +
  672 + # Test GObservations class access operators
  673 + def _test_observations_access(self):
  674 + """
  675 + Test GObservations class observation access
  676 + """
  677 + # Setup observation container and CTA observation
  678 + obs = self._setup_obs()
  679 + run = gammalib.GCTAObservation()
  680 +
  681 + # Perform observation access tests
  682 + test_support._container_access_index(self, obs)
  683 +
  684 + # Return
  685 + return
  686 +
  687 + # Test GObservations class slicing
  688 + def _test_observations_slicing(self):
  689 + """
  690 + Test GObservations class slicing
  691 + """
  692 + # Setup observation container
  693 + obs = self._setup_obs()
  694 +
  695 + # Perform slicing tests
  696 + test_support._container_slicing(self, obs)
  697 +
  698 + # Perform additional slicing tests
  699 + self.test_value(len(obs[3:5].models()), 10)
  700 + self.test_value(len(obs[7:].models()), 10)
  701 + self.test_value(len(obs[:2].models()), 10)
  702 + self.test_value(len(obs[:].models()), 10)
  703 + self.test_value(len(obs[3:7:2].models()), 10)
  704 + self.test_value(len(obs[6:3:-2].models()), 10)
  705 + self.test_value(len(obs[-2:].models()), 10)
  706 + self.test_value(len(obs[:-7].models()), 10)
  707 +
  708 + # Return
  709 + return
  710 +
  711 + # Set test functions
  712 + def set(self):
  713 + """
  714 + Set all test functions
  715 + """
  716 + # Set test name
  717 + self.name('obs')
  718 +
  719 + # Append tests
  720 + self.append(self._test_energy, 'Test GEnergy')
  721 + self.append(self._test_energies, 'Test GEnergies')
  722 + self.append(self._test_time, 'Test GTime')
  723 + self.append(self._test_energies_access, 'Test GEnergies energy access')
  724 + self.append(self._test_times_access, 'Test GTimes time access')
  725 + self.append(self._test_photons_access, 'Test GPhotons photon access')
  726 + self.append(self._test_observations_access, 'Test GObservations observation access')
  727 + self.append(self._test_energies_slicing, 'Test GEnergies slicing')
  728 + self.append(self._test_ebounds_slicing, 'Test GEbounds slicing')
  729 + self.append(self._test_times_slicing, 'Test GTimes slicing')
  730 + self.append(self._test_photons_slicing, 'Test GPhotons slicing')
  731 + self.append(self._test_observations_slicing, 'Test GObservations slicing')
  732 +
  733 + # Return
  734 + return
... ...
test/test_GOptimizer.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib optimizer module.
3 3 #
4   -# Copyright (C) 2012-2015 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2017 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -18,6 +18,7 @@
18 18 #
19 19 # ==========================================================================
20 20 import gammalib
  21 +import test_support
21 22  
22 23  
23 24 # ======================================== #
... ... @@ -38,24 +39,76 @@ class Test(gammalib.GPythonTestSuite):
38 39 # Return
39 40 return
40 41  
41   - # Set test functions
42   - def set(self):
  42 + # Setup GOptimizerPars container
  43 + def _setup_pars(self):
43 44 """
44   - Set all test functions.
  45 + Setup GOptimizerPars container
  46 +
  47 + Returns
  48 + -------
  49 + pars : `~gammalib.GOptimizerPars`
  50 + GOptimizerPars container
45 51 """
46   - # Set test name
47   - self.name("opt")
  52 + # Setup GOptimizerPars container
  53 + pars = gammalib.GOptimizerPars()
  54 + par = gammalib.GOptimizerPar()
  55 + for i in range(10):
  56 + par.name('%s' % i)
  57 + pars.append(par)
48 58  
49   - # Append tests
50   - self.append(self.test, "Optimizer module dummy test")
  59 + # Return GOptimizerPars container
  60 + return pars
  61 +
  62 + # Test GOptimizerPars class access operators
  63 + def _test_pars_access(self):
  64 + """
  65 + Test GOptimizerPars class parameter access
  66 + """
  67 + # Setup GOptimizerPars container and parameter
  68 + pars = self._setup_pars()
  69 + par = gammalib.GOptimizerPar()
  70 +
  71 + # Perform GOptimizerPars access tests
  72 + test_support._container_access_index(self, pars)
  73 +
  74 + # Check parameter setting by index from start
  75 + par.name('98')
  76 + pars[3] = par
  77 + self.test_value(pars[3].name(), '98')
  78 +
  79 + # Check parameter setting by index from end
  80 + par.name('99')
  81 + pars[-2] = par
  82 + self.test_value(pars[-2].name(), '99')
  83 +
  84 + # Return
  85 + return
  86 +
  87 + # Test GOptimizerPars class slicing
  88 + def _test_pars_slicing(self):
  89 + """
  90 + Test GOptimizerPars class slicing
  91 + """
  92 + # Setup GOptimizerPars container
  93 + pars = self._setup_pars()
  94 +
  95 + # Perform slicing tests
  96 + test_support._container_slicing(self, pars)
51 97  
52 98 # Return
53 99 return
54 100  
55   - # Test function
56   - def test(self):
  101 + # Set test functions
  102 + def set(self):
57 103 """
58   - Test function.
  104 + Set all test functions.
59 105 """
  106 + # Set test name
  107 + self.name('opt')
  108 +
  109 + # Append tests
  110 + self.append(self._test_pars_access, "Test GOptimizerPars parameter access")
  111 + self.append(self._test_pars_slicing, "Test GOptimizerPars slicing")
  112 +
60 113 # Return
61 114 return
... ...
test/test_GSky.py
... ... @@ -20,12 +20,13 @@
20 20 import os
21 21 import math
22 22 import gammalib
  23 +import test_support
23 24  
24 25  
25 26 # =========== #
26 27 # Text parser #
27 28 # =========== #
28   -def loadtxt(filename):
  29 +def _loadtxt(filename):
29 30 """
30 31 Parse text file with columns of floats.
31 32  
... ... @@ -63,40 +64,33 @@ class Test(gammalib.GPythonTestSuite):
63 64 # Return
64 65 return
65 66  
66   - def set(self):
67   - """
68   - Set all test functions.
  67 + # Setup GSkyRegions container
  68 + def _setup_regions(self):
69 69 """
70   - # Set test name
71   - self.name("sky")
  70 + Setup GSkyRegions container
72 71  
73   - # Append tests
74   - self.append(self.test_methods, "Test sky map methods")
75   - self.append(self.test_friend_methods, "Test sky map friend methods")
76   - self.append(self.test_operators, "Test sky map operators")
77   - self.append(self.test_skymap_healpix, "Test HEALPix map")
78   - self.append(self.test_skymap_ait, "Test AIT projection map")
79   - self.append(self.test_skymap_azp, "Test AZP projection map")
80   - self.append(self.test_skymap_car, "Test CAR projection map")
81   - self.append(self.test_skymap_gls, "Test GLS projection map")
82   - self.append(self.test_skymap_mer, "Test MER projection map")
83   - self.append(self.test_skymap_mol, "Test MOL projection map")
84   - self.append(self.test_skymap_sfl, "Test SFL projection map")
85   - self.append(self.test_skymap_sin, "Test SIN projection map")
86   - self.append(self.test_skymap_stg, "Test STG projection map")
87   - self.append(self.test_skymap_tan, "Test TAN projection map")
88   - self.append(self.test_fk5_to_galactic, "Test FK5 to Galactic coordinate conversion")
  72 + Returns
  73 + -------
  74 + regions : `~gammalib.GSkyRegions`
  75 + Sky regions container
  76 + """
  77 + # Setup regions container
  78 + regions = gammalib.GSkyRegions()
  79 + circle = gammalib.GSkyRegionCircle()
  80 + for i in range(10):
  81 + circle.name('%s' % i)
  82 + regions.append(circle)
89 83  
90   - # Return
91   - return
  84 + # Return regions container
  85 + return regions
92 86  
93 87 # Test sky map methods
94   - def test_methods(self):
  88 + def _test_methods(self):
95 89 """
96 90 Test the sky map methods.
97 91 """
98 92 # Setup sky maps
99   - map = gammalib.GSkyMap("CAR", "CEL", 83.63, 22.01, -3.7, 2.6, 10, 8, 12)
  93 + map = gammalib.GSkyMap('CAR', 'CEL', 83.63, 22.01, -3.7, 2.6, 10, 8, 12)
100 94  
101 95 # Set sky map shape
102 96 map.shape(3,4)
... ... @@ -126,7 +120,7 @@ class Test(gammalib.GPythonTestSuite):
126 120 return
127 121  
128 122 # Test sky map friend methods
129   - def test_friend_methods(self):
  123 + def _test_friend_methods(self):
130 124 """
131 125 Test the sky map friend methods
132 126 """
... ... @@ -154,12 +148,12 @@ class Test(gammalib.GPythonTestSuite):
154 148 return
155 149  
156 150 # Test sky map operators
157   - def test_operators(self):
  151 + def _test_operators(self):
158 152 """
159 153 Test the sky map operators.
160 154 """
161 155 # Setup sky maps
162   - map = gammalib.GSkyMap("CAR", "CEL", 83.6331, 22.0145, -3.7, 2.6, 2, 2)
  156 + map = gammalib.GSkyMap('CAR', 'CEL', 83.6331, 22.0145, -3.7, 2.6, 2, 2)
163 157 map[0] = 1.0
164 158 map[1] = 2.0
165 159 map[2] = 3.0
... ... @@ -218,7 +212,7 @@ class Test(gammalib.GPythonTestSuite):
218 212 return
219 213  
220 214 # Generic skymap pixel transformation test
221   - def test_skymap_pixels(self, pixels, map):
  215 + def _test_skymap_pixels(self, pixels, map):
222 216 """
223 217 Control coordinate and pixel transformation methods.
224 218 """
... ... @@ -226,9 +220,9 @@ class Test(gammalib.GPythonTestSuite):
226 220 for i in range(pixels.npix()):
227 221 dir = pixels.inx2dir(i)
228 222 inx = pixels.dir2inx(dir)
229   - msg = map + " inx2dir/dir2inx check for pixel " + str(i)
230   - err = map + " GSkyMap trouble with pixel " + str(i) + " (" + str(inx) + \
231   - "), RA=" + str(dir.ra() * 180 / math.pi) + ", Dec=" + str(dir.dec() * 180 / math.pi)
  223 + msg = map + ' inx2dir/dir2inx check for pixel ' + str(i)
  224 + err = map + ' GSkyMap trouble with pixel ' + str(i) + ' (' + str(inx) + \
  225 + '), RA=' + str(dir.ra() * 180 / math.pi) + ', Dec=' + str(dir.dec() * 180 / math.pi)
232 226 self.test_assert(i == inx, msg, err)
233 227  
234 228 # Control SkyDir coordinate transformation for all pixels
... ... @@ -240,21 +234,21 @@ class Test(gammalib.GPythonTestSuite):
240 234 if (dra >= 5.0):
241 235 dra -= 2.0 * math.pi
242 236 ddec = abs(dir.dec() - dir_new.dec())
243   - msg = map + " dir check for pixel " + str(i)
244   - err = map + " GSkyMap trouble with pixel " + str(i) + " (" + str(dra) + \
245   - "," + str(ddec) + ")"
  237 + msg = map + ' dir check for pixel ' + str(i)
  238 + err = map + ' GSkyMap trouble with pixel ' + str(i) + ' (' + str(dra) + \
  239 + ',' + str(ddec) + ')'
246 240 self.test_assert(not (dra > 1.0e-9 or ddec > 1.0e-9), msg, err)
247 241  
248 242 # Return
249 243 return
250 244  
251 245 # Generic skymap projection test
252   - def test_skymap_proj(self, proj):
  246 + def _test_skymap_proj(self, proj):
253 247 """
254 248 Test skymap projection.
255 249 """
256 250 # Set filename
257   - file = "test_python_skymap_" + proj + ".fits"
  251 + file = 'test_python_skymap_' + proj + '.fits'
258 252  
259 253 # Remove test files
260 254 try:
... ... @@ -263,26 +257,26 @@ class Test(gammalib.GPythonTestSuite):
263 257 pass
264 258  
265 259 # Create skymap
266   - pixels = gammalib.GSkyMap(proj, "CEL", 83.6331, 22.0145, -3.7, 2.6, 5, 5, 20)
  260 + pixels = gammalib.GSkyMap(proj, 'CEL', 83.6331, 22.0145, -3.7, 2.6, 5, 5, 20)
267 261 for map in range(pixels.nmaps()):
268 262 for i in range(pixels.npix()):
269 263 pixels[i, map] = i + map * pixels.npix()
270 264 pixels.save(file)
271 265  
272 266 # Test coordinate and pixel transformations
273   - self.test_skymap_pixels(pixels, proj)
  267 + self._test_skymap_pixels(pixels, proj)
274 268  
275 269 # Return
276 270 return
277 271  
278 272 # Test HEALPix projection
279   - def test_skymap_healpix(self):
  273 + def _test_skymap_healpix(self):
280 274 """
281 275 Test HEALPix interface.
282 276 """
283 277 # Set filenames
284   - file1 = "test_python_skymap_hpx_v1.fits"
285   - file2 = "test_python_skymap_hpx_v2.fits"
  278 + file1 = 'test_python_skymap_hpx_v1.fits'
  279 + file2 = 'test_python_skymap_hpx_v2.fits'
286 280  
287 281 # Remove test files
288 282 try:
... ... @@ -292,7 +286,7 @@ class Test(gammalib.GPythonTestSuite):
292 286 pass
293 287  
294 288 # Create HEALPix skymap
295   - pixels = gammalib.GSkyMap("GAL", 2, "RING", 2)
  289 + pixels = gammalib.GSkyMap('GAL', 2, 'RING', 2)
296 290 for i in range(pixels.npix()):
297 291 pixels[i] = i + 1.0
298 292 pixels[i, 1] = i + 1.0 + 1000.0
... ... @@ -302,7 +296,7 @@ class Test(gammalib.GPythonTestSuite):
302 296 pixels = gammalib.GSkyMap(file1)
303 297  
304 298 # Control coordinate and pixel transformations
305   - self.test_skymap_pixels(pixels, "HEALPix")
  299 + self._test_skymap_pixels(pixels, 'HEALPix')
306 300  
307 301 # Save HEALPix skymap twice. The second saving should fail.
308 302 try:
... ... @@ -311,7 +305,7 @@ class Test(gammalib.GPythonTestSuite):
311 305 except RuntimeError:
312 306 pass
313 307 else:
314   - raise RuntimeError("*** TEST ERROR: FITS file overwritten!")
  308 + raise RuntimeError('*** TEST ERROR: FITS file overwritten!')
315 309 pixels.save(file2, True)
316 310  
317 311 # Load again HEALPix skymap
... ... @@ -321,117 +315,117 @@ class Test(gammalib.GPythonTestSuite):
321 315 return
322 316  
323 317 # Test AIT projection
324   - def test_skymap_ait(self):
  318 + def _test_skymap_ait(self):
325 319 """
326 320 Test AIT projection.
327 321 """
328 322 # Execute generic test
329   - self.test_skymap_proj("AIT")
  323 + self._test_skymap_proj('AIT')
330 324  
331 325 # Return
332 326 return
333 327  
334 328 # Test AZP projection
335   - def test_skymap_azp(self):
  329 + def _test_skymap_azp(self):
336 330 """
337 331 Test AZP projection.
338 332 """
339 333 # Execute generic test
340   - self.test_skymap_proj("AZP")
  334 + self._test_skymap_proj('AZP')
341 335  
342 336 # Return
343 337 return
344 338  
345 339 # Test CAR projection
346   - def test_skymap_car(self):
  340 + def _test_skymap_car(self):
347 341 """
348 342 Test CAR projection.
349 343 """
350 344 # Execute generic test
351   - self.test_skymap_proj("CAR")
  345 + self._test_skymap_proj('CAR')
352 346  
353 347 # Return
354 348 return
355 349  
356 350 # Test GLS projection
357   - def test_skymap_gls(self):
  351 + def _test_skymap_gls(self):
358 352 """
359 353 Test GLS projection.
360 354 """
361 355 # Execute generic test
362   - self.test_skymap_proj("GLS")
  356 + self._test_skymap_proj('GLS')
363 357  
364 358 # Return
365 359 return
366 360  
367 361 # Test MER projection
368   - def test_skymap_mer(self):
  362 + def _test_skymap_mer(self):
369 363 """
370 364 Test MER projection.
371 365 """
372 366 # Execute generic test
373   - self.test_skymap_proj("MER")
  367 + self._test_skymap_proj('MER')
374 368  
375 369 # Return
376 370 return
377 371  
378 372 # Test MOL projection
379   - def test_skymap_mol(self):
  373 + def _test_skymap_mol(self):
380 374 """
381 375 Test MOL projection.
382 376 """
383 377 # Execute generic test
384   - self.test_skymap_proj("MOL")
  378 + self._test_skymap_proj('MOL')
385 379  
386 380 # Return
387 381 return
388 382  
389 383 # Test SIN projection
390   - def test_skymap_sin(self):
  384 + def _test_skymap_sin(self):
391 385 """
392 386 Test SIN projection.
393 387 """
394 388 # Execute generic test
395   - self.test_skymap_proj("SIN")
  389 + self._test_skymap_proj('SIN')
396 390  
397 391 # Return
398 392 return
399 393  
400 394 # Test SFL projection
401   - def test_skymap_sfl(self):
  395 + def _test_skymap_sfl(self):
402 396 """
403 397 Test SFL projection.
404 398 """
405 399 # Execute generic test
406   - self.test_skymap_proj("SFL")
  400 + self._test_skymap_proj('SFL')
407 401  
408 402 # Return
409 403 return
410 404  
411 405 # Test STG projection
412   - def test_skymap_stg(self):
  406 + def _test_skymap_stg(self):
413 407 """
414 408 Test STG projection.
415 409 """
416 410 # Execute generic test
417   - self.test_skymap_proj("STG")
  411 + self._test_skymap_proj('STG')
418 412  
419 413 # Return
420 414 return
421 415  
422 416 # Test TAN projection
423   - def test_skymap_tan(self):
  417 + def _test_skymap_tan(self):
424 418 """
425 419 Test TAN projection.
426 420 """
427 421 # Execute generic test
428   - self.test_skymap_proj("TAN")
  422 + self._test_skymap_proj('TAN')
429 423  
430 424 # Return
431 425 return
432 426  
433 427 # FK5 J2000 to Galactic coordinate tranformations
434   - def test_fk5_to_galactic(self):
  428 + def _test_fk5_to_galactic(self):
435 429 """
436 430 Test precision of FK5 J2000 to Galactic coordinate tranformations
437 431 against pyast (http://dsberry.github.com/starlink/pyast.html)
... ... @@ -446,8 +440,8 @@ class Test(gammalib.GPythonTestSuite):
446 440 # Set parameters
447 441 fk5_filename = datadir + 'initial_coords.txt'
448 442 galactic_filename = datadir + 'fk5_to_galactic.txt'
449   - fk5_coordinates = loadtxt(fk5_filename)
450   - galactic_coordinates = loadtxt(galactic_filename)
  443 + fk5_coordinates = _loadtxt(fk5_filename)
  444 + galactic_coordinates = _loadtxt(galactic_filename)
451 445 coordinates = zip(fk5_coordinates, galactic_coordinates)
452 446 max_dist = 0
453 447  
... ... @@ -483,3 +477,70 @@ class Test(gammalib.GPythonTestSuite):
483 477  
484 478 # Return
485 479 return
  480 +
  481 + # Test GSkyRegions class access operators
  482 + def _test_regions_access(self):
  483 + """
  484 + Test GSkyRegions class observation access
  485 + """
  486 + # Setup regions container
  487 + regions = self._setup_regions()
  488 + circle = gammalib.GSkyRegionCircle()
  489 +
  490 + # Perform regions access tests
  491 + test_support._container_access_index(self, regions)
  492 +
  493 + # Check regions setting by index from start
  494 + circle.name('98')
  495 + regions[3] = circle
  496 + self.test_value(regions[3].name(), '98')
  497 +
  498 + # Check observation setting by index from end
  499 + circle.name('99')
  500 + regions[-2] = circle
  501 + self.test_value(regions[-2].name(), '99')
  502 +
  503 + # Return
  504 + return
  505 +
  506 + # Test GSkyRegions class slicing
  507 + def _test_regions_slicing(self):
  508 + """
  509 + Test GSkyRegions class slicing
  510 + """
  511 + # Setup regions container
  512 + regions = self._setup_regions()
  513 +
  514 + # Perform slicing tests
  515 + test_support._container_slicing(self, regions)
  516 +
  517 + # Return
  518 + return
  519 +
  520 + def set(self):
  521 + """
  522 + Set all test functions.
  523 + """
  524 + # Set test name
  525 + self.name("sky")
  526 +
  527 + # Append tests
  528 + self.append(self._test_methods, "Test sky map methods")
  529 + self.append(self._test_friend_methods, "Test sky map friend methods")
  530 + self.append(self._test_operators, "Test sky map operators")
  531 + self.append(self._test_skymap_healpix, "Test HEALPix map")
  532 + self.append(self._test_skymap_ait, "Test AIT projection map")
  533 + self.append(self._test_skymap_azp, "Test AZP projection map")
  534 + self.append(self._test_skymap_car, "Test CAR projection map")
  535 + self.append(self._test_skymap_gls, "Test GLS projection map")
  536 + self.append(self._test_skymap_mer, "Test MER projection map")
  537 + self.append(self._test_skymap_mol, "Test MOL projection map")
  538 + self.append(self._test_skymap_sfl, "Test SFL projection map")
  539 + self.append(self._test_skymap_sin, "Test SIN projection map")
  540 + self.append(self._test_skymap_stg, "Test STG projection map")
  541 + self.append(self._test_skymap_tan, "Test TAN projection map")
  542 + self.append(self._test_regions_access, "Test GSkyRegions region access")
  543 + self.append(self._test_regions_slicing, "Test GSkyRegions slicing")
  544 +
  545 + # Return
  546 + return
... ...
test/test_GSupport.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib support module.
3 3 #
4   -# Copyright (C) 2012-2016 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2017 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -39,26 +39,26 @@ class Test(gammalib.GPythonTestSuite):
39 39 # Return
40 40 return
41 41  
42   - # Set all test functions
43   - def set(self):
44   - """
45   - Set all test functions.
  42 + # Setup GNodeArray container
  43 + def _setup_nodes(self):
46 44 """
47   - # Set test name
48   - self.name('support')
  45 + Setup GNodeArray
49 46  
50   - # Append tests
51   - self.append(self.test_node_array, 'Test GNodeArray')
52   - self.append(self.test_url_file, 'Test GUrlFile')
53   - self.append(self.test_url_string, 'Test GUrlString')
54   - self.append(self.test_filename, 'Test GFilename')
55   - self.append(self.test_csv, 'Test GCsv')
  47 + Returns
  48 + -------
  49 + nodes : `~gammalib.GNodeArray`
  50 + Node array
  51 + """
  52 + # Setup time container
  53 + nodes = gammalib.GNodeArray()
  54 + for i in range(10):
  55 + nodes.append(float(i))
56 56  
57   - # Return
58   - return
  57 + # Return GNodeArray
  58 + return nodes
59 59  
60 60 # Test GNodeArray class
61   - def test_node_array(self):
  61 + def _test_node_array(self):
62 62 """
63 63 Test GNodeArray class.
64 64 """
... ... @@ -91,8 +91,91 @@ class Test(gammalib.GPythonTestSuite):
91 91 # Return
92 92 return
93 93  
  94 + # Test GNodeArray access
  95 + def _test_node_array_access(self):
  96 + """
  97 + Test GNodeArray access
  98 + """
  99 + # Setup nodes container
  100 + nodes = self._setup_nodes()
  101 +
  102 + # Loop over all elements using the container iterator and count the
  103 + # number of iterations
  104 + nnodes = 0
  105 + reference = 0.0
  106 + for node in nodes:
  107 + self.test_value(node, reference)
  108 + nnodes += 1
  109 + reference += 1.0
  110 +
  111 + # Check that looping was successful
  112 + self.test_value(nodes.size(), 10, 'Check container size')
  113 + self.test_value(nnodes, 10, 'Check container iterator')
  114 +
  115 + # Test access from start
  116 + self.test_value(nodes[3], 3.0)
  117 +
  118 + # Check access from end
  119 + self.test_value(nodes[-2], 8.0)
  120 +
  121 + # Return
  122 + return
  123 +
  124 + # Test GNodeArray slicing
  125 + def _test_node_array_slicing(self):
  126 + """
  127 + Test GNodeArray slicing
  128 + """
  129 + # Setup nodes container
  130 + nodes = self._setup_nodes()
  131 +
  132 + # Test nodes[start:end]
  133 + self.test_value(len(nodes[3:5]), 2)
  134 + self.test_value(nodes[3:5][0], 3.0)
  135 + self.test_value(nodes[3:5][1], 4.0)
  136 +
  137 + # Test nodes[start:]
  138 + self.test_value(len(nodes[7:]), 3)
  139 + self.test_value(nodes[7:][0], 7.0)
  140 + self.test_value(nodes[7:][1], 8.0)
  141 + self.test_value(nodes[7:][2], 9.0)
  142 +
  143 + # Test nodes[:end]
  144 + self.test_value(len(nodes[:2]), 2)
  145 + self.test_value(nodes[:2][0], 0.0)
  146 + self.test_value(nodes[:2][1], 1.0)
  147 +
  148 + # Test nodes[:]
  149 + self.test_value(len(nodes[:]), 10)
  150 + for i in range(10):
  151 + self.test_value(nodes[:][i], float(i))
  152 +
  153 + # Test nodes[start:end:step]
  154 + self.test_value(len(nodes[3:7:2]), 2)
  155 + self.test_value(nodes[3:7:2][0], 3.0)
  156 + self.test_value(nodes[3:7:2][1], 5.0)
  157 +
  158 + # Test nodes[start:end:step]
  159 + self.test_value(len(nodes[6:3:-2]), 2)
  160 + self.test_value(nodes[6:3:-2][0], 6.0)
  161 + self.test_value(nodes[6:3:-2][1], 4.0)
  162 +
  163 + # Test nodes[-start:]
  164 + self.test_value(len(nodes[-2:]), 2)
  165 + self.test_value(nodes[-2:][0], 8.0)
  166 + self.test_value(nodes[-2:][1], 9.0)
  167 +
  168 + # Test nodes[:-end]
  169 + self.test_value(len(nodes[:-7]), 3)
  170 + self.test_value(nodes[:-7][0], 0.0)
  171 + self.test_value(nodes[:-7][1], 1.0)
  172 + self.test_value(nodes[:-7][2], 2.0)
  173 +
  174 + # Return
  175 + return
  176 +
94 177 # Test GUrlFile class
95   - def test_url_file(self):
  178 + def _test_url_file(self):
96 179 """
97 180 Test GUrlFile class.
98 181 """
... ... @@ -113,7 +196,7 @@ class Test(gammalib.GPythonTestSuite):
113 196 return
114 197  
115 198 # Test GUrlString class
116   - def test_url_string(self):
  199 + def _test_url_string(self):
117 200 """
118 201 Test GUrlString class.
119 202 """
... ... @@ -133,7 +216,7 @@ class Test(gammalib.GPythonTestSuite):
133 216 return
134 217  
135 218 # Test GFilename class
136   - def test_filename(self):
  219 + def _test_filename(self):
137 220 """
138 221 Test GFilename class.
139 222 """
... ... @@ -158,7 +241,7 @@ class Test(gammalib.GPythonTestSuite):
158 241 return
159 242  
160 243 # Test GCsv class
161   - def test_csv(self):
  244 + def _test_csv(self):
162 245 """
163 246 Test GCsv class.
164 247 """
... ... @@ -195,3 +278,24 @@ class Test(gammalib.GPythonTestSuite):
195 278  
196 279 # Return
197 280 return
  281 +
  282 + # Set all test functions
  283 + def set(self):
  284 + """
  285 + Set all test functions.
  286 + """
  287 + # Set test name
  288 + self.name('support')
  289 +
  290 + # Append tests
  291 + self.append(self._test_node_array, 'Test GNodeArray')
  292 + self.append(self._test_node_array_access, 'Test GNodeArray node access')
  293 + self.append(self._test_node_array_slicing, 'Test GNodeArray slicing')
  294 + self.append(self._test_url_file, 'Test GUrlFile')
  295 + self.append(self._test_url_string, 'Test GUrlString')
  296 + self.append(self._test_filename, 'Test GFilename')
  297 + self.append(self._test_csv, 'Test GCsv')
  298 +
  299 + # Return
  300 + return
  301 +
... ...
test/test_GTest.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib test module.
3 3 #
4   -# Copyright (C) 2012-2015 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2017 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -18,6 +18,7 @@
18 18 #
19 19 # ==========================================================================
20 20 import gammalib
  21 +import test_support
21 22  
22 23  
23 24 # =================================== #
... ... @@ -25,12 +26,12 @@ import gammalib
25 26 # =================================== #
26 27 class Test(gammalib.GPythonTestSuite):
27 28 """
28   - Test class for GammaLib test module.
  29 + Test class for GammaLib test module
29 30 """
30 31 # Constructor
31 32 def __init__(self):
32 33 """
33   - Constructor.
  34 + Constructor
34 35 """
35 36 # Call base class constructor
36 37 gammalib.GPythonTestSuite.__init__(self)
... ... @@ -38,24 +39,76 @@ class Test(gammalib.GPythonTestSuite):
38 39 # Return
39 40 return
40 41  
41   - # Set test functions
42   - def set(self):
  42 + # Setup test suite container
  43 + def _setup_suites(self):
43 44 """
44   - Set all test functions.
  45 + Setup test suite container
  46 +
  47 + Returns
  48 + -------
  49 + suites : `~gammalib.GTestSuites`
  50 + Test suite container
45 51 """
46   - # Set test name
47   - self.name("test")
  52 + # Setup test suite container
  53 + suites = gammalib.GTestSuites()
  54 + suite = gammalib.GPythonTestSuite()
  55 + for i in range(10):
  56 + suite.name('%s' % i)
  57 + suites.append(suite)
48 58  
49   - # Append tests
50   - self.append(self.test, "Test module dummy test")
  59 + # Return test suite container
  60 + return suites
  61 +
  62 + # Test GTestSuites class access operators
  63 + def _test_suites_access(self):
  64 + """
  65 + Test GTestSuites class parameter access
  66 + """
  67 + # Setup test suite container and test suite
  68 + suites = self._setup_suites()
  69 + suite = gammalib.GPythonTestSuite()
  70 +
  71 + # Perform GTestSuites access tests
  72 + test_support._container_access_index(self, suites)
  73 +
  74 + # Check parameter setting by index from start
  75 + suite.name('98')
  76 + suites[3] = suite
  77 + self.test_value(suites[3].name(), '98')
  78 +
  79 + # Check parameter setting by index from end
  80 + suite.name('99')
  81 + suites[-2] = suite
  82 + self.test_value(suites[-2].name(), '99')
  83 +
  84 + # Return
  85 + return
  86 +
  87 + # Test GTestSuites class slicing
  88 + def _test_suites_slicing(self):
  89 + """
  90 + Test GTestSuites class slicing
  91 + """
  92 + # Setup test suite container
  93 + suites = self._setup_suites()
  94 +
  95 + # Perform slicing tests
  96 + test_support._container_slicing(self, suites)
51 97  
52 98 # Return
53 99 return
54 100  
55   - # Test function
56   - def test(self):
  101 + # Set test functions
  102 + def set(self):
57 103 """
58   - Test function.
  104 + Set all test functions.
59 105 """
  106 + # Set test name
  107 + self.name('test')
  108 +
  109 + # Append tests
  110 + self.append(self._test_suites_access, 'Test GTestSuites parameter access')
  111 + self.append(self._test_suites_slicing, 'Test GTestSuites slicing')
  112 +
60 113 # Return
61 114 return
... ...
test/test_GXml.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib xml module.
3 3 #
4   -# Copyright (C) 2012-2015 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2017 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -18,6 +18,7 @@
18 18 #
19 19 # ==========================================================================
20 20 import gammalib
  21 +import test_support
21 22  
22 23  
23 24 # ================================== #
... ... @@ -25,7 +26,7 @@ import gammalib
25 26 # ================================== #
26 27 class Test(gammalib.GPythonTestSuite):
27 28 """
28   - Test class for GammaLib xml module.
  29 + Test class for GammaLib xml module
29 30 """
30 31 # Constructor
31 32 def __init__(self):
... ... @@ -38,24 +39,137 @@ class Test(gammalib.GPythonTestSuite):
38 39 # Return
39 40 return
40 41  
41   - # Set test functions
42   - def set(self):
  42 + # Setup GXml container
  43 + def _setup_xml(self):
43 44 """
44   - Set all test functions.
  45 + Setup GXml container
  46 +
  47 + Returns
  48 + -------
  49 + xml : `~gammalib.GXml`
  50 + GXml container
45 51 """
46   - # Set test name
47   - self.name("xml")
  52 + # Setup XML container
  53 + xml = gammalib.GXml()
  54 + element = gammalib.GXmlElement()
  55 + for i in range(10):
  56 + element.name('%s' % i)
  57 + xml.append(element)
48 58  
49   - # Append tests
50   - self.append(self.test, "XML module dummy test")
  59 + # Return XML container
  60 + return xml
  61 +
  62 + # Setup GXmlElement container
  63 + def _setup_elements(self):
  64 + """
  65 + Setup GXmlElement container
  66 +
  67 + Returns
  68 + -------
  69 + elements : `~gammalib.GXmlElement`
  70 + GXml container
  71 + """
  72 + # Setup GXmlElement container
  73 + elements = gammalib.GXmlElement()
  74 + element = gammalib.GXmlElement()
  75 + for i in range(10):
  76 + element.name('%s' % i)
  77 + elements.append(element)
  78 +
  79 + # Return GXmlElement container
  80 + return elements
  81 +
  82 + # Test GXml class access operators
  83 + def _test_xml_access(self):
  84 + """
  85 + Test GXml class parameter access
  86 + """
  87 + # Setup XML container and element
  88 + xml = self._setup_xml()
  89 + element = gammalib.GXmlElement()
  90 +
  91 + # Perform GXml access tests
  92 + test_support._container_access_index(self, xml)
  93 +
  94 + # Check parameter setting by index from start
  95 + element.name('98')
  96 + xml[3] = element
  97 + self.test_value(xml[3].name(), '98')
  98 +
  99 + # Check parameter setting by index from end
  100 + element.name('99')
  101 + xml[-2] = element
  102 + self.test_value(xml[-2].name(), '99')
  103 +
  104 + # Return
  105 + return
  106 +
  107 + # Test GXml class slicing
  108 + def _test_xml_slicing(self):
  109 + """
  110 + Test GXml class slicing
  111 + """
  112 + # Setup XML container
  113 + xml = self._setup_xml()
  114 +
  115 + # Perform slicing tests
  116 + test_support._container_slicing(self, xml)
51 117  
52 118 # Return
53 119 return
54 120  
55   - # Test function
56   - def test(self):
  121 + # Test GXmlElement class access operators
  122 + def _test_elements_access(self):
57 123 """
58   - Test function.
  124 + Test GXmlElement class parameter access
59 125 """
  126 + # Setup GXmlElement container and element
  127 + elements = self._setup_elements()
  128 + element = gammalib.GXmlElement()
  129 +
  130 + # Perform GXmlElement access tests
  131 + test_support._container_access_index(self, elements)
  132 +
  133 + # Check parameter setting by index from start
  134 + element.name('98')
  135 + elements[3] = element
  136 + self.test_value(elements[3].name(), '98')
  137 +
  138 + # Check parameter setting by index from end
  139 + element.name('99')
  140 + elements[-2] = element
  141 + self.test_value(elements[-2].name(), '99')
  142 +
  143 + # Return
  144 + return
  145 +
  146 + # Test GXmlElement class slicing
  147 + def _test_elements_slicing(self):
  148 + """
  149 + Test GXmlElement class slicing
  150 + """
  151 + # Setup GXmlElement container
  152 + elements = self._setup_elements()
  153 +
  154 + # Perform slicing tests
  155 + test_support._container_slicing(self, elements)
  156 +
  157 + # Return
  158 + return
  159 +
  160 + # Set test functions
  161 + def set(self):
  162 + """
  163 + Set all test functions.
  164 + """
  165 + # Set test name
  166 + self.name('xml')
  167 +
  168 + # Append tests
  169 + self.append(self._test_xml_access, 'Test GXml parameter access')
  170 + self.append(self._test_xml_slicing, 'Test GXml slicing')
  171 + self.append(self._test_elements_access, 'Test GXmlElement parameter access')
  172 + self.append(self._test_elements_slicing, 'Test GXmlElement slicing')
  173 +
60 174 # Return
61 175 return
... ...
test/test_support.py 0 → 100755
  1 +# ==========================================================================
  2 +# This module provides support functions for the Python unit tests
  3 +#
  4 +# Copyright (C) 2017 Juergen Knoedlseder
  5 +#
  6 +# This program is free software: you can redistribute it and/or modify
  7 +# it under the terms of the GNU General Public License as published by
  8 +# the Free Software Foundation, either version 3 of the License, or
  9 +# (at your option) any later version.
  10 +#
  11 +# This program is distributed in the hope that it will be useful,
  12 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 +# GNU General Public License for more details.
  15 +#
  16 +# You should have received a copy of the GNU General Public License
  17 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
  18 +#
  19 +# ==========================================================================
  20 +
  21 +
  22 +# ============================== #
  23 +# Test container access by index #
  24 +# ============================== #
  25 +def _container_access_index(testsuite, container):
  26 + """
  27 + Test container access by index
  28 +
  29 + Parameters
  30 + ----------
  31 + testsuite : `~gammalib.GPythonTestSuite`
  32 + Test suite class
  33 + container : `~gammalib.GContainer`
  34 + Container class
  35 + """
  36 + # Loop over all elements using the container iterator and count the number
  37 + # of iterations
  38 + niter = 0
  39 + for element in container:
  40 + testsuite.test_value(element.name(), '%s' % niter)
  41 + niter += 1
  42 +
  43 + # Check that looping was successful
  44 + testsuite.test_value(container.size(), 10, 'Check container size')
  45 + testsuite.test_value(niter, 10, 'Check container iterator')
  46 +
  47 + # Test access from start
  48 + testsuite.test_value(container[3].name(), '3')
  49 +
  50 + # Check access from end
  51 + testsuite.test_value(container[-2].name(), '8')
  52 +
  53 + # Clone first element
  54 + #element = container[0].copy()
  55 +
  56 + # Check setting by index from start
  57 + #element.name('98')
  58 + #container[3] = element
  59 + #self.test_value(container[3].name(), '98')
  60 +
  61 + # Check setting by index from end
  62 + #element.name('99')
  63 + #container[-2] = element
  64 + #self.test_value(container[-2].name(), '99')
  65 +
  66 + # Return
  67 + return
  68 +
  69 +
  70 +# ===================================== #
  71 +# Test energy container access by index #
  72 +# ===================================== #
  73 +def _energy_container_access_index(testsuite, container):
  74 + """
  75 + Test energy container access by index
  76 +
  77 + Parameters
  78 + ----------
  79 + testsuite : `~gammalib.GPythonTestSuite`
  80 + Test suite class
  81 + container : `~gammalib.GContainer`
  82 + Container class
  83 + """
  84 + # Loop over all elements using the container iterator and count the number
  85 + # of iterations
  86 + niter = 0
  87 + reference = 0.0
  88 + for element in container:
  89 + testsuite.test_value(element.energy().MeV(), reference)
  90 + niter += 1
  91 + reference += 1.0
  92 +
  93 + # Check that looping was successful
  94 + testsuite.test_value(container.size(), 10, 'Check container size')
  95 + testsuite.test_value(niter, 10, 'Check container iterator')
  96 +
  97 + # Test access from start
  98 + testsuite.test_value(container[3].energy().MeV(), 3.0)
  99 +
  100 + # Check access from end
  101 + testsuite.test_value(container[-2].energy().MeV(), 8.0)
  102 +
  103 + # Clone first element
  104 + element = container[0].copy()
  105 +
  106 + # Check setting by index from start
  107 + element.energy().MeV(98.0)
  108 + container[3] = element
  109 + testsuite.test_value(container[3].energy().MeV(), 98.0)
  110 +
  111 + # Check setting setting by index from end
  112 + element.energy().MeV(99.0)
  113 + container[-2] = element
  114 + testsuite.test_value(container[-2].energy().MeV(), 99.0)
  115 +
  116 + # Return
  117 + return
  118 +
  119 +
  120 +# ====================== #
  121 +# Test container slicing #
  122 +# ====================== #
  123 +def _container_slicing(testsuite, container):
  124 + """
  125 + Test container slicing
  126 +
  127 + Parameters
  128 + ----------
  129 + testsuite : `~gammalib.GPythonTestSuite`
  130 + Test suite class
  131 + container : `~gammalib.GContainer`
  132 + Container class
  133 + """
  134 + # Test container[start:end]
  135 + testsuite.test_value(len(container[3:5]), 2)
  136 + testsuite.test_value(container[3:5][0].name(), '3')
  137 + testsuite.test_value(container[3:5][1].name(), '4')
  138 +
  139 + # Test container[start:]
  140 + testsuite.test_value(len(container[7:]), 3)
  141 + testsuite.test_value(container[7:][0].name(), '7')
  142 + testsuite.test_value(container[7:][1].name(), '8')
  143 + testsuite.test_value(container[7:][2].name(), '9')
  144 +
  145 + # Test container[:end]
  146 + testsuite.test_value(len(container[:2]), 2)
  147 + testsuite.test_value(container[:2][0].name(), '0')
  148 + testsuite.test_value(container[:2][1].name(), '1')
  149 +
  150 + # Test container[:]
  151 + testsuite.test_value(len(container[:]), 10)
  152 + for i in range(10):
  153 + testsuite.test_value(container[:][i].name(), '%s' % i)
  154 +
  155 + # Test container[start:end:step]
  156 + testsuite.test_value(len(container[3:7:2]), 2)
  157 + testsuite.test_value(container[3:7:2][0].name(), '3')
  158 + testsuite.test_value(container[3:7:2][1].name(), '5')
  159 +
  160 + # Test container[start:end:step]
  161 + testsuite.test_value(len(container[6:3:-2]), 2)
  162 + testsuite.test_value(container[6:3:-2][0].name(), '6')
  163 + testsuite.test_value(container[6:3:-2][1].name(), '4')
  164 +
  165 + # Test container[-start:]
  166 + testsuite.test_value(len(container[-2:]), 2)
  167 + testsuite.test_value(container[-2:][0].name(), '8')
  168 + testsuite.test_value(container[-2:][1].name(), '9')
  169 +
  170 + # Test container[:-end]
  171 + testsuite.test_value(len(container[:-7]), 3)
  172 + testsuite.test_value(container[:-7][0].name(), '0')
  173 + testsuite.test_value(container[:-7][1].name(), '1')
  174 + testsuite.test_value(container[:-7][2].name(), '2')
  175 +
  176 + # Return
  177 + return
  178 +
  179 +
  180 +# ============================= #
  181 +# Test energy container slicing #
  182 +# ============================= #
  183 +def _energy_container_slicing(testsuite, container):
  184 + """
  185 + Test energy container slicing
  186 +
  187 + Parameters
  188 + ----------
  189 + testsuite : `~gammalib.GPythonTestSuite`
  190 + Test suite class
  191 + container : `~gammalib.GContainer`
  192 + Container class
  193 + """
  194 + # Test container[start:end]
  195 + testsuite.test_value(len(container[3:5]), 2)
  196 + testsuite.test_value(container[3:5][0].energy().MeV(), 3.0)
  197 + testsuite.test_value(container[3:5][1].energy().MeV(), 4.0)
  198 +
  199 + # Test container[start:]
  200 + testsuite.test_value(len(container[7:]), 3)
  201 + testsuite.test_value(container[7:][0].energy().MeV(), 7.0)
  202 + testsuite.test_value(container[7:][1].energy().MeV(), 8.0)
  203 + testsuite.test_value(container[7:][2].energy().MeV(), 9.0)
  204 +
  205 + # Test container[:end]
  206 + testsuite.test_value(len(container[:2]), 2)
  207 + testsuite.test_value(container[:2][0].energy().MeV(), 0.0)
  208 + testsuite.test_value(container[:2][1].energy().MeV(), 1.0)
  209 +
  210 + # Test container[:]
  211 + testsuite.test_value(len(container[:]), 10)
  212 + for i in range(10):
  213 + testsuite.test_value(container[:][i].energy().MeV(), float(i))
  214 +
  215 + # Test container[start:end:step]
  216 + testsuite.test_value(len(container[3:7:2]), 2)
  217 + testsuite.test_value(container[3:7:2][0].energy().MeV(), 3.0)
  218 + testsuite.test_value(container[3:7:2][1].energy().MeV(), 5.0)
  219 +
  220 + # Test container[start:end:step]
  221 + testsuite.test_value(len(container[6:3:-2]), 2)
  222 + testsuite.test_value(container[6:3:-2][0].energy().MeV(), 6.0)
  223 + testsuite.test_value(container[6:3:-2][1].energy().MeV(), 4.0)
  224 +
  225 + # Test container[-start:]
  226 + testsuite.test_value(len(container[-2:]), 2)
  227 + testsuite.test_value(container[-2:][0].energy().MeV(), 8.0)
  228 + testsuite.test_value(container[-2:][1].energy().MeV(), 9.0)
  229 +
  230 + # Test container[:-end]
  231 + testsuite.test_value(len(container[:-7]), 3)
  232 + testsuite.test_value(container[:-7][0].energy().MeV(), 0.0)
  233 + testsuite.test_value(container[:-7][1].energy().MeV(), 1.0)
  234 + testsuite.test_value(container[:-7][2].energy().MeV(), 2.0)
  235 +
  236 + # Return
  237 + return
... ...