Commit e6d15df1b5ae55579f053c455c267011a3857f2a
1 parent
b8b92464
Support Python container slicing (#2128)
Showing
30 changed files
with
1733 additions
and
408 deletions
ChangeLog
NEWS
| 1 | New Features and Important Changes in GammaLib 1.4.0 | 1 | New Features and Important Changes in GammaLib 1.4.0 |
| 2 | 2 | ||
| 3 | -22 June 2017 | 3 | +22 July 2017 |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | 1. Introduction | 6 | 1. Introduction |
| @@ -21,7 +21,13 @@ The following classes have been renamed: | @@ -21,7 +21,13 @@ The following classes have been renamed: | ||
| 21 | - n.a. | 21 | - n.a. |
| 22 | 22 | ||
| 23 | The following methods have been added: | 23 | The following methods have been added: |
| 24 | -- n.a. | 24 | +- GSkyRegion::type(std::string&) |
| 25 | +- GSkyRegion::name(std::string&) | ||
| 26 | +- GSkyRegion::solidangle(std::string&) | ||
| 27 | +- GOptimizerPars::append(GOptimizerPar&) | ||
| 28 | +- GLATEventList::append(GLATEventAtom&) | ||
| 29 | +- GLATEventList::reserve(int&) | ||
| 30 | +- GLATEventList::remove(int&,int&) | ||
| 25 | 31 | ||
| 26 | The following methods have been removed: | 32 | The following methods have been removed: |
| 27 | - n.a. | 33 | - n.a. |
| @@ -78,12 +84,13 @@ None | @@ -78,12 +84,13 @@ None | ||
| 78 | 84 | ||
| 79 | 11. Optimization module | 85 | 11. Optimization module |
| 80 | ----------------------- | 86 | ----------------------- |
| 81 | -None | 87 | +Add GOptimizerPars::append() method to allow appending of parameters to the |
| 88 | +container. | ||
| 82 | 89 | ||
| 83 | 90 | ||
| 84 | 12. Sky module | 91 | 12. Sky module |
| 85 | -------------- | 92 | -------------- |
| 86 | -None | 93 | +Add methods to set the name, type and solid angle of a sky region. |
| 87 | 94 | ||
| 88 | 95 | ||
| 89 | 13. Support module | 96 | 13. Support module |
| @@ -118,7 +125,7 @@ None | @@ -118,7 +125,7 @@ None | ||
| 118 | 125 | ||
| 119 | 19. Fermi-LAT interface | 126 | 19. Fermi-LAT interface |
| 120 | ---------------------- | 127 | ---------------------- |
| 121 | -None | 128 | +Add append(), remove() and reserve() methods to GLATEventList class. |
| 122 | 129 | ||
| 123 | 130 | ||
| 124 | 20. CTA interface | 131 | 20. CTA interface |
include/GOptimizerPars.hpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GOptimizerPars.hpp - Optimizer parameter container class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -75,6 +75,7 @@ public: | @@ -75,6 +75,7 @@ public: | ||
| 75 | int nfree(void) const; | 75 | int nfree(void) const; |
| 76 | GOptimizerPar* set(const int& index, const GOptimizerPar& par); | 76 | GOptimizerPar* set(const int& index, const GOptimizerPar& par); |
| 77 | GOptimizerPar* set(const std::string& name, const GOptimizerPar& par); | 77 | GOptimizerPar* set(const std::string& name, const GOptimizerPar& par); |
| 78 | + GOptimizerPar* append(const GOptimizerPar& par); | ||
| 78 | void attach(GOptimizerPar* par); | 79 | void attach(GOptimizerPar* par); |
| 79 | void attach(const int& index, GOptimizerPar* par); | 80 | void attach(const int& index, GOptimizerPar* par); |
| 80 | void attach(const std::string& name, GOptimizerPar* par); | 81 | void attach(const std::string& name, GOptimizerPar* par); |
include/GSkyRegion.hpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GSkyRegion.hpp - Abstract virtual sky region base class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -80,6 +80,9 @@ public: | @@ -80,6 +80,9 @@ public: | ||
| 80 | const std::string& type(void) const; | 80 | const std::string& type(void) const; |
| 81 | const std::string& name(void) const; | 81 | const std::string& name(void) const; |
| 82 | const double& solidangle(void) const; | 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 | protected: | 87 | protected: |
| 85 | // Protected methods | 88 | // Protected methods |
| @@ -109,6 +112,21 @@ const std::string& GSkyRegion::name(void) const | @@ -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 | * @brief Return region type | 130 | * @brief Return region type |
| 113 | * | 131 | * |
| 114 | * @return Region type | 132 | * @return Region type |
| @@ -123,16 +141,46 @@ const std::string& GSkyRegion::type(void) const | @@ -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 | inline | 165 | inline |
| 133 | const double& GSkyRegion::solidangle(void) const | 166 | const double& GSkyRegion::solidangle(void) const |
| 134 | { | 167 | { |
| 135 | return (m_solid); | 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 | #endif /* GSKYREGION_HPP */ | 186 | #endif /* GSKYREGION_HPP */ |
inst/cta/pyext/GCTAEventList.i
| @@ -90,19 +90,64 @@ public: | @@ -90,19 +90,64 @@ public: | ||
| 90 | * @brief GCTAEventList class extension | 90 | * @brief GCTAEventList class extension |
| 91 | ***************************************************************************/ | 91 | ***************************************************************************/ |
| 92 | %extend GCTAEventList { | 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 | return (*self)[index]; | 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,6 +20,7 @@ | ||
| 20 | import os | 20 | import os |
| 21 | import gammalib | 21 | import gammalib |
| 22 | import math | 22 | import math |
| 23 | +import test_support | ||
| 23 | 24 | ||
| 24 | 25 | ||
| 25 | # ================================== # | 26 | # ================================== # |
| @@ -27,12 +28,12 @@ import math | @@ -27,12 +28,12 @@ import math | ||
| 27 | # ================================== # | 28 | # ================================== # |
| 28 | class Test(gammalib.GPythonTestSuite): | 29 | class Test(gammalib.GPythonTestSuite): |
| 29 | """ | 30 | """ |
| 30 | - Test class for GammaLib CTA module. | 31 | + Test class for GammaLib CTA module |
| 31 | """ | 32 | """ |
| 32 | # Constructor | 33 | # Constructor |
| 33 | def __init__(self): | 34 | def __init__(self): |
| 34 | """ | 35 | """ |
| 35 | - Constructor. | 36 | + Constructor |
| 36 | """ | 37 | """ |
| 37 | # Call base class constructor | 38 | # Call base class constructor |
| 38 | gammalib.GPythonTestSuite.__init__(self) | 39 | gammalib.GPythonTestSuite.__init__(self) |
| @@ -44,28 +45,58 @@ class Test(gammalib.GPythonTestSuite): | @@ -44,28 +45,58 @@ class Test(gammalib.GPythonTestSuite): | ||
| 44 | # Return | 45 | # Return |
| 45 | return | 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 | # Return | 93 | # Return |
| 63 | return | 94 | return |
| 64 | 95 | ||
| 65 | # Test effective area response | 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 | # Test GCTAAeff2D file constructor | 101 | # Test GCTAAeff2D file constructor |
| 71 | filename = self._caldb + '/prod1_gauss.fits' | 102 | filename = self._caldb + '/prod1_gauss.fits' |
| @@ -119,9 +150,9 @@ class Test(gammalib.GPythonTestSuite): | @@ -119,9 +150,9 @@ class Test(gammalib.GPythonTestSuite): | ||
| 119 | return | 150 | return |
| 120 | 151 | ||
| 121 | # Test point spread function response | 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 | # Test GCTAPsf2D file constructor | 157 | # Test GCTAPsf2D file constructor |
| 127 | filename = self._caldb + '/prod1_gauss.fits' | 158 | filename = self._caldb + '/prod1_gauss.fits' |
| @@ -175,9 +206,9 @@ class Test(gammalib.GPythonTestSuite): | @@ -175,9 +206,9 @@ class Test(gammalib.GPythonTestSuite): | ||
| 175 | return | 206 | return |
| 176 | 207 | ||
| 177 | # Test energy dispersion | 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 | # Test GCTAEdispRmf file constructor | 213 | # Test GCTAEdispRmf file constructor |
| 183 | filename = self._caldb + '/dc1/rmf.fits' | 214 | filename = self._caldb + '/dc1/rmf.fits' |
| @@ -222,7 +253,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -222,7 +253,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 222 | # 0.5, 0.005) | 253 | # 0.5, 0.005) |
| 223 | 254 | ||
| 224 | # Test response | 255 | # Test response |
| 225 | - def test_response(self): | 256 | + def _test_response(self): |
| 226 | """ | 257 | """ |
| 227 | Test response classes | 258 | Test response classes |
| 228 | """ | 259 | """ |
| @@ -234,9 +265,9 @@ class Test(gammalib.GPythonTestSuite): | @@ -234,9 +265,9 @@ class Test(gammalib.GPythonTestSuite): | ||
| 234 | return | 265 | return |
| 235 | 266 | ||
| 236 | # Test On/Off analysis | 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 | # Create On region | 272 | # Create On region |
| 242 | crab = gammalib.GSkyDir() | 273 | crab = gammalib.GSkyDir() |
| @@ -271,9 +302,6 @@ class Test(gammalib.GPythonTestSuite): | @@ -271,9 +302,6 @@ class Test(gammalib.GPythonTestSuite): | ||
| 271 | lm = gammalib.GOptimizerLM() | 302 | lm = gammalib.GOptimizerLM() |
| 272 | outobs.optimize(lm) | 303 | outobs.optimize(lm) |
| 273 | outobs.errors(lm) | 304 | outobs.errors(lm) |
| 274 | - #print(lm) | ||
| 275 | - #print(outobs) | ||
| 276 | - #print(outobs.models()) | ||
| 277 | 305 | ||
| 278 | # Test On/Off model fitting results | 306 | # Test On/Off model fitting results |
| 279 | sky = outobs.models()['Crab'] | 307 | sky = outobs.models()['Crab'] |
| @@ -307,3 +335,23 @@ class Test(gammalib.GPythonTestSuite): | @@ -307,3 +335,23 @@ class Test(gammalib.GPythonTestSuite): | ||
| 307 | 335 | ||
| 308 | # Return | 336 | # Return |
| 309 | return | 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,7 +61,7 @@ public: | ||
| 61 | virtual ~GLATEventList(void); | 61 | virtual ~GLATEventList(void); |
| 62 | 62 | ||
| 63 | // Operators | 63 | // Operators |
| 64 | - virtual GLATEventList& operator= (const GLATEventList& list); | 64 | + virtual GLATEventList& operator=(const GLATEventList& list); |
| 65 | virtual GLATEventAtom* operator[](const int& index); | 65 | virtual GLATEventAtom* operator[](const int& index); |
| 66 | virtual const GLATEventAtom* operator[](const int& index) const; | 66 | virtual const GLATEventAtom* operator[](const int& index) const; |
| 67 | 67 | ||
| @@ -81,6 +81,9 @@ public: | @@ -81,6 +81,9 @@ public: | ||
| 81 | virtual std::string print(const GChatter& chatter = NORMAL) const; | 81 | virtual std::string print(const GChatter& chatter = NORMAL) const; |
| 82 | 82 | ||
| 83 | // Other methods | 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 | protected: | 88 | protected: |
| 86 | // Protected methods | 89 | // Protected methods |
| @@ -93,13 +96,13 @@ protected: | @@ -93,13 +96,13 @@ protected: | ||
| 93 | void read_ds_keys(const GFitsHDU& hdu); | 96 | void read_ds_keys(const GFitsHDU& hdu); |
| 94 | 97 | ||
| 95 | // Protected members | 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& GLATEventList::roi(void) const | @@ -150,4 +153,19 @@ const GLATRoi& GLATEventList::roi(void) const | ||
| 150 | return m_roi; | 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 | #endif /* GLATEVENTLIST_HPP */ | 171 | #endif /* GLATEVENTLIST_HPP */ |
inst/lat/pyext/GLATEventList.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GLATEventList.i - Fermi/LAT event list class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -56,6 +56,11 @@ public: | @@ -56,6 +56,11 @@ public: | ||
| 56 | virtual int number(void) const; | 56 | virtual int number(void) const; |
| 57 | virtual void roi(const GRoi& roi); | 57 | virtual void roi(const GRoi& roi); |
| 58 | virtual const GLATRoi& roi(void) const; | 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,25 +68,64 @@ public: | ||
| 63 | * @brief GLATEventList class extension | 68 | * @brief GLATEventList class extension |
| 64 | ***************************************************************************/ | 69 | ***************************************************************************/ |
| 65 | %extend GLATEventList { | 70 | %extend GLATEventList { |
| 66 | - GLATEventList copy() { | ||
| 67 | - return (*self); | ||
| 68 | - } | ||
| 69 | GLATEventAtom* __getitem__(const int& index) { | 71 | GLATEventAtom* __getitem__(const int& index) { |
| 72 | + // Counting from start, e.g. [2] | ||
| 70 | if (index >= 0 && index < self->size()) { | 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 | else { | 80 | else { |
| 74 | throw GException::out_of_range("__getitem__(int)", "Event index", | 81 | throw GException::out_of_range("__getitem__(int)", "Event index", |
| 75 | index, self->size()); | 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 | else { | 123 | else { |
| 83 | throw GException::out_of_range("__setitem__(int)", "Event index", | 124 | throw GException::out_of_range("__setitem__(int)", "Event index", |
| 84 | index, self->size()); | 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& roi) | @@ -384,9 +384,56 @@ void GLATEventList::roi(const GRoi& 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 | * @brief Print event list information | 434 | * @brief Print event list information |
| 388 | * | 435 | * |
| 389 | - * @param[in] chatter Chattiness (defaults to NORMAL). | 436 | + * @param[in] chatter Chattiness. |
| 390 | * @return String containing event list information. | 437 | * @return String containing event list information. |
| 391 | ***************************************************************************/ | 438 | ***************************************************************************/ |
| 392 | std::string GLATEventList::print(const GChatter& chatter) const | 439 | std::string GLATEventList::print(const GChatter& chatter) const |
inst/lat/test/test_LAT.py
| 1 | # ========================================================================== | 1 | # ========================================================================== |
| 2 | # This module performs unit tests for the GammaLib LAT module. | 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 | # This program is free software: you can redistribute it and/or modify | 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 | 7 | # it under the terms of the GNU General Public License as published by |
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # | 18 | # |
| 19 | # ========================================================================== | 19 | # ========================================================================== |
| 20 | import gammalib | 20 | import gammalib |
| 21 | +import test_support | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | # ================================== # | 24 | # ================================== # |
| @@ -25,12 +26,12 @@ import gammalib | @@ -25,12 +26,12 @@ import gammalib | ||
| 25 | # ================================== # | 26 | # ================================== # |
| 26 | class Test(gammalib.GPythonTestSuite): | 27 | class Test(gammalib.GPythonTestSuite): |
| 27 | """ | 28 | """ |
| 28 | - Test class for GammaLib LAT module. | 29 | + Test class for GammaLib LAT module |
| 29 | """ | 30 | """ |
| 30 | # Constructor | 31 | # Constructor |
| 31 | def __init__(self): | 32 | def __init__(self): |
| 32 | """ | 33 | """ |
| 33 | - Constructor. | 34 | + Constructor |
| 34 | """ | 35 | """ |
| 35 | # Call base class constructor | 36 | # Call base class constructor |
| 36 | gammalib.GPythonTestSuite.__init__(self) | 37 | gammalib.GPythonTestSuite.__init__(self) |
| @@ -38,24 +39,65 @@ class Test(gammalib.GPythonTestSuite): | @@ -38,24 +39,65 @@ class Test(gammalib.GPythonTestSuite): | ||
| 38 | # Return | 39 | # Return |
| 39 | return | 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 | # Return | 87 | # Return |
| 53 | return | 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 | # Return | 102 | # Return |
| 61 | return | 103 | return |
pyext/GFits.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GFits.i - FITS file class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -100,9 +100,14 @@ public: | @@ -100,9 +100,14 @@ public: | ||
| 100 | ***************************************************************************/ | 100 | ***************************************************************************/ |
| 101 | %extend GFits { | 101 | %extend GFits { |
| 102 | GFitsHDU* __getitem__(const int& extno) { | 102 | GFitsHDU* __getitem__(const int& extno) { |
| 103 | + // Counting from start, e.g. [2] | ||
| 103 | if (extno >= 0 && extno < self->size()) { | 104 | if (extno >= 0 && extno < self->size()) { |
| 104 | return (*self)[extno]; | 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 | else { | 111 | else { |
| 107 | throw GException::out_of_range("__getitem__(int)", | 112 | throw GException::out_of_range("__getitem__(int)", |
| 108 | "Extension number", | 113 | "Extension number", |
| @@ -112,10 +117,43 @@ public: | @@ -112,10 +117,43 @@ public: | ||
| 112 | GFitsHDU* __getitem__(const std::string& extname) { | 117 | GFitsHDU* __getitem__(const std::string& extname) { |
| 113 | return (*self)[extname]; | 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 | void __setitem__(const int& extno, const GFitsHDU& hdu) { | 149 | void __setitem__(const int& extno, const GFitsHDU& hdu) { |
| 150 | + // Counting from start, e.g. [2] | ||
| 116 | if (extno >= 0 && extno < self->size()) { | 151 | if (extno >= 0 && extno < self->size()) { |
| 117 | self->set(extno, hdu); | 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 | else { | 158 | else { |
| 121 | throw GException::out_of_range("__setitem__(int)", | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -29,15 +29,13 @@ | @@ -29,15 +29,13 @@ | ||
| 29 | #include "GTools.hpp" | 29 | #include "GTools.hpp" |
| 30 | %} | 30 | %} |
| 31 | 31 | ||
| 32 | -//%include stl.i | ||
| 33 | - | ||
| 34 | 32 | ||
| 35 | /***********************************************************************//** | 33 | /***********************************************************************//** |
| 36 | * @class GFitsHeader | 34 | * @class GFitsHeader |
| 37 | * | 35 | * |
| 38 | * @brief Interface for FITS header class | 36 | * @brief Interface for FITS header class |
| 39 | ***************************************************************************/ | 37 | ***************************************************************************/ |
| 40 | -class GFitsHeader : public GBase { | 38 | +class GFitsHeader : public GContainer { |
| 41 | public: | 39 | public: |
| 42 | // Constructors and destructors | 40 | // Constructors and destructors |
| 43 | GFitsHeader(void); | 41 | GFitsHeader(void); |
| @@ -77,9 +75,14 @@ public: | @@ -77,9 +75,14 @@ public: | ||
| 77 | ***************************************************************************/ | 75 | ***************************************************************************/ |
| 78 | %extend GFitsHeader { | 76 | %extend GFitsHeader { |
| 79 | GFitsHeaderCard& __getitem__(const int& cardno) { | 77 | GFitsHeaderCard& __getitem__(const int& cardno) { |
| 78 | + // Counting from start, e.g. [2] | ||
| 80 | if (cardno >= 0 && cardno < self->size()) { | 79 | if (cardno >= 0 && cardno < self->size()) { |
| 81 | return (*self)[cardno]; | 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 | else { | 86 | else { |
| 84 | throw GException::out_of_range("__getitem__(int)", | 87 | throw GException::out_of_range("__getitem__(int)", |
| 85 | "Header card number", | 88 | "Header card number", |
| @@ -89,10 +92,43 @@ public: | @@ -89,10 +92,43 @@ public: | ||
| 89 | GFitsHeaderCard& __getitem__(const std::string& keyname) { | 92 | GFitsHeaderCard& __getitem__(const std::string& keyname) { |
| 90 | return (*self)[keyname]; | 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 | void __setitem__(const int& cardno, const GFitsHeaderCard& card) { | 124 | void __setitem__(const int& cardno, const GFitsHeaderCard& card) { |
| 125 | + // Counting from start, e.g. [2] | ||
| 93 | if (cardno >= 0 && cardno < self->size()) { | 126 | if (cardno >= 0 && cardno < self->size()) { |
| 94 | (*self)[cardno] = card; | 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 | else { | 133 | else { |
| 98 | throw GException::out_of_range("__setitem__(int)", | 134 | throw GException::out_of_range("__setitem__(int)", |
pyext/GNodeArray.i
| @@ -86,17 +86,55 @@ public: | @@ -86,17 +86,55 @@ public: | ||
| 86 | ***************************************************************************/ | 86 | ***************************************************************************/ |
| 87 | %extend GNodeArray { | 87 | %extend GNodeArray { |
| 88 | double __getitem__(const int& index) { | 88 | double __getitem__(const int& index) { |
| 89 | + // Counting from start, e.g. [2] | ||
| 89 | if (index >= 0 && index < self->size()) { | 90 | if (index >= 0 && index < self->size()) { |
| 90 | return (*self)[index]; | 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 | else { | 97 | else { |
| 93 | throw GException::out_of_range("__getitem__(int)", index, self->size()); | 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 | void __setitem__(const int& index, const double& val) { | 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 | (*self)[index] = val; | 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 | else { | 139 | else { |
| 102 | throw GException::out_of_range("__setitem__(int)", index, self->size()); | 140 | throw GException::out_of_range("__setitem__(int)", index, self->size()); |
pyext/GOptimizerPars.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GOptimizerPars.i - Optimizer parameter container class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -52,6 +52,7 @@ public: | @@ -52,6 +52,7 @@ public: | ||
| 52 | int nfree(void) const; | 52 | int nfree(void) const; |
| 53 | GOptimizerPar* set(const int& index, const GOptimizerPar& par); | 53 | GOptimizerPar* set(const int& index, const GOptimizerPar& par); |
| 54 | GOptimizerPar* set(const std::string& name, const GOptimizerPar& par); | 54 | GOptimizerPar* set(const std::string& name, const GOptimizerPar& par); |
| 55 | + GOptimizerPar* append(const GOptimizerPar& par); | ||
| 55 | void attach(GOptimizerPar *par); | 56 | void attach(GOptimizerPar *par); |
| 56 | void attach(const int& index, GOptimizerPar* par); | 57 | void attach(const int& index, GOptimizerPar* par); |
| 57 | void attach(const std::string& name, GOptimizerPar* par); | 58 | void attach(const std::string& name, GOptimizerPar* par); |
| @@ -70,9 +71,14 @@ public: | @@ -70,9 +71,14 @@ public: | ||
| 70 | ***************************************************************************/ | 71 | ***************************************************************************/ |
| 71 | %extend GOptimizerPars { | 72 | %extend GOptimizerPars { |
| 72 | GOptimizerPar* __getitem__(const int& index) { | 73 | GOptimizerPar* __getitem__(const int& index) { |
| 74 | + // Counting from start, e.g. [2] | ||
| 73 | if (index >= 0 && index < self->size()) { | 75 | if (index >= 0 && index < self->size()) { |
| 74 | return (*self)[index]; | 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 | else { | 82 | else { |
| 77 | throw GException::out_of_range("__getitem__(int)", "Parameter index", | 83 | throw GException::out_of_range("__getitem__(int)", "Parameter index", |
| 78 | index, self->size()); | 84 | index, self->size()); |
| @@ -81,10 +87,43 @@ public: | @@ -81,10 +87,43 @@ public: | ||
| 81 | GOptimizerPar* __getitem__(const std::string& name) { | 87 | GOptimizerPar* __getitem__(const std::string& name) { |
| 82 | return (*self)[name]; | 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 | void __setitem__(const int& index, GOptimizerPar* par) { | 119 | void __setitem__(const int& index, GOptimizerPar* par) { |
| 120 | + // Counting from start, e.g. [2] | ||
| 85 | if (index >= 0 && index < self->size()) { | 121 | if (index >= 0 && index < self->size()) { |
| 86 | self->attach(index, par); | 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 | else { | 128 | else { |
| 90 | throw GException::out_of_range("__setitem__(int)", "Parameter index", | 129 | throw GException::out_of_range("__setitem__(int)", "Parameter index", |
pyext/GSkyRegion.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GSkyRegion.i - Sky region class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -55,6 +55,9 @@ public: | @@ -55,6 +55,9 @@ public: | ||
| 55 | const std::string& type(void) const; | 55 | const std::string& type(void) const; |
| 56 | const std::string& name(void) const; | 56 | const std::string& name(void) const; |
| 57 | const double& solidangle(void) const; | 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
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GSkyRegions.i - Sky region container class * | 2 | * GSkyRegions.i - Sky region container class * |
| 3 | * ----------------------------------------------------------------------- * | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2013-2016 by Pierrick Martin * | 4 | + * copyright (C) 2013-2017 by Pierrick Martin * |
| 5 | * ----------------------------------------------------------------------- * | 5 | * ----------------------------------------------------------------------- * |
| 6 | * * | 6 | * * |
| 7 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -67,17 +67,55 @@ public: | @@ -67,17 +67,55 @@ public: | ||
| 67 | ***************************************************************************/ | 67 | ***************************************************************************/ |
| 68 | %extend GSkyRegions { | 68 | %extend GSkyRegions { |
| 69 | GSkyRegion* __getitem__(const int& index) { | 69 | GSkyRegion* __getitem__(const int& index) { |
| 70 | + // Counting from start, e.g. [2] | ||
| 70 | if (index >= 0 && index < self->size()) { | 71 | if (index >= 0 && index < self->size()) { |
| 71 | return (*self)[index]; | 72 | return (*self)[index]; |
| 72 | } | 73 | } |
| 74 | + // Counting from end, e.g. [-1] | ||
| 75 | + else if (index < 0 && self->size()+index >= 0) { | ||
| 76 | + return (*self)[self->size()+index]; | ||
| 77 | + } | ||
| 73 | else { | 78 | else { |
| 74 | throw GException::out_of_range("__getitem__(int)", index, self->size()); | 79 | throw GException::out_of_range("__getitem__(int)", index, self->size()); |
| 75 | } | 80 | } |
| 76 | } | 81 | } |
| 82 | + GSkyRegions* __getitem__(PyObject *param) { | ||
| 83 | + if (PySlice_Check(param)) { | ||
| 84 | + Py_ssize_t start = 0; | ||
| 85 | + Py_ssize_t stop = 0; | ||
| 86 | + Py_ssize_t step = 0; | ||
| 87 | + Py_ssize_t len = self->size(); | ||
| 88 | + if (PySlice_GetIndices((PySliceObject*)param, len, &start, &stop, &step) == 0) { | ||
| 89 | + GSkyRegions* regions = new GSkyRegions; | ||
| 90 | + if (step > 0) { | ||
| 91 | + for (int i = (int)start; i < (int)stop; i += (int)step) { | ||
| 92 | + regions->append(*(*self)[i]); | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | + else { | ||
| 96 | + for (int i = (int)start; i > (int)stop; i += (int)step) { | ||
| 97 | + regions->append(*(*self)[i]); | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + return regions; | ||
| 101 | + } | ||
| 102 | + else { | ||
| 103 | + throw GException::invalid_argument("__getitem__(PyObject)", | ||
| 104 | + "Invalid slice indices"); | ||
| 105 | + } | ||
| 106 | + } | ||
| 107 | + else { | ||
| 108 | + throw GException::invalid_argument("__getitem__(PyObject)",""); | ||
| 109 | + } | ||
| 110 | + } | ||
| 77 | void __setitem__(const int& index, const GSkyRegion& val) { | 111 | void __setitem__(const int& index, const GSkyRegion& val) { |
| 78 | - if (index>=0 && index < self->size()) { | 112 | + // Counting from start, e.g. [2] |
| 113 | + if (index >= 0 && index < self->size()) { | ||
| 79 | self->set(index, val); | 114 | self->set(index, val); |
| 80 | - return; | 115 | + } |
| 116 | + // Counting from end, e.g. [-1] | ||
| 117 | + else if (index < 0 && self->size()+index >= 0) { | ||
| 118 | + self->set(self->size()+index, val); | ||
| 81 | } | 119 | } |
| 82 | else { | 120 | else { |
| 83 | throw GException::out_of_range("__setitem__(int)", index, self->size()); | 121 | throw GException::out_of_range("__setitem__(int)", index, self->size()); |
pyext/GTestSuites.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GTestSuites.i - Test suite container class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -73,17 +73,55 @@ public: | @@ -73,17 +73,55 @@ public: | ||
| 73 | ***************************************************************************/ | 73 | ***************************************************************************/ |
| 74 | %extend GTestSuites { | 74 | %extend GTestSuites { |
| 75 | GTestSuite* __getitem__(const int& index) { | 75 | GTestSuite* __getitem__(const int& index) { |
| 76 | + // Counting from start, e.g. [2] | ||
| 76 | if (index >= 0 && index < self->size()) { | 77 | if (index >= 0 && index < self->size()) { |
| 77 | return (*self)[index]; | 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 | else { | 84 | else { |
| 80 | throw GException::out_of_range("__getitem__(int)", index, self->size()); | 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 | void __setitem__(const int& index, const GTestSuite& suite) { | 117 | void __setitem__(const int& index, const GTestSuite& suite) { |
| 118 | + // Counting from start, e.g. [2] | ||
| 84 | if (index >= 0 && index < self->size()) { | 119 | if (index >= 0 && index < self->size()) { |
| 85 | self->set(index, suite); | 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 | else { | 126 | else { |
| 89 | throw GException::out_of_range("__setitem__(int)", index, self->size()); | 127 | throw GException::out_of_range("__setitem__(int)", index, self->size()); |
pyext/GXml.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GXml.i - XML class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -74,27 +74,60 @@ public: | @@ -74,27 +74,60 @@ public: | ||
| 74 | ***************************************************************************/ | 74 | ***************************************************************************/ |
| 75 | %extend GXml { | 75 | %extend GXml { |
| 76 | GXmlNode* __getitem__(const int& index) { | 76 | GXmlNode* __getitem__(const int& index) { |
| 77 | + // Counting from start, e.g. [2] | ||
| 77 | if (index >= 0 && index < self->size()) { | 78 | if (index >= 0 && index < self->size()) { |
| 78 | return (*self)[index]; | 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 | else { | 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 | void __setitem__(const int& index, const GXmlNode& node) { | 118 | void __setitem__(const int& index, const GXmlNode& node) { |
| 119 | + // Counting from start, e.g. [2] | ||
| 86 | if (index >= 0 && index < self->size()) { | 120 | if (index >= 0 && index < self->size()) { |
| 87 | self->set(index, node); | 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 | else { | 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 | GXml copy() { | 131 | GXml copy() { |
| 99 | return (*self); | 132 | return (*self); |
| 100 | } | 133 | } |
pyext/GXmlElement.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GXmlElement.i - XML element node class definition * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -61,6 +61,61 @@ public: | @@ -61,6 +61,61 @@ public: | ||
| 61 | * @brief GXmlElement class extension | 61 | * @brief GXmlElement class extension |
| 62 | ***************************************************************************/ | 62 | ***************************************************************************/ |
| 63 | %extend GXmlElement { | 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 | GXmlElement copy() { | 119 | GXmlElement copy() { |
| 65 | return (*self); | 120 | return (*self); |
| 66 | } | 121 | } |
pyext/GXmlNode.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GXmlNode.i - Abstract XML node base class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -36,7 +36,7 @@ | @@ -36,7 +36,7 @@ | ||
| 36 | * | 36 | * |
| 37 | * @brief Abstract XML node base class | 37 | * @brief Abstract XML node base class |
| 38 | ***************************************************************************/ | 38 | ***************************************************************************/ |
| 39 | -class GXmlNode : public GBase { | 39 | +class GXmlNode : public GContainer { |
| 40 | public: | 40 | public: |
| 41 | // Constructors and destructors | 41 | // Constructors and destructors |
| 42 | GXmlNode(void); | 42 | GXmlNode(void); |
| @@ -89,25 +89,29 @@ public: | @@ -89,25 +89,29 @@ public: | ||
| 89 | return gammalib::tochar(self->print(NORMAL, 0)); | 89 | return gammalib::tochar(self->print(NORMAL, 0)); |
| 90 | } | 90 | } |
| 91 | GXmlNode* __getitem__(const int& index) { | 91 | GXmlNode* __getitem__(const int& index) { |
| 92 | + // Counting from start, e.g. [2] | ||
| 92 | if (index >= 0 && index < self->size()) { | 93 | if (index >= 0 && index < self->size()) { |
| 93 | return (*self)[index]; | 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 | else { | 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 | void __setitem__(const int& index, const GXmlNode& node) { | 104 | void __setitem__(const int& index, const GXmlNode& node) { |
| 105 | + // Counting from start, e.g. [2] | ||
| 101 | if (index >= 0 && index < self->size()) { | 106 | if (index >= 0 && index < self->size()) { |
| 102 | self->set(index, node); | 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 | else { | 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/opt/GOptimizerPar.cpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GOptimizerPar.cpp - Optimizer parameter class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -700,8 +700,8 @@ std::string GOptimizerPar::print(const GChatter& chatter) const | @@ -700,8 +700,8 @@ std::string GOptimizerPar::print(const GChatter& chatter) const | ||
| 700 | void GOptimizerPar::init_members(void) | 700 | void GOptimizerPar::init_members(void) |
| 701 | { | 701 | { |
| 702 | // Initialise members | 702 | // Initialise members |
| 703 | - m_name = ""; | ||
| 704 | - m_unit = ""; | 703 | + m_name.clear(); |
| 704 | + m_unit.clear(); | ||
| 705 | m_factor_value = 0.0; | 705 | m_factor_value = 0.0; |
| 706 | m_factor_error = 0.0; | 706 | m_factor_error = 0.0; |
| 707 | m_factor_gradient = 0.0; | 707 | m_factor_gradient = 0.0; |
src/opt/GOptimizerPars.cpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GOptimizerPars.cpp - Optimizer parameter container class * | 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 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -392,6 +392,30 @@ GOptimizerPar* GOptimizerPars::set(const std::string& name, const GOptimizerPar& | @@ -392,6 +392,30 @@ GOptimizerPar* GOptimizerPars::set(const std::string& name, const GOptimizerPar& | ||
| 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 | * @brief Attach parameter to container | 419 | * @brief Attach parameter to container |
| 396 | * | 420 | * |
| 397 | * @param[in] par Parameter pointer. | 421 | * @param[in] par Parameter pointer. |
| @@ -680,6 +704,7 @@ std::string GOptimizerPars::print(const GChatter& chatter) const | @@ -680,6 +704,7 @@ std::string GOptimizerPars::print(const GChatter& chatter) const | ||
| 680 | 704 | ||
| 681 | // Append parameters | 705 | // Append parameters |
| 682 | for (int i = 0; i < size(); ++i) { | 706 | for (int i = 0; i < size(); ++i) { |
| 707 | +std::cout << i << " " << m_pars[i] << std::endl; | ||
| 683 | result.append("\n"+m_pars[i]->print(chatter)); | 708 | result.append("\n"+m_pars[i]->print(chatter)); |
| 684 | } | 709 | } |
| 685 | 710 |
test/test_GFits.py
| @@ -27,11 +27,12 @@ import gammalib | @@ -27,11 +27,12 @@ import gammalib | ||
| 27 | # =================================== # | 27 | # =================================== # |
| 28 | class Test(gammalib.GPythonTestSuite): | 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 | def __init__(self): | 33 | def __init__(self): |
| 33 | """ | 34 | """ |
| 34 | - Constructor. | 35 | + Constructor |
| 35 | """ | 36 | """ |
| 36 | # Call base class constructor | 37 | # Call base class constructor |
| 37 | gammalib.GPythonTestSuite.__init__(self) | 38 | gammalib.GPythonTestSuite.__init__(self) |
| @@ -39,25 +40,236 @@ class Test(gammalib.GPythonTestSuite): | @@ -39,25 +40,236 @@ class Test(gammalib.GPythonTestSuite): | ||
| 39 | # Return | 40 | # Return |
| 40 | return | 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 | # Return | 213 | # Return |
| 56 | return | 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 | # Get test data directory | 274 | # Get test data directory |
| 63 | datadir = os.environ['TEST_DATA'] + '/' | 275 | datadir = os.environ['TEST_DATA'] + '/' |
| @@ -66,33 +278,33 @@ class Test(gammalib.GPythonTestSuite): | @@ -66,33 +278,33 @@ class Test(gammalib.GPythonTestSuite): | ||
| 66 | file = gammalib.GFilename(datadir+'file.fits') | 278 | file = gammalib.GFilename(datadir+'file.fits') |
| 67 | 279 | ||
| 68 | # Test loading of FITS file | 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 | try: | 282 | try: |
| 71 | fits = gammalib.GFits(file) | 283 | fits = gammalib.GFits(file) |
| 72 | self.test_try_success() | 284 | self.test_try_success() |
| 73 | except: | 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 | # Test creation of FITS file | 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 | try: | 290 | try: |
| 79 | - fits = gammalib.GFits("test_file.fits", True) | 291 | + fits = gammalib.GFits('test_file.fits', True) |
| 80 | self.test_try_success() | 292 | self.test_try_success() |
| 81 | except: | 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 | # Open FITS file | 296 | # Open FITS file |
| 85 | fits = gammalib.GFits(file) | 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 | # Open FITS file with event selection | 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 | # Open FITS file with non-existing extension name | 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 | try: | 306 | try: |
| 95 | - fits = gammalib.GFits(file+"[DUMMY][ENERGY>1.0]") | 307 | + fits = gammalib.GFits(file+'[DUMMY][ENERGY>1.0]') |
| 96 | self.test_try_failure() | 308 | self.test_try_failure() |
| 97 | except: | 309 | except: |
| 98 | self.test_try_success() | 310 | self.test_try_success() |
| @@ -100,13 +312,14 @@ class Test(gammalib.GPythonTestSuite): | @@ -100,13 +312,14 @@ class Test(gammalib.GPythonTestSuite): | ||
| 100 | # Return | 312 | # Return |
| 101 | return | 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 | # Set test file names | 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 | # Remove test files | 324 | # Remove test files |
| 112 | file1.remove() | 325 | file1.remove() |
| @@ -138,15 +351,15 @@ class Test(gammalib.GPythonTestSuite): | @@ -138,15 +351,15 @@ class Test(gammalib.GPythonTestSuite): | ||
| 138 | img7[x, y] = x + y * nx | 351 | img7[x, y] = x + y * nx |
| 139 | img8[x, y] = x + y * nx | 352 | img8[x, y] = x + y * nx |
| 140 | img9[x, y] = x + y * nx | 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 | # Test image types by checking the bitpix values | 364 | # Test image types by checking the bitpix values |
| 152 | self.test_value(img1.bitpix(), 8) | 365 | self.test_value(img1.bitpix(), 8) |
| @@ -172,9 +385,9 @@ class Test(gammalib.GPythonTestSuite): | @@ -172,9 +385,9 @@ class Test(gammalib.GPythonTestSuite): | ||
| 172 | 385 | ||
| 173 | # Set header keywords | 386 | # Set header keywords |
| 174 | img_byte = fits.image(0) | 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 | # Save FITS file | 392 | # Save FITS file |
| 180 | fits.save() | 393 | fits.save() |
| @@ -198,7 +411,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -198,7 +411,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 198 | 411 | ||
| 199 | # Get double precision image, take square root of pixel and save in | 412 | # Get double precision image, take square root of pixel and save in |
| 200 | # another file | 413 | # another file |
| 201 | - img_double = fits.image("Double") | 414 | + img_double = fits.image('Double') |
| 202 | for x in range(nx): | 415 | for x in range(nx): |
| 203 | for y in range(ny): | 416 | for y in range(ny): |
| 204 | img_double[x, y] = math.sqrt(img_double[x, y]) | 417 | img_double[x, y] = math.sqrt(img_double[x, y]) |
| @@ -232,13 +445,14 @@ class Test(gammalib.GPythonTestSuite): | @@ -232,13 +445,14 @@ class Test(gammalib.GPythonTestSuite): | ||
| 232 | # Return | 445 | # Return |
| 233 | return | 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 | # Set test file names | 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 | # Remove test files | 457 | # Remove test files |
| 244 | file1.remove() | 458 | file1.remove() |
| @@ -249,17 +463,17 @@ class Test(gammalib.GPythonTestSuite): | @@ -249,17 +463,17 @@ class Test(gammalib.GPythonTestSuite): | ||
| 249 | 463 | ||
| 250 | # Create table columns | 464 | # Create table columns |
| 251 | nrows = 10 | 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 | for i in range(nrows): | 477 | for i in range(nrows): |
| 264 | #col1[i] = i % 2 # Old swig version | 478 | #col1[i] = i % 2 # Old swig version |
| 265 | #col2[i] = i % 2 # Old swig version | 479 | #col2[i] = i % 2 # Old swig version |
| @@ -288,7 +502,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -288,7 +502,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 288 | tbl_ascii.append(col9) | 502 | tbl_ascii.append(col9) |
| 289 | tbl_ascii.append(col10) | 503 | tbl_ascii.append(col10) |
| 290 | tbl_ascii.append(col11) | 504 | tbl_ascii.append(col11) |
| 291 | - tbl_ascii.extname("ASCII table") | 505 | + tbl_ascii.extname('ASCII table') |
| 292 | fits.append(tbl_ascii) | 506 | fits.append(tbl_ascii) |
| 293 | 507 | ||
| 294 | # Set binary table | 508 | # Set binary table |
| @@ -304,7 +518,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -304,7 +518,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 304 | tbl_bin.append(col9) | 518 | tbl_bin.append(col9) |
| 305 | tbl_bin.append(col10) | 519 | tbl_bin.append(col10) |
| 306 | tbl_bin.append(col11) | 520 | tbl_bin.append(col11) |
| 307 | - tbl_bin.extname("Binary table") | 521 | + tbl_bin.extname('Binary table') |
| 308 | fits.append(tbl_bin) | 522 | fits.append(tbl_bin) |
| 309 | 523 | ||
| 310 | # Save FITS file | 524 | # Save FITS file |
| @@ -316,36 +530,37 @@ class Test(gammalib.GPythonTestSuite): | @@ -316,36 +530,37 @@ class Test(gammalib.GPythonTestSuite): | ||
| 316 | # Return | 530 | # Return |
| 317 | return | 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 | Test FITS table columns | 536 | Test FITS table columns |
| 322 | """ | 537 | """ |
| 323 | # Create table columns | 538 | # Create table columns |
| 324 | nrows = 10 | 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 | # Test number of rows | 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 | # Test iterators | 565 | # Test iterators |
| 351 | for row in col1: | 566 | for row in col1: |
| @@ -373,28 +588,48 @@ class Test(gammalib.GPythonTestSuite): | @@ -373,28 +588,48 @@ class Test(gammalib.GPythonTestSuite): | ||
| 373 | 588 | ||
| 374 | # Test setting and retrieving of values | 589 | # Test setting and retrieving of values |
| 375 | col1[5] = True | 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 | col2[5] = True | 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 | col3[5] = 5 | 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 | col4[5] = 3.14 | 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 | col5[5] = 3.14 | 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 | col6[5] = 314 | 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 | col7[5] = 314 | 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 | col8[5] = 314 | 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 | col10[5] = 314 | 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 | col11[5] = 314 | 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 | # Return | 634 | # Return |
| 399 | return | 635 | return |
| 400 | - |
test/test_GObservation.py
| @@ -649,24 +649,8 @@ class Test(gammalib.GPythonTestSuite): | @@ -649,24 +649,8 @@ class Test(gammalib.GPythonTestSuite): | ||
| 649 | # Setup photons container | 649 | # Setup photons container |
| 650 | photons = self._setup_photons() | 650 | photons = self._setup_photons() |
| 651 | 651 | ||
| 652 | - # Loop over all elements using the container iterator and count the | ||
| 653 | - # number of iterations | ||
| 654 | - nphotons = 0 | ||
| 655 | - reference = 0.0 | ||
| 656 | - for photon in photons: | ||
| 657 | - self.test_value(photon.energy().MeV(), reference) | ||
| 658 | - nphotons += 1 | ||
| 659 | - reference += 1.0 | ||
| 660 | - | ||
| 661 | - # Check that looping was successful | ||
| 662 | - self.test_value(photons.size(), 10, 'Check container size') | ||
| 663 | - self.test_value(nphotons, 10, 'Check container iterator') | ||
| 664 | - | ||
| 665 | - # Test access from start | ||
| 666 | - self.test_value(photons[3].energy().MeV(), 3.0) | ||
| 667 | - | ||
| 668 | - # Check access from end | ||
| 669 | - self.test_value(photons[-2].energy().MeV(), 8.0) | 652 | + # Perform photons access tests |
| 653 | + test_support._energy_container_access_index(self, photons) | ||
| 670 | 654 | ||
| 671 | # Return | 655 | # Return |
| 672 | return | 656 | return |
| @@ -679,47 +663,8 @@ class Test(gammalib.GPythonTestSuite): | @@ -679,47 +663,8 @@ class Test(gammalib.GPythonTestSuite): | ||
| 679 | # Setup photons container | 663 | # Setup photons container |
| 680 | photons = self._setup_photons() | 664 | photons = self._setup_photons() |
| 681 | 665 | ||
| 682 | - # Test photons[start:end] | ||
| 683 | - self.test_value(len(photons[3:5]), 2) | ||
| 684 | - self.test_value(photons[3:5][0].energy().MeV(), 3.0) | ||
| 685 | - self.test_value(photons[3:5][1].energy().MeV(), 4.0) | ||
| 686 | - | ||
| 687 | - # Test photons[start:] | ||
| 688 | - self.test_value(len(photons[7:]), 3) | ||
| 689 | - self.test_value(photons[7:][0].energy().MeV(), 7.0) | ||
| 690 | - self.test_value(photons[7:][1].energy().MeV(), 8.0) | ||
| 691 | - self.test_value(photons[7:][2].energy().MeV(), 9.0) | ||
| 692 | - | ||
| 693 | - # Test photons[:end] | ||
| 694 | - self.test_value(len(photons[:2]), 2) | ||
| 695 | - self.test_value(photons[:2][0].energy().MeV(), 0.0) | ||
| 696 | - self.test_value(photons[:2][1].energy().MeV(), 1.0) | ||
| 697 | - | ||
| 698 | - # Test photons[:] | ||
| 699 | - self.test_value(len(photons[:]), 10) | ||
| 700 | - for i in range(10): | ||
| 701 | - self.test_value(photons[:][i].energy().MeV(), float(i)) | ||
| 702 | - | ||
| 703 | - # Test photons[start:end:step] | ||
| 704 | - self.test_value(len(photons[3:7:2]), 2) | ||
| 705 | - self.test_value(photons[3:7:2][0].energy().MeV(), 3.0) | ||
| 706 | - self.test_value(photons[3:7:2][1].energy().MeV(), 5.0) | ||
| 707 | - | ||
| 708 | - # Test photons[start:end:step] | ||
| 709 | - self.test_value(len(photons[6:3:-2]), 2) | ||
| 710 | - self.test_value(photons[6:3:-2][0].energy().MeV(), 6.0) | ||
| 711 | - self.test_value(photons[6:3:-2][1].energy().MeV(), 4.0) | ||
| 712 | - | ||
| 713 | - # Test photons[-start:] | ||
| 714 | - self.test_value(len(photons[-2:]), 2) | ||
| 715 | - self.test_value(photons[-2:][0].energy().MeV(), 8.0) | ||
| 716 | - self.test_value(photons[-2:][1].energy().MeV(), 9.0) | ||
| 717 | - | ||
| 718 | - # Test photons[:-end] | ||
| 719 | - self.test_value(len(photons[:-7]), 3) | ||
| 720 | - self.test_value(photons[:-7][0].energy().MeV(), 0.0) | ||
| 721 | - self.test_value(photons[:-7][1].energy().MeV(), 1.0) | ||
| 722 | - self.test_value(photons[:-7][2].energy().MeV(), 2.0) | 666 | + # Perform slicing tests |
| 667 | + test_support._energy_container_slicing(self, photons) | ||
| 723 | 668 | ||
| 724 | # Return | 669 | # Return |
| 725 | return | 670 | return |
| @@ -736,16 +681,6 @@ class Test(gammalib.GPythonTestSuite): | @@ -736,16 +681,6 @@ class Test(gammalib.GPythonTestSuite): | ||
| 736 | # Perform observation access tests | 681 | # Perform observation access tests |
| 737 | test_support._container_access_index(self, obs) | 682 | test_support._container_access_index(self, obs) |
| 738 | 683 | ||
| 739 | - # Check observation setting by index from start | ||
| 740 | - run.id('98') | ||
| 741 | - obs[3] = run | ||
| 742 | - self.test_value(obs[3].id(), '98') | ||
| 743 | - | ||
| 744 | - # Check observation setting by index from end | ||
| 745 | - run.id('99') | ||
| 746 | - obs[-2] = run | ||
| 747 | - self.test_value(obs[-2].id(), '99') | ||
| 748 | - | ||
| 749 | # Return | 684 | # Return |
| 750 | return | 685 | return |
| 751 | 686 |
test/test_GOptimizer.py
| 1 | # ========================================================================== | 1 | # ========================================================================== |
| 2 | # This module performs unit tests for the GammaLib optimizer module. | 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 | # This program is free software: you can redistribute it and/or modify | 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 | 7 | # it under the terms of the GNU General Public License as published by |
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # | 18 | # |
| 19 | # ========================================================================== | 19 | # ========================================================================== |
| 20 | import gammalib | 20 | import gammalib |
| 21 | +import test_support | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | # ======================================== # | 24 | # ======================================== # |
| @@ -38,24 +39,76 @@ class Test(gammalib.GPythonTestSuite): | @@ -38,24 +39,76 @@ class Test(gammalib.GPythonTestSuite): | ||
| 38 | # Return | 39 | # Return |
| 39 | return | 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 | # Return | 98 | # Return |
| 53 | return | 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 | # Return | 113 | # Return |
| 61 | return | 114 | return |
test/test_GSky.py
| @@ -20,12 +20,13 @@ | @@ -20,12 +20,13 @@ | ||
| 20 | import os | 20 | import os |
| 21 | import math | 21 | import math |
| 22 | import gammalib | 22 | import gammalib |
| 23 | +import test_support | ||
| 23 | 24 | ||
| 24 | 25 | ||
| 25 | # =========== # | 26 | # =========== # |
| 26 | # Text parser # | 27 | # Text parser # |
| 27 | # =========== # | 28 | # =========== # |
| 28 | -def loadtxt(filename): | 29 | +def _loadtxt(filename): |
| 29 | """ | 30 | """ |
| 30 | Parse text file with columns of floats. | 31 | Parse text file with columns of floats. |
| 31 | 32 | ||
| @@ -63,40 +64,33 @@ class Test(gammalib.GPythonTestSuite): | @@ -63,40 +64,33 @@ class Test(gammalib.GPythonTestSuite): | ||
| 63 | # Return | 64 | # Return |
| 64 | return | 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 | # Test sky map methods | 87 | # Test sky map methods |
| 94 | - def test_methods(self): | 88 | + def _test_methods(self): |
| 95 | """ | 89 | """ |
| 96 | Test the sky map methods. | 90 | Test the sky map methods. |
| 97 | """ | 91 | """ |
| 98 | # Setup sky maps | 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 | # Set sky map shape | 95 | # Set sky map shape |
| 102 | map.shape(3,4) | 96 | map.shape(3,4) |
| @@ -126,7 +120,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -126,7 +120,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 126 | return | 120 | return |
| 127 | 121 | ||
| 128 | # Test sky map friend methods | 122 | # Test sky map friend methods |
| 129 | - def test_friend_methods(self): | 123 | + def _test_friend_methods(self): |
| 130 | """ | 124 | """ |
| 131 | Test the sky map friend methods | 125 | Test the sky map friend methods |
| 132 | """ | 126 | """ |
| @@ -154,12 +148,12 @@ class Test(gammalib.GPythonTestSuite): | @@ -154,12 +148,12 @@ class Test(gammalib.GPythonTestSuite): | ||
| 154 | return | 148 | return |
| 155 | 149 | ||
| 156 | # Test sky map operators | 150 | # Test sky map operators |
| 157 | - def test_operators(self): | 151 | + def _test_operators(self): |
| 158 | """ | 152 | """ |
| 159 | Test the sky map operators. | 153 | Test the sky map operators. |
| 160 | """ | 154 | """ |
| 161 | # Setup sky maps | 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 | map[0] = 1.0 | 157 | map[0] = 1.0 |
| 164 | map[1] = 2.0 | 158 | map[1] = 2.0 |
| 165 | map[2] = 3.0 | 159 | map[2] = 3.0 |
| @@ -218,7 +212,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -218,7 +212,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 218 | return | 212 | return |
| 219 | 213 | ||
| 220 | # Generic skymap pixel transformation test | 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 | Control coordinate and pixel transformation methods. | 217 | Control coordinate and pixel transformation methods. |
| 224 | """ | 218 | """ |
| @@ -226,9 +220,9 @@ class Test(gammalib.GPythonTestSuite): | @@ -226,9 +220,9 @@ class Test(gammalib.GPythonTestSuite): | ||
| 226 | for i in range(pixels.npix()): | 220 | for i in range(pixels.npix()): |
| 227 | dir = pixels.inx2dir(i) | 221 | dir = pixels.inx2dir(i) |
| 228 | inx = pixels.dir2inx(dir) | 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 | self.test_assert(i == inx, msg, err) | 226 | self.test_assert(i == inx, msg, err) |
| 233 | 227 | ||
| 234 | # Control SkyDir coordinate transformation for all pixels | 228 | # Control SkyDir coordinate transformation for all pixels |
| @@ -240,21 +234,21 @@ class Test(gammalib.GPythonTestSuite): | @@ -240,21 +234,21 @@ class Test(gammalib.GPythonTestSuite): | ||
| 240 | if (dra >= 5.0): | 234 | if (dra >= 5.0): |
| 241 | dra -= 2.0 * math.pi | 235 | dra -= 2.0 * math.pi |
| 242 | ddec = abs(dir.dec() - dir_new.dec()) | 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 | self.test_assert(not (dra > 1.0e-9 or ddec > 1.0e-9), msg, err) | 240 | self.test_assert(not (dra > 1.0e-9 or ddec > 1.0e-9), msg, err) |
| 247 | 241 | ||
| 248 | # Return | 242 | # Return |
| 249 | return | 243 | return |
| 250 | 244 | ||
| 251 | # Generic skymap projection test | 245 | # Generic skymap projection test |
| 252 | - def test_skymap_proj(self, proj): | 246 | + def _test_skymap_proj(self, proj): |
| 253 | """ | 247 | """ |
| 254 | Test skymap projection. | 248 | Test skymap projection. |
| 255 | """ | 249 | """ |
| 256 | # Set filename | 250 | # Set filename |
| 257 | - file = "test_python_skymap_" + proj + ".fits" | 251 | + file = 'test_python_skymap_' + proj + '.fits' |
| 258 | 252 | ||
| 259 | # Remove test files | 253 | # Remove test files |
| 260 | try: | 254 | try: |
| @@ -263,26 +257,26 @@ class Test(gammalib.GPythonTestSuite): | @@ -263,26 +257,26 @@ class Test(gammalib.GPythonTestSuite): | ||
| 263 | pass | 257 | pass |
| 264 | 258 | ||
| 265 | # Create skymap | 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 | for map in range(pixels.nmaps()): | 261 | for map in range(pixels.nmaps()): |
| 268 | for i in range(pixels.npix()): | 262 | for i in range(pixels.npix()): |
| 269 | pixels[i, map] = i + map * pixels.npix() | 263 | pixels[i, map] = i + map * pixels.npix() |
| 270 | pixels.save(file) | 264 | pixels.save(file) |
| 271 | 265 | ||
| 272 | # Test coordinate and pixel transformations | 266 | # Test coordinate and pixel transformations |
| 273 | - self.test_skymap_pixels(pixels, proj) | 267 | + self._test_skymap_pixels(pixels, proj) |
| 274 | 268 | ||
| 275 | # Return | 269 | # Return |
| 276 | return | 270 | return |
| 277 | 271 | ||
| 278 | # Test HEALPix projection | 272 | # Test HEALPix projection |
| 279 | - def test_skymap_healpix(self): | 273 | + def _test_skymap_healpix(self): |
| 280 | """ | 274 | """ |
| 281 | Test HEALPix interface. | 275 | Test HEALPix interface. |
| 282 | """ | 276 | """ |
| 283 | # Set filenames | 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 | # Remove test files | 281 | # Remove test files |
| 288 | try: | 282 | try: |
| @@ -292,7 +286,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -292,7 +286,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 292 | pass | 286 | pass |
| 293 | 287 | ||
| 294 | # Create HEALPix skymap | 288 | # Create HEALPix skymap |
| 295 | - pixels = gammalib.GSkyMap("GAL", 2, "RING", 2) | 289 | + pixels = gammalib.GSkyMap('GAL', 2, 'RING', 2) |
| 296 | for i in range(pixels.npix()): | 290 | for i in range(pixels.npix()): |
| 297 | pixels[i] = i + 1.0 | 291 | pixels[i] = i + 1.0 |
| 298 | pixels[i, 1] = i + 1.0 + 1000.0 | 292 | pixels[i, 1] = i + 1.0 + 1000.0 |
| @@ -302,7 +296,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -302,7 +296,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 302 | pixels = gammalib.GSkyMap(file1) | 296 | pixels = gammalib.GSkyMap(file1) |
| 303 | 297 | ||
| 304 | # Control coordinate and pixel transformations | 298 | # Control coordinate and pixel transformations |
| 305 | - self.test_skymap_pixels(pixels, "HEALPix") | 299 | + self._test_skymap_pixels(pixels, 'HEALPix') |
| 306 | 300 | ||
| 307 | # Save HEALPix skymap twice. The second saving should fail. | 301 | # Save HEALPix skymap twice. The second saving should fail. |
| 308 | try: | 302 | try: |
| @@ -311,7 +305,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -311,7 +305,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 311 | except RuntimeError: | 305 | except RuntimeError: |
| 312 | pass | 306 | pass |
| 313 | else: | 307 | else: |
| 314 | - raise RuntimeError("*** TEST ERROR: FITS file overwritten!") | 308 | + raise RuntimeError('*** TEST ERROR: FITS file overwritten!') |
| 315 | pixels.save(file2, True) | 309 | pixels.save(file2, True) |
| 316 | 310 | ||
| 317 | # Load again HEALPix skymap | 311 | # Load again HEALPix skymap |
| @@ -321,117 +315,117 @@ class Test(gammalib.GPythonTestSuite): | @@ -321,117 +315,117 @@ class Test(gammalib.GPythonTestSuite): | ||
| 321 | return | 315 | return |
| 322 | 316 | ||
| 323 | # Test AIT projection | 317 | # Test AIT projection |
| 324 | - def test_skymap_ait(self): | 318 | + def _test_skymap_ait(self): |
| 325 | """ | 319 | """ |
| 326 | Test AIT projection. | 320 | Test AIT projection. |
| 327 | """ | 321 | """ |
| 328 | # Execute generic test | 322 | # Execute generic test |
| 329 | - self.test_skymap_proj("AIT") | 323 | + self._test_skymap_proj('AIT') |
| 330 | 324 | ||
| 331 | # Return | 325 | # Return |
| 332 | return | 326 | return |
| 333 | 327 | ||
| 334 | # Test AZP projection | 328 | # Test AZP projection |
| 335 | - def test_skymap_azp(self): | 329 | + def _test_skymap_azp(self): |
| 336 | """ | 330 | """ |
| 337 | Test AZP projection. | 331 | Test AZP projection. |
| 338 | """ | 332 | """ |
| 339 | # Execute generic test | 333 | # Execute generic test |
| 340 | - self.test_skymap_proj("AZP") | 334 | + self._test_skymap_proj('AZP') |
| 341 | 335 | ||
| 342 | # Return | 336 | # Return |
| 343 | return | 337 | return |
| 344 | 338 | ||
| 345 | # Test CAR projection | 339 | # Test CAR projection |
| 346 | - def test_skymap_car(self): | 340 | + def _test_skymap_car(self): |
| 347 | """ | 341 | """ |
| 348 | Test CAR projection. | 342 | Test CAR projection. |
| 349 | """ | 343 | """ |
| 350 | # Execute generic test | 344 | # Execute generic test |
| 351 | - self.test_skymap_proj("CAR") | 345 | + self._test_skymap_proj('CAR') |
| 352 | 346 | ||
| 353 | # Return | 347 | # Return |
| 354 | return | 348 | return |
| 355 | 349 | ||
| 356 | # Test GLS projection | 350 | # Test GLS projection |
| 357 | - def test_skymap_gls(self): | 351 | + def _test_skymap_gls(self): |
| 358 | """ | 352 | """ |
| 359 | Test GLS projection. | 353 | Test GLS projection. |
| 360 | """ | 354 | """ |
| 361 | # Execute generic test | 355 | # Execute generic test |
| 362 | - self.test_skymap_proj("GLS") | 356 | + self._test_skymap_proj('GLS') |
| 363 | 357 | ||
| 364 | # Return | 358 | # Return |
| 365 | return | 359 | return |
| 366 | 360 | ||
| 367 | # Test MER projection | 361 | # Test MER projection |
| 368 | - def test_skymap_mer(self): | 362 | + def _test_skymap_mer(self): |
| 369 | """ | 363 | """ |
| 370 | Test MER projection. | 364 | Test MER projection. |
| 371 | """ | 365 | """ |
| 372 | # Execute generic test | 366 | # Execute generic test |
| 373 | - self.test_skymap_proj("MER") | 367 | + self._test_skymap_proj('MER') |
| 374 | 368 | ||
| 375 | # Return | 369 | # Return |
| 376 | return | 370 | return |
| 377 | 371 | ||
| 378 | # Test MOL projection | 372 | # Test MOL projection |
| 379 | - def test_skymap_mol(self): | 373 | + def _test_skymap_mol(self): |
| 380 | """ | 374 | """ |
| 381 | Test MOL projection. | 375 | Test MOL projection. |
| 382 | """ | 376 | """ |
| 383 | # Execute generic test | 377 | # Execute generic test |
| 384 | - self.test_skymap_proj("MOL") | 378 | + self._test_skymap_proj('MOL') |
| 385 | 379 | ||
| 386 | # Return | 380 | # Return |
| 387 | return | 381 | return |
| 388 | 382 | ||
| 389 | # Test SIN projection | 383 | # Test SIN projection |
| 390 | - def test_skymap_sin(self): | 384 | + def _test_skymap_sin(self): |
| 391 | """ | 385 | """ |
| 392 | Test SIN projection. | 386 | Test SIN projection. |
| 393 | """ | 387 | """ |
| 394 | # Execute generic test | 388 | # Execute generic test |
| 395 | - self.test_skymap_proj("SIN") | 389 | + self._test_skymap_proj('SIN') |
| 396 | 390 | ||
| 397 | # Return | 391 | # Return |
| 398 | return | 392 | return |
| 399 | 393 | ||
| 400 | # Test SFL projection | 394 | # Test SFL projection |
| 401 | - def test_skymap_sfl(self): | 395 | + def _test_skymap_sfl(self): |
| 402 | """ | 396 | """ |
| 403 | Test SFL projection. | 397 | Test SFL projection. |
| 404 | """ | 398 | """ |
| 405 | # Execute generic test | 399 | # Execute generic test |
| 406 | - self.test_skymap_proj("SFL") | 400 | + self._test_skymap_proj('SFL') |
| 407 | 401 | ||
| 408 | # Return | 402 | # Return |
| 409 | return | 403 | return |
| 410 | 404 | ||
| 411 | # Test STG projection | 405 | # Test STG projection |
| 412 | - def test_skymap_stg(self): | 406 | + def _test_skymap_stg(self): |
| 413 | """ | 407 | """ |
| 414 | Test STG projection. | 408 | Test STG projection. |
| 415 | """ | 409 | """ |
| 416 | # Execute generic test | 410 | # Execute generic test |
| 417 | - self.test_skymap_proj("STG") | 411 | + self._test_skymap_proj('STG') |
| 418 | 412 | ||
| 419 | # Return | 413 | # Return |
| 420 | return | 414 | return |
| 421 | 415 | ||
| 422 | # Test TAN projection | 416 | # Test TAN projection |
| 423 | - def test_skymap_tan(self): | 417 | + def _test_skymap_tan(self): |
| 424 | """ | 418 | """ |
| 425 | Test TAN projection. | 419 | Test TAN projection. |
| 426 | """ | 420 | """ |
| 427 | # Execute generic test | 421 | # Execute generic test |
| 428 | - self.test_skymap_proj("TAN") | 422 | + self._test_skymap_proj('TAN') |
| 429 | 423 | ||
| 430 | # Return | 424 | # Return |
| 431 | return | 425 | return |
| 432 | 426 | ||
| 433 | # FK5 J2000 to Galactic coordinate tranformations | 427 | # FK5 J2000 to Galactic coordinate tranformations |
| 434 | - def test_fk5_to_galactic(self): | 428 | + def _test_fk5_to_galactic(self): |
| 435 | """ | 429 | """ |
| 436 | Test precision of FK5 J2000 to Galactic coordinate tranformations | 430 | Test precision of FK5 J2000 to Galactic coordinate tranformations |
| 437 | against pyast (http://dsberry.github.com/starlink/pyast.html) | 431 | against pyast (http://dsberry.github.com/starlink/pyast.html) |
| @@ -446,8 +440,8 @@ class Test(gammalib.GPythonTestSuite): | @@ -446,8 +440,8 @@ class Test(gammalib.GPythonTestSuite): | ||
| 446 | # Set parameters | 440 | # Set parameters |
| 447 | fk5_filename = datadir + 'initial_coords.txt' | 441 | fk5_filename = datadir + 'initial_coords.txt' |
| 448 | galactic_filename = datadir + 'fk5_to_galactic.txt' | 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 | coordinates = zip(fk5_coordinates, galactic_coordinates) | 445 | coordinates = zip(fk5_coordinates, galactic_coordinates) |
| 452 | max_dist = 0 | 446 | max_dist = 0 |
| 453 | 447 | ||
| @@ -483,3 +477,70 @@ class Test(gammalib.GPythonTestSuite): | @@ -483,3 +477,70 @@ class Test(gammalib.GPythonTestSuite): | ||
| 483 | 477 | ||
| 484 | # Return | 478 | # Return |
| 485 | return | 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 | # This module performs unit tests for the GammaLib support module. | 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 | # This program is free software: you can redistribute it and/or modify | 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 | 7 | # it under the terms of the GNU General Public License as published by |
| @@ -39,26 +39,26 @@ class Test(gammalib.GPythonTestSuite): | @@ -39,26 +39,26 @@ class Test(gammalib.GPythonTestSuite): | ||
| 39 | # Return | 39 | # Return |
| 40 | return | 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 | # Test GNodeArray class | 60 | # Test GNodeArray class |
| 61 | - def test_node_array(self): | 61 | + def _test_node_array(self): |
| 62 | """ | 62 | """ |
| 63 | Test GNodeArray class. | 63 | Test GNodeArray class. |
| 64 | """ | 64 | """ |
| @@ -91,8 +91,91 @@ class Test(gammalib.GPythonTestSuite): | @@ -91,8 +91,91 @@ class Test(gammalib.GPythonTestSuite): | ||
| 91 | # Return | 91 | # Return |
| 92 | return | 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 | # Test GUrlFile class | 177 | # Test GUrlFile class |
| 95 | - def test_url_file(self): | 178 | + def _test_url_file(self): |
| 96 | """ | 179 | """ |
| 97 | Test GUrlFile class. | 180 | Test GUrlFile class. |
| 98 | """ | 181 | """ |
| @@ -113,7 +196,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -113,7 +196,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 113 | return | 196 | return |
| 114 | 197 | ||
| 115 | # Test GUrlString class | 198 | # Test GUrlString class |
| 116 | - def test_url_string(self): | 199 | + def _test_url_string(self): |
| 117 | """ | 200 | """ |
| 118 | Test GUrlString class. | 201 | Test GUrlString class. |
| 119 | """ | 202 | """ |
| @@ -133,7 +216,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -133,7 +216,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 133 | return | 216 | return |
| 134 | 217 | ||
| 135 | # Test GFilename class | 218 | # Test GFilename class |
| 136 | - def test_filename(self): | 219 | + def _test_filename(self): |
| 137 | """ | 220 | """ |
| 138 | Test GFilename class. | 221 | Test GFilename class. |
| 139 | """ | 222 | """ |
| @@ -158,7 +241,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -158,7 +241,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 158 | return | 241 | return |
| 159 | 242 | ||
| 160 | # Test GCsv class | 243 | # Test GCsv class |
| 161 | - def test_csv(self): | 244 | + def _test_csv(self): |
| 162 | """ | 245 | """ |
| 163 | Test GCsv class. | 246 | Test GCsv class. |
| 164 | """ | 247 | """ |
| @@ -195,3 +278,24 @@ class Test(gammalib.GPythonTestSuite): | @@ -195,3 +278,24 @@ class Test(gammalib.GPythonTestSuite): | ||
| 195 | 278 | ||
| 196 | # Return | 279 | # Return |
| 197 | return | 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 | # This module performs unit tests for the GammaLib test module. | 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 | # This program is free software: you can redistribute it and/or modify | 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 | 7 | # it under the terms of the GNU General Public License as published by |
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # | 18 | # |
| 19 | # ========================================================================== | 19 | # ========================================================================== |
| 20 | import gammalib | 20 | import gammalib |
| 21 | +import test_support | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | # =================================== # | 24 | # =================================== # |
| @@ -25,12 +26,12 @@ import gammalib | @@ -25,12 +26,12 @@ import gammalib | ||
| 25 | # =================================== # | 26 | # =================================== # |
| 26 | class Test(gammalib.GPythonTestSuite): | 27 | class Test(gammalib.GPythonTestSuite): |
| 27 | """ | 28 | """ |
| 28 | - Test class for GammaLib test module. | 29 | + Test class for GammaLib test module |
| 29 | """ | 30 | """ |
| 30 | # Constructor | 31 | # Constructor |
| 31 | def __init__(self): | 32 | def __init__(self): |
| 32 | """ | 33 | """ |
| 33 | - Constructor. | 34 | + Constructor |
| 34 | """ | 35 | """ |
| 35 | # Call base class constructor | 36 | # Call base class constructor |
| 36 | gammalib.GPythonTestSuite.__init__(self) | 37 | gammalib.GPythonTestSuite.__init__(self) |
| @@ -38,24 +39,76 @@ class Test(gammalib.GPythonTestSuite): | @@ -38,24 +39,76 @@ class Test(gammalib.GPythonTestSuite): | ||
| 38 | # Return | 39 | # Return |
| 39 | return | 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 | # Return | 98 | # Return |
| 53 | return | 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 | # Return | 113 | # Return |
| 61 | return | 114 | return |
test/test_GXml.py
| 1 | # ========================================================================== | 1 | # ========================================================================== |
| 2 | # This module performs unit tests for the GammaLib xml module. | 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 | # This program is free software: you can redistribute it and/or modify | 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 | 7 | # it under the terms of the GNU General Public License as published by |
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # | 18 | # |
| 19 | # ========================================================================== | 19 | # ========================================================================== |
| 20 | import gammalib | 20 | import gammalib |
| 21 | +import test_support | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | # ================================== # | 24 | # ================================== # |
| @@ -25,7 +26,7 @@ import gammalib | @@ -25,7 +26,7 @@ import gammalib | ||
| 25 | # ================================== # | 26 | # ================================== # |
| 26 | class Test(gammalib.GPythonTestSuite): | 27 | class Test(gammalib.GPythonTestSuite): |
| 27 | """ | 28 | """ |
| 28 | - Test class for GammaLib xml module. | 29 | + Test class for GammaLib xml module |
| 29 | """ | 30 | """ |
| 30 | # Constructor | 31 | # Constructor |
| 31 | def __init__(self): | 32 | def __init__(self): |
| @@ -38,24 +39,137 @@ class Test(gammalib.GPythonTestSuite): | @@ -38,24 +39,137 @@ class Test(gammalib.GPythonTestSuite): | ||
| 38 | # Return | 39 | # Return |
| 39 | return | 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 | # Return | 118 | # Return |
| 53 | return | 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 | # Return | 174 | # Return |
| 61 | return | 175 | return |
test/test_support.py
| @@ -50,6 +50,69 @@ def _container_access_index(testsuite, container): | @@ -50,6 +50,69 @@ def _container_access_index(testsuite, container): | ||
| 50 | # Check access from end | 50 | # Check access from end |
| 51 | testsuite.test_value(container[-2].name(), '8') | 51 | testsuite.test_value(container[-2].name(), '8') |
| 52 | 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 | + | ||
| 53 | # Return | 116 | # Return |
| 54 | return | 117 | return |
| 55 | 118 | ||
| @@ -112,3 +175,63 @@ def _container_slicing(testsuite, container): | @@ -112,3 +175,63 @@ def _container_slicing(testsuite, container): | ||
| 112 | 175 | ||
| 113 | # Return | 176 | # Return |
| 114 | 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 |