Commit 956995475d7c4f1de1538fc26d57514c06501196

Authored by Jürgen Knödlseder
2 parents 986c4d09 82c2d3e1

Merge branch '1996-ctselect-add-phase-info-GCTAEventList' into integration

# Conflicts:
#	ChangeLog
#	inst/cta/include/GCTAEventList.hpp
#	inst/cta/pyext/GCTAEventList.i
ChangeLog
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 * Version 1.3.0 released 3 * Version 1.3.0 released
4 ========================= 4 =========================
5 5
  6 + Add GPhases class (#1996)
6 Add support for Monte Carlo identifier metadata (#1483) 7 Add support for Monte Carlo identifier metadata (#1483)
7 Add GEventList::has_mc_id() and GEventAtom::mc_id() methods (#1483) 8 Add GEventList::has_mc_id() and GEventAtom::mc_id() methods (#1483)
8 Add GEventList::has_phase() and GEventList::has_detxy() methods (#1982) 9 Add GEventList::has_phase() and GEventList::has_detxy() methods (#1982)
@@ -12,6 +12,7 @@ made since the last release of GammaLib. @@ -12,6 +12,7 @@ made since the last release of GammaLib.
12 2. Public interface modifications 12 2. Public interface modifications
13 --------------------------------- 13 ---------------------------------
14 The following classes have been added: 14 The following classes have been added:
  15 +- GPhases
15 - GWcsGLS 16 - GWcsGLS
16 - GWcsSFL 17 - GWcsSFL
17 - GModelSpectralSmoothBrokenPlaw 18 - GModelSpectralSmoothBrokenPlaw
@@ -139,6 +140,8 @@ GEbounds::set_log() method throws an exception if either the minimum or @@ -139,6 +140,8 @@ GEbounds::set_log() method throws an exception if either the minimum or
139 maximum energy are zero. Furthermore, the methods clear the energy boundaries 140 maximum energy are zero. Furthermore, the methods clear the energy boundaries
140 if the requested number of intervals is non-zero (#1989). 141 if the requested number of intervals is non-zero (#1989).
141 142
  143 +The GPhases class has been added to handle phase selections of events (#1996).
  144 +
142 145
143 11. Optimization module 146 11. Optimization module
144 ----------------------- 147 -----------------------
include/GPhases.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * GPhases.hpp - Phase intervals class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2017 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GPhases.hpp
  23 + * @brief Phase intervals class interface definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef GPHASES_HPP
  28 +#define GPHASES_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include <string>
  32 +#include "GContainer.hpp"
  33 +
  34 +/* __ Forward declarations _______________________________________________ */
  35 +
  36 +
  37 +/***********************************************************************//**
  38 + * @class GPhases
  39 + *
  40 + * @brief Phase Intervals class
  41 + ***************************************************************************/
  42 +class GPhases : public GContainer {
  43 +
  44 +public:
  45 + // Constructors and destructors
  46 + GPhases(void);
  47 + GPhases(const GPhases& phases);
  48 + GPhases(const double& pmin, const double& pmax);
  49 + virtual ~GPhases(void);
  50 +
  51 + // Operators
  52 + GPhases& operator=(const GPhases& phases);
  53 +
  54 + // Methods
  55 + void clear(void);
  56 + GPhases* clone(void) const;
  57 + std::string classname(void) const;
  58 + int size(void) const;
  59 + bool is_empty(void) const;
  60 + void append(const double& pmin, const double& pmax);
  61 + void remove(const int& index);
  62 + void reserve(const int& num);
  63 + void extend(const GPhases& phases);
  64 + double pmin(const int& index) const;
  65 + double pmax(const int& index) const;
  66 + std::string print(const GChatter& chatter = NORMAL) const;
  67 +
  68 +protected:
  69 + // Protected methods
  70 + void init_members(void);
  71 + void copy_members(const GPhases& phases);
  72 + void free_members(void);
  73 + void insert_interval(const int& index, const double& pmin,
  74 + const double& pmax);
  75 +
  76 + // Protected data area
  77 + std::vector<double> m_pmin; // Lower phase interval boundaries
  78 + std::vector<double> m_pmax; // Upper phase interval boundaries
  79 +};
  80 +
  81 +
  82 +/***********************************************************************//**
  83 + * @brief Return class name
  84 + *
  85 + * @return String containing the class name ("GPhases").
  86 + ***************************************************************************/
  87 +inline
  88 +std::string GPhases::classname(void) const
  89 +{
  90 + return ("GPhases");
  91 +}
  92 +
  93 +
  94 +/***********************************************************************//**
  95 + * @brief Return number of phase intervals
  96 + *
  97 + * @return Number of phase intervals.
  98 + ***************************************************************************/
  99 +inline
  100 +int GPhases::size(void) const
  101 +{
  102 + return (int)m_pmin.size();
  103 +}
  104 +
  105 +
  106 +/***********************************************************************//**
  107 + * @brief Signal if there are no phase intervals
  108 + *
  109 + * @return True if there are no phase intervals.
  110 + ***************************************************************************/
  111 +inline
  112 +bool GPhases::is_empty(void) const
  113 +{
  114 + return (m_pmin.size() == 0);
  115 +}
  116 +
  117 +#endif /* GPHASES_HPP */
include/GammaLib.hpp
@@ -183,6 +183,7 @@ @@ -183,6 +183,7 @@
183 #include "GGti.hpp" 183 #include "GGti.hpp"
184 #include "GRoi.hpp" 184 #include "GRoi.hpp"
185 #include "GEbounds.hpp" 185 #include "GEbounds.hpp"
  186 +#include "GPhases.hpp"
186 #include "GInstDir.hpp" 187 #include "GInstDir.hpp"
187 #include "GResponse.hpp" 188 #include "GResponse.hpp"
188 #include "GPhotons.hpp" 189 #include "GPhotons.hpp"
include/Makefile.am
@@ -143,6 +143,7 @@ pkginclude_HEADERS = GammaLib.hpp \ @@ -143,6 +143,7 @@ pkginclude_HEADERS = GammaLib.hpp \
143 GGti.hpp \ 143 GGti.hpp \
144 GRoi.hpp \ 144 GRoi.hpp \
145 GEbounds.hpp \ 145 GEbounds.hpp \
  146 + GPhases.hpp \
146 GInstDir.hpp \ 147 GInstDir.hpp \
147 GResponse.hpp \ 148 GResponse.hpp \
148 GPhotons.hpp \ 149 GPhotons.hpp \
inst/cta/include/GCTAEventList.hpp
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 #include <string> 31 #include <string>
32 #include <vector> 32 #include <vector>
33 #include "GEventList.hpp" 33 #include "GEventList.hpp"
  34 +#include "GPhases.hpp"
34 #include "GFilename.hpp" 35 #include "GFilename.hpp"
35 #include "GCTAEventAtom.hpp" 36 #include "GCTAEventAtom.hpp"
36 #include "GCTARoi.hpp" 37 #include "GCTARoi.hpp"
@@ -96,6 +97,8 @@ public: @@ -96,6 +97,8 @@ public:
96 double irf_cache(const std::string& name, const int& index) const; 97 double irf_cache(const std::string& name, const int& index) const;
97 void irf_cache(const std::string& name, const int& index, 98 void irf_cache(const std::string& name, const int& index,
98 const double& irf) const; 99 const double& irf) const;
  100 + const GPhases& phases(void) const;
  101 + void phases(const GPhases& phases);
99 const std::string& gtiname(void) const; 102 const std::string& gtiname(void) const;
100 void has_phase(const bool& has_phase); 103 void has_phase(const bool& has_phase);
101 void has_detxy(const bool& has_detxy); 104 void has_detxy(const bool& has_detxy);
@@ -124,6 +127,7 @@ protected: @@ -124,6 +127,7 @@ protected:
124 127
125 // Event list meta data 128 // Event list meta data
126 GCTARoi m_roi; //!< Region of interest 129 GCTARoi m_roi; //!< Region of interest
  130 + GPhases m_phases; //!< Phase intervals
127 int m_num_events; //!< Number of events 131 int m_num_events; //!< Number of events
128 std::string m_gti_extname; //!< GTI extension name 132 std::string m_gti_extname; //!< GTI extension name
129 bool m_has_phase; //!< Signal presence of phase 133 bool m_has_phase; //!< Signal presence of phase
@@ -192,6 +196,31 @@ const GCTARoi&amp; GCTAEventList::roi(void) const @@ -192,6 +196,31 @@ const GCTARoi&amp; GCTAEventList::roi(void) const
192 196
193 197
194 /***********************************************************************//** 198 /***********************************************************************//**
  199 + * @brief Return phase intervals
  200 + *
  201 + * @return Phase intervals.
  202 + ***************************************************************************/
  203 +inline
  204 +const GPhases& GCTAEventList::phases(void) const
  205 +{
  206 + return (m_phases);
  207 +}
  208 +
  209 +
  210 +/***********************************************************************//**
  211 + * @brief Set phase intervals
  212 + *
  213 + * @param[in] phases Phase intervals.
  214 + ***************************************************************************/
  215 +inline
  216 +void GCTAEventList::phases(const GPhases& phases)
  217 +{
  218 + m_phases = phases;
  219 + return;
  220 +}
  221 +
  222 +
  223 +/***********************************************************************//**
195 * @brief Reserves space for events 224 * @brief Reserves space for events
196 * 225 *
197 * @param[in] number Number of events. 226 * @param[in] number Number of events.
inst/cta/pyext/GCTAEventList.i
@@ -62,17 +62,21 @@ public: @@ -62,17 +62,21 @@ public:
62 void append_column(const GFitsTableCol& column); 62 void append_column(const GFitsTableCol& column);
63 void reserve(const int& number); 63 void reserve(const int& number);
64 void remove(const int& index, const int& number = 1); 64 void remove(const int& index, const int& number = 1);
65 - void write(GFits& fits, const std::string& evtname,  
66 - const std::string& gtiname) const;  
67 - void fetch(void);  
68 - void dispose(void);  
69 - double irf_cache(const std::string& name, const int& index) const;  
70 - void irf_cache(const std::string& name, const int& index, 65 + void write(GFits& fits,
  66 + const std::string& evtname,
  67 + const std::string& gtiname) const;
  68 + void fetch(void) const;
  69 + void dispose(void) const;
  70 + double irf_cache(const std::string& name,
  71 + const int& index) const;
  72 + void irf_cache(const std::string& name,
  73 + const int& index,
71 const double& irf) const; 74 const double& irf) const;
  75 + const GPhases& phases(void) const;
  76 + void phases(const GPhases& phases);
72 const std::string& gtiname(void) const; 77 const std::string& gtiname(void) const;
73 void has_phase(const bool& has_phase); 78 void has_phase(const bool& has_phase);
74 void has_detxy(const bool& has_detxy); 79 void has_detxy(const bool& has_detxy);
75 - void has_mc_id(const bool& has_mc_id);  
76 const bool& has_phase() const; 80 const bool& has_phase() const;
77 const bool& has_detxy() const; 81 const bool& has_detxy() const;
78 const bool& has_mc_id() const; 82 const bool& has_mc_id() const;
inst/cta/src/GCTAEventList.cpp
@@ -53,6 +53,8 @@ @@ -53,6 +53,8 @@
53 #define G_SET_MC_ID_NAMES "GCTAEventList::set_mc_id_names(std::vector<int>&,"\ 53 #define G_SET_MC_ID_NAMES "GCTAEventList::set_mc_id_names(std::vector<int>&,"\
54 " std::vector<std::string>&)" 54 " std::vector<std::string>&)"
55 #define G_FETCH "GCTAEventList::fetch()" 55 #define G_FETCH "GCTAEventList::fetch()"
  56 +#define G_WRITE_DS_KEYS "GCTAEventList::write_ds_keys(GFitsHDU&, "\
  57 + "const std::string&) const"
56 58
57 /* __ Macros _____________________________________________________________ */ 59 /* __ Macros _____________________________________________________________ */
58 60
@@ -439,6 +441,9 @@ void GCTAEventList::read(const GFits&amp; fits) @@ -439,6 +441,9 @@ void GCTAEventList::read(const GFits&amp; fits)
439 // Read energy boundaries from data sub-space keyword 441 // Read energy boundaries from data sub-space keyword
440 m_ebounds = gammalib::read_ds_ebounds(events); 442 m_ebounds = gammalib::read_ds_ebounds(events);
441 443
  444 + // Read phase intervals from data sub-space keyword
  445 + m_phases = gammalib::read_ds_phase(events);
  446 +
442 // If the file name contains an expression then load the events now. 447 // If the file name contains an expression then load the events now.
443 // We do this at the end to make sure that the GTI has been set before. 448 // We do this at the end to make sure that the GTI has been set before.
444 if (m_filename.has_expression()) { 449 if (m_filename.has_expression()) {
@@ -957,6 +962,7 @@ void GCTAEventList::init_members(void) @@ -957,6 +962,7 @@ void GCTAEventList::init_members(void)
957 { 962 {
958 // Initialise members 963 // Initialise members
959 m_roi.clear(); 964 m_roi.clear();
  965 + m_phases.clear();
960 m_events.clear(); 966 m_events.clear();
961 m_columns.clear(); 967 m_columns.clear();
962 m_filename.clear(); 968 m_filename.clear();
@@ -986,6 +992,7 @@ void GCTAEventList::copy_members(const GCTAEventList&amp; list) @@ -986,6 +992,7 @@ void GCTAEventList::copy_members(const GCTAEventList&amp; list)
986 { 992 {
987 // Copy members 993 // Copy members
988 m_roi = list.m_roi; 994 m_roi = list.m_roi;
  995 + m_phases = list.m_phases;
989 m_events = list.m_events; 996 m_events = list.m_events;
990 m_filename = list.m_filename; 997 m_filename = list.m_filename;
991 m_num_events = list.m_num_events; 998 m_num_events = list.m_num_events;
@@ -1337,6 +1344,9 @@ void GCTAEventList::write_events(GFitsBinTable&amp; hdu) const @@ -1337,6 +1344,9 @@ void GCTAEventList::write_events(GFitsBinTable&amp; hdu) const
1337 * @param[in] hdu FITS HDU. 1344 * @param[in] hdu FITS HDU.
1338 * @param[in] gtiname Good Time Interval FITS extension. 1345 * @param[in] gtiname Good Time Interval FITS extension.
1339 * 1346 *
  1347 + * @exception GException::vector_mismatch
  1348 + * Lower and upper phase boundaries have different size.
  1349 + *
1340 * Writes the data sub-space keywords for an event list into the FITS HDU. 1350 * Writes the data sub-space keywords for an event list into the FITS HDU.
1341 * The following keywords will be written: 1351 * The following keywords will be written:
1342 * 1352 *
@@ -1410,6 +1420,30 @@ void GCTAEventList::write_ds_keys(GFitsHDU&amp; hdu, const std::string&amp; gtiname) con @@ -1410,6 +1420,30 @@ void GCTAEventList::write_ds_keys(GFitsHDU&amp; hdu, const std::string&amp; gtiname) con
1410 1420
1411 } // endif: RoI was valid 1421 } // endif: RoI was valid
1412 1422
  1423 + // Check if there are phase interval cuts
  1424 + if (m_phases.size() > 0) {
  1425 +
  1426 + // Set phase interval string
  1427 + std::string dsval4 = "";
  1428 + for (int i = 0; i < m_phases.size(); ++i) {
  1429 + if (i != 0) {
  1430 + dsval4 += ",";
  1431 + }
  1432 + dsval4 += gammalib::str(m_phases.pmin(i)) + ":" +
  1433 + gammalib::str(m_phases.pmax(i));
  1434 + }
  1435 +
  1436 + // Write DS keywords
  1437 + hdu.card("DSTYP"+gammalib::str(ndskeys), "PHASE",
  1438 + "Data sub-space type");
  1439 + hdu.card("DSUNI"+gammalib::str(ndskeys), "DIMENSIONLESS",
  1440 + "Data sub-space unit");
  1441 + hdu.card("DSVAL"+gammalib::str(ndskeys), dsval4,
  1442 + "Data sub-space value");
  1443 + ndskeys++;
  1444 +
  1445 + } // endif: there were phase interval cuts
  1446 +
1413 // Set number of data selection keys 1447 // Set number of data selection keys
1414 hdu.card("NDSKEYS", ndskeys, "Number of data sub-space keys"); 1448 hdu.card("NDSKEYS", ndskeys, "Number of data sub-space keys");
1415 1449
inst/cta/src/GCTASupport.cpp
1 /*************************************************************************** 1 /***************************************************************************
2 * GCTASupport.cpp - CTA support functions * 2 * GCTASupport.cpp - CTA support functions *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2011-2016 by Juergen Knoedlseder * 4 + * copyright (C) 2011-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,13 +36,15 @@ @@ -36,13 +36,15 @@
36 #include "GMath.hpp" 36 #include "GMath.hpp"
37 #include "GFitsHDU.hpp" 37 #include "GFitsHDU.hpp"
38 #include "GEbounds.hpp" 38 #include "GEbounds.hpp"
  39 +#include "GPhases.hpp"
39 #include "GCTARoi.hpp" 40 #include "GCTARoi.hpp"
40 #include "GCTAInstDir.hpp" 41 #include "GCTAInstDir.hpp"
41 42
42 /* __ Method name definitions ____________________________________________ */ 43 /* __ Method name definitions ____________________________________________ */
43 #define G_READ_DS_ROI "gammalib::read_ds_roi(GFitsHDU&)" 44 #define G_READ_DS_ROI "gammalib::read_ds_roi(GFitsHDU&)"
44 #define G_READ_DS_EBOUNDS "gammalib::read_ds_ebounds(GFitsHDU&)" 45 #define G_READ_DS_EBOUNDS "gammalib::read_ds_ebounds(GFitsHDU&)"
45 -#define G_READ_DS_GTI "GGti gammalib::read_ds_gti_extname(GFitsHDU&)" 46 +#define G_READ_DS_PHASE "gammalib::read_ds_phase(GFitsHDU&)"
  47 +#define G_READ_DS_GTI "gammalib::read_ds_gti_extname(GFitsHDU&)"
46 48
47 /* __ Coding definitions _________________________________________________ */ 49 /* __ Coding definitions _________________________________________________ */
48 50
@@ -259,6 +261,69 @@ GEbounds gammalib::read_ds_ebounds(const GFitsHDU&amp; hdu) @@ -259,6 +261,69 @@ GEbounds gammalib::read_ds_ebounds(const GFitsHDU&amp; hdu)
259 261
260 262
261 /***********************************************************************//** 263 /***********************************************************************//**
  264 + * @brief Read phase boundary data sub-space keywords
  265 + *
  266 + * @param[in] hdu FITS HDU
  267 + * @return Phase intervals
  268 + *
  269 + * @exception GException::invalid_value
  270 + * Invalid phase data sub-space encountered
  271 + *
  272 + * Reads the phase boundary data sub-space keywords by searching for a
  273 + * DSTYPx keyword named "PHASE". The data sub-space information is expected
  274 + * to be in the format "0.1:0.3,0.5:0.7", where each subset of numbers
  275 + * represents the minimum and maximum phase. No detailed syntax
  276 + * checking is performed.
  277 + ***************************************************************************/
  278 +GPhases gammalib::read_ds_phase(const GFitsHDU& hdu)
  279 +{
  280 + // Initialise phase intervals
  281 + GPhases phases;
  282 +
  283 + // Get number of data sub-space keywords (default to 0 if keyword is
  284 + // not found)
  285 + int ndskeys = (hdu.has_card("NDSKEYS")) ? hdu.integer("NDSKEYS") : 0;
  286 +
  287 + // Loop over all data sub-space keys
  288 + for (int i = 1; i <= ndskeys; ++i) {
  289 +
  290 + // Set data sub-space key strings
  291 + std::string type_key = "DSTYP"+gammalib::str(i);
  292 + std::string unit_key = "DSUNI"+gammalib::str(i);
  293 + std::string value_key = "DSVAL"+gammalib::str(i);
  294 +
  295 + // Continue only if type_key is found and if this key is PHASE
  296 + if (hdu.has_card(type_key) && hdu.string(type_key) == "PHASE") {
  297 +
  298 + // Extract phase boundaries
  299 + std::string value = hdu.string(value_key);
  300 + std::vector<std::string> intervals = gammalib::split(value, ",");
  301 + for (int j = 0; j < intervals.size(); ++j) {
  302 + std::vector<std::string> values = gammalib::split(intervals[j], ":");
  303 + if (values.size() == 2) {
  304 + double phmin = gammalib::todouble(values[0]);
  305 + double phmax = gammalib::todouble(values[1]);
  306 + phases.append(phmin, phmax);
  307 + }
  308 + else {
  309 + std::string msg = "Invalid phase value \""+value+
  310 + "\" encountered in data selection key \""+
  311 + value_key+"\"";
  312 + throw GException::invalid_value(G_READ_DS_PHASE, msg);
  313 + }
  314 +
  315 + } //endfor: looped over phase intervals
  316 +
  317 + } // endif: PHASE type_key found
  318 +
  319 + } // endfor: looped over data selection keys
  320 +
  321 + // Return
  322 + return phases;
  323 +}
  324 +
  325 +
  326 +/***********************************************************************//**
262 * @brief Return Good Time Intervals extension name from data sub-space keywords 327 * @brief Return Good Time Intervals extension name from data sub-space keywords
263 * 328 *
264 * @param[in] hdu FITS HDU 329 * @param[in] hdu FITS HDU
inst/cta/src/GCTASupport.hpp
1 /*************************************************************************** 1 /***************************************************************************
2 * GCTASupport.hpp - CTA support functions * 2 * GCTASupport.hpp - CTA support functions *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2011-2016 by Juergen Knoedlseder * 4 + * copyright (C) 2011-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,6 +29,7 @@ @@ -29,6 +29,7 @@
29 29
30 /* __ Includes ___________________________________________________________ */ 30 /* __ Includes ___________________________________________________________ */
31 #include <string> 31 #include <string>
  32 +#include <vector>
32 33
33 /* __ Namespaces _________________________________________________________ */ 34 /* __ Namespaces _________________________________________________________ */
34 35
@@ -38,6 +39,7 @@ @@ -38,6 +39,7 @@
38 class GFitsHDU; 39 class GFitsHDU;
39 class GCTARoi; 40 class GCTARoi;
40 class GEbounds; 41 class GEbounds;
  42 +class GPhases;
41 43
42 /* __ Prototypes _________________________________________________________ */ 44 /* __ Prototypes _________________________________________________________ */
43 namespace gammalib { 45 namespace gammalib {
@@ -46,6 +48,7 @@ namespace gammalib { @@ -46,6 +48,7 @@ namespace gammalib {
46 const double& roi, const double& cosroi); 48 const double& roi, const double& cosroi);
47 GCTARoi read_ds_roi(const GFitsHDU& hdu); 49 GCTARoi read_ds_roi(const GFitsHDU& hdu);
48 GEbounds read_ds_ebounds(const GFitsHDU& hdu); 50 GEbounds read_ds_ebounds(const GFitsHDU& hdu);
  51 + GPhases read_ds_phase(const GFitsHDU& hdu);
49 std::string read_ds_gti_extname(const GFitsHDU& hdu); 52 std::string read_ds_gti_extname(const GFitsHDU& hdu);
50 } 53 }
51 54
pyext/GGti.i
@@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
35 * 35 *
36 * @brief Good Time Interval class 36 * @brief Good Time Interval class
37 ***************************************************************************/ 37 ***************************************************************************/
38 -class GGti : public GBase { 38 +class GGti : public GContainer {
39 39
40 public: 40 public:
41 // Constructors and destructors 41 // Constructors and destructors
pyext/GPhases.i 0 → 100644
  1 +/***************************************************************************
  2 + * GPhases.i - Phase intervals class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2017 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GPhases.i
  23 + * @brief Phase intervals class interface definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +%{
  27 +/* Put headers and other declarations here that are needed for compilation */
  28 +#include "GPhases.hpp"
  29 +#include "GTools.hpp"
  30 +%}
  31 +
  32 +
  33 +/***********************************************************************//**
  34 + * @class GPhases
  35 + *
  36 + * @brief Phase intervals class
  37 + ***************************************************************************/
  38 +class GPhases : public GContainer {
  39 +
  40 +public:
  41 + // Constructors and destructors
  42 + GPhases(void);
  43 + GPhases(const GPhases& phases);
  44 + GPhases(const double& pmin, const double& pmax);
  45 + virtual ~GPhases(void);
  46 +
  47 + // Methods
  48 + void clear(void);
  49 + GPhases* clone(void) const;
  50 + std::string classname(void) const;
  51 + int size(void) const;
  52 + bool is_empty(void) const;
  53 + void append(const double& pmin, const double& pmax);
  54 + void remove(const int& index);
  55 + void reserve(const int& num);
  56 + void extend(const GPhases& phases);
  57 + double pmin(const int& index) const;
  58 + double pmax(const int& index) const;
  59 +};
  60 +
  61 +
  62 +/***********************************************************************//**
  63 + * @brief GPhases class extension
  64 + ***************************************************************************/
  65 +%extend GPhases {
  66 + int __len__() {
  67 + return (self->size());
  68 + }
  69 + GPhases copy() {
  70 + return (*self);
  71 + }
  72 +};
pyext/gammalib/obs.i
1 /*************************************************************************** 1 /***************************************************************************
2 * obs.i - Observation module * 2 * obs.i - Observation module *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2011-2016 by Juergen Knoedlseder * 4 + * copyright (C) 2011-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 *
@@ -171,6 +171,7 @@ @@ -171,6 +171,7 @@
171 %include "GEventBin.i" 171 %include "GEventBin.i"
172 %include "GInstDir.i" 172 %include "GInstDir.i"
173 %include "GRoi.i" 173 %include "GRoi.i"
  174 +%include "GPhases.i"
174 %include "GResponse.i" 175 %include "GResponse.i"
175 %include "GPhoton.i" 176 %include "GPhoton.i"
176 %include "GPhotons.i" 177 %include "GPhotons.i"
src/obs/GGti.cpp
@@ -100,7 +100,7 @@ GGti::GGti(const GFilename&amp; filename) @@ -100,7 +100,7 @@ GGti::GGti(const GFilename&amp; filename)
100 * 100 *
101 * @param[in] gti Good Time Intervals. 101 * @param[in] gti Good Time Intervals.
102 * 102 *
103 - * Constructs Good Time Intervals by coping other Good Time Intervals. 103 + * Constructs Good Time Intervals by copying other Good Time Intervals.
104 ***************************************************************************/ 104 ***************************************************************************/
105 GGti::GGti(const GGti& gti) 105 GGti::GGti(const GGti& gti)
106 { 106 {
src/obs/GPhases.cpp 0 → 100644
  1 +/***************************************************************************
  2 + * GPhases.cpp - Phase intervals class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2017 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GPhases.cpp
  23 + * @brief Phase intervals class implementation
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +/* __ Includes ___________________________________________________________ */
  28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
  31 +#include "GException.hpp"
  32 +#include "GTools.hpp"
  33 +#include "GPhases.hpp"
  34 +
  35 +/* __ Method name definitions ____________________________________________ */
  36 +#define G_REMOVE "GPhases::remove(int&)"
  37 +#define G_PMIN "GPhases::pmin(int&)"
  38 +#define G_PMAX "GPhases::pmax(int&)"
  39 +#define G_INSERT_INTERVAL "GPhases::insert_interval(int&, double&, double&)"
  40 +
  41 +/* __ Macros _____________________________________________________________ */
  42 +
  43 +/* __ Coding definitions _________________________________________________ */
  44 +
  45 +/* __ Debug definitions __________________________________________________ */
  46 +
  47 +
  48 +/*==========================================================================
  49 + = =
  50 + = Constructors/destructors =
  51 + = =
  52 + ==========================================================================*/
  53 +
  54 +/***********************************************************************//**
  55 + * @brief Void constructor
  56 + *
  57 + * Constructs empty phase intervals.
  58 + ***************************************************************************/
  59 +GPhases::GPhases(void)
  60 +{
  61 + // Initialise class members
  62 + init_members();
  63 +
  64 + // Return
  65 + return;
  66 +}
  67 +
  68 +
  69 +/***********************************************************************//**
  70 + * @brief Copy constructor
  71 + *
  72 + * @param[in] phases Phase intervals.
  73 + *
  74 + * Constructs phase intervals by copying other phase intervals.
  75 + ***************************************************************************/
  76 +GPhases::GPhases(const GPhases& phases)
  77 +{
  78 + // Initialise class members
  79 + init_members();
  80 +
  81 + // Copy members
  82 + copy_members(phases);
  83 +
  84 + // Return
  85 + return;
  86 +}
  87 +
  88 +
  89 +/***********************************************************************//**
  90 + * @brief Single phase interval constructor
  91 + *
  92 + * @param[in] pmin Lower boundary of phase interval.
  93 + * @param[in] pmax Upper boundary of phase interval.
  94 + *
  95 + * Constructs Good Time Intervals from a single phase interval, given by
  96 + * [p@ pmin, @p pmax].
  97 + ***************************************************************************/
  98 +GPhases::GPhases(const double& pmin, const double& pmax)
  99 +{
  100 + // Initialise members
  101 + init_members();
  102 +
  103 + // Append phase interval
  104 + append(pmin, pmax);
  105 +
  106 + // Return
  107 + return;
  108 +}
  109 +
  110 +
  111 +/***********************************************************************//**
  112 + * @brief Destructor
  113 + ***************************************************************************/
  114 +GPhases::~GPhases(void)
  115 +{
  116 + // Free members
  117 + free_members();
  118 +
  119 + // Return
  120 + return;
  121 +}
  122 +
  123 +
  124 +/*==========================================================================
  125 + = =
  126 + = Operators =
  127 + = =
  128 + ==========================================================================*/
  129 +
  130 +/***********************************************************************//**
  131 + * @brief Assignment operator
  132 + *
  133 + * @param[in] phases Phase intervals.
  134 + * @return Phase intervals.
  135 + ***************************************************************************/
  136 +GPhases& GPhases::operator=(const GPhases& phases)
  137 +{
  138 + // Execute only if object is not identical
  139 + if (this != &phases) {
  140 +
  141 + // Free members
  142 + free_members();
  143 +
  144 + // Initialise private members
  145 + init_members();
  146 +
  147 + // Copy members
  148 + copy_members(phases);
  149 +
  150 + } // endif: object was not identical
  151 +
  152 + // Return this object
  153 + return *this;
  154 +}
  155 +
  156 +
  157 +/*==========================================================================
  158 + = =
  159 + = Public methods =
  160 + = =
  161 + ==========================================================================*/
  162 +
  163 +/***********************************************************************//**
  164 + * @brief Clear phase intervals
  165 + ***************************************************************************/
  166 +void GPhases::clear(void)
  167 +{
  168 + // Free members
  169 + free_members();
  170 +
  171 + // Initialise private members
  172 + init_members();
  173 +
  174 + // Return
  175 + return;
  176 +}
  177 +
  178 +
  179 +/***********************************************************************//**
  180 + * @brief Clone phase intervals
  181 + *
  182 + * @return Pointer to deep copy of phase intervals.
  183 + ***************************************************************************/
  184 +GPhases* GPhases::clone(void) const
  185 +{
  186 + return new GPhases(*this);
  187 +}
  188 +
  189 +
  190 +/***********************************************************************//**
  191 + * @brief Append phase interval
  192 + *
  193 + * @param[in] pmin Lower boundary of phase interval.
  194 + * @param[in] pmax Upper boundary of phase interval.
  195 + *
  196 + * Appends a phase interval at the end of the container.
  197 + ***************************************************************************/
  198 +void GPhases::append(const double& pmin, const double& pmax)
  199 +{
  200 + // Insert phase interval at the end of the list
  201 + insert_interval(size(), pmin, pmax);
  202 +
  203 + // Return
  204 + return;
  205 +}
  206 +
  207 +
  208 +/***********************************************************************//**
  209 + * @brief Remove phase interval
  210 + *
  211 + * @param[in] index Phase interval index (0,...,size()-1).
  212 + *
  213 + * Removes phase interval at @p index from the container. All intervals
  214 + * after the specified @p index are moved forward by one position.
  215 + ***************************************************************************/
  216 +void GPhases::remove(const int& index)
  217 +{
  218 + #if defined(G_RANGE_CHECK)
  219 + // If index is outside boundary then throw an error
  220 + if (index < 0 || index >= size()) {
  221 + throw GException::out_of_range(G_REMOVE, "Phase interval", index,
  222 + size());
  223 + }
  224 + #endif
  225 +
  226 + // Remove lower and upper boundaries
  227 + m_pmin.erase(m_pmin.begin() + index);
  228 + m_pmax.erase(m_pmax.begin() + index);
  229 +
  230 + // Return
  231 + return;
  232 +}
  233 +
  234 +
  235 +/***********************************************************************//**
  236 + * @brief Reserve space for phase intervals
  237 + *
  238 + * @param[in] num Number of elements.
  239 + ***************************************************************************/
  240 +void GPhases::reserve(const int& num)
  241 +{
  242 + // Reserves memory
  243 + m_pmin.reserve(num);
  244 + m_pmax.reserve(num);
  245 +
  246 + // Return
  247 + return;
  248 +}
  249 +
  250 +
  251 +/***********************************************************************//**
  252 + * @brief Append phase intervals
  253 + *
  254 + * @param[in] phases Phase intervals.
  255 + *
  256 + * Append phase intervals to the container.
  257 + ***************************************************************************/
  258 +void GPhases::extend(const GPhases& phases)
  259 +{
  260 + // Continue only if phase intervals are not empty
  261 + if (!phases.is_empty()) {
  262 +
  263 + // Get size. Note that we extract the size first to avoid an
  264 + // endless loop that arises when a container is appended to
  265 + // itself.
  266 + int num = phases.size();
  267 +
  268 + // Resize the boundary vectors
  269 + reserve(size() + num);
  270 +
  271 + // Loop over all elements and append them to container
  272 + for (int i = 0; i < num; ++i) {
  273 + m_pmin.push_back(phases.pmin(i));
  274 + m_pmax.push_back(phases.pmax(i));
  275 + }
  276 +
  277 + } // endif: Phase intervals were not empty
  278 +
  279 + // Return
  280 + return;
  281 +}
  282 +
  283 +
  284 +/***********************************************************************//**
  285 + * @brief Returns lower boundary for a given phase interval
  286 + *
  287 + * @param[in] index Phase interval index (0,...,size()-1).
  288 + * @return Lower boundary of phase interval.
  289 + *
  290 + * @exception GException::out_of_range
  291 + * Specified index is out of range.
  292 + ***************************************************************************/
  293 +double GPhases::pmin(const int& index) const
  294 +{
  295 + #if defined(G_RANGE_CHECK)
  296 + // If index is outside boundary then throw an error
  297 + if (index < 0 || index >= size()) {
  298 + throw GException::out_of_range(G_PMIN, "Phase interval", index,
  299 + size());
  300 + }
  301 + #endif
  302 +
  303 + // Return
  304 + return (m_pmin[index]);
  305 +}
  306 +
  307 +
  308 +/***********************************************************************//**
  309 + * @brief Returns upper boundary for a given phase interval
  310 + *
  311 + * @param[in] index Phase interval index (0,...,size()-1).
  312 + * @return Upper boundary of phase interval.
  313 + *
  314 + * @exception GException::out_of_range
  315 + * Specified index is out of range.
  316 + ***************************************************************************/
  317 +double GPhases::pmax(const int& index) const
  318 +{
  319 + #if defined(G_RANGE_CHECK)
  320 + // If index is outside boundary then throw an error
  321 + if (index < 0 || index >= size()) {
  322 + throw GException::out_of_range(G_PMAX, "Phase interval", index,
  323 + size());
  324 + }
  325 + #endif
  326 +
  327 + // Return
  328 + return (m_pmax[index]);
  329 +}
  330 +
  331 +
  332 +/***********************************************************************//**
  333 + * @brief Print phase intervals
  334 + *
  335 + * @param[in] chatter Chattiness.
  336 + * @return String containing phase interval information.
  337 + ***************************************************************************/
  338 +std::string GPhases::print(const GChatter& chatter) const
  339 +{
  340 + // Initialise result string
  341 + std::string result;
  342 +
  343 + // Continue only if chatter is not silent
  344 + if (chatter != SILENT) {
  345 +
  346 + // Append header
  347 + result.append("=== GPhases ===");
  348 +
  349 + // Append phase interval information
  350 + result.append("\n"+gammalib::parformat("Number of intervals"));
  351 + result.append(gammalib::str(size()));
  352 +
  353 + } // endif: chatter was not silent
  354 +
  355 + // Return result
  356 + return result;
  357 +}
  358 +
  359 +
  360 +/*==========================================================================
  361 + = =
  362 + = Private methods =
  363 + = =
  364 + ==========================================================================*/
  365 +
  366 +/***********************************************************************//**
  367 + * @brief Initialise class members
  368 + ***************************************************************************/
  369 +void GPhases::init_members(void)
  370 +{
  371 + // Initialise members
  372 + m_pmin.clear();
  373 + m_pmax.clear();
  374 +
  375 + // Return
  376 + return;
  377 +}
  378 +
  379 +
  380 +/***********************************************************************//**
  381 + * @brief Copy class members
  382 + *
  383 + * @param[in] phases Phase intervals.
  384 + ***************************************************************************/
  385 +void GPhases::copy_members(const GPhases& phases)
  386 +{
  387 + // Copy attributes
  388 + m_pmin = phases.m_pmin;
  389 + m_pmax = phases.m_pmax;
  390 +
  391 + // Return
  392 + return;
  393 +}
  394 +
  395 +
  396 +/***********************************************************************//**
  397 + * @brief Delete class members
  398 + ***************************************************************************/
  399 +void GPhases::free_members(void)
  400 +{
  401 + // Return
  402 + return;
  403 +}
  404 +
  405 +
  406 +/***********************************************************************//**
  407 + * @brief Insert phase interval
  408 + *
  409 + * @param[in] index Index after which interval is inserted.
  410 + * @param[in] pmin Lower boundary of interval.
  411 + * @param[in] pmax Upper boundary of interval.
  412 + *
  413 + * @exception GException::invalid_argument
  414 + * Invalid phase interval boundaries specified
  415 + *
  416 + * Inserts a phase interval before the interval with the specified @p index.
  417 + * If no interval with the specified index exists then append the interval
  418 + * at the end of the existing phase intervals.
  419 + ***************************************************************************/
  420 +void GPhases::insert_interval(const int& index,
  421 + const double& pmin,
  422 + const double& pmax)
  423 +{
  424 + // Throw an exception if phase minimum is outside the range [0,1]
  425 + if (pmin < 0.0 || pmin > 1.0) {
  426 + std::string msg = "Phase minimum "+gammalib::str(pmin)+
  427 + " outside the valid range [0,1]. Please "
  428 + "specify phase interval boundaries comprised "
  429 + "within 0 and 1.";
  430 + throw GException::invalid_argument(G_INSERT_INTERVAL, msg);
  431 + }
  432 +
  433 + // Throw an exception if phase minimum is outside the range [0,1]
  434 + if (pmax < 0.0 || pmax > 1.0) {
  435 + std::string msg = "Phase maximum "+gammalib::str(pmax)+
  436 + " outside the valid range [0,1]. Please "
  437 + "specify phase interval boundaries comprised "
  438 + "within 0 and 1.";
  439 + throw GException::invalid_argument(G_INSERT_INTERVAL, msg);
  440 + }
  441 +
  442 + // If phase minimum is smaller than phase maximum then append or insert
  443 + // a single interval ...
  444 + if (pmin < pmax) {
  445 + if (index >= size()) {
  446 + m_pmin.push_back(pmin);
  447 + m_pmax.push_back(pmax);
  448 + }
  449 + else {
  450 + m_pmin.insert(m_pmin.begin()+index, pmin);
  451 + m_pmax.insert(m_pmax.begin()+index, pmax);
  452 + }
  453 + }
  454 +
  455 + // ... otherwise if the phase minimum is larger than the maximum then
  456 + // consider this a wrap around interval and append or insert one interval
  457 + // from phase minimum to 1 and another interval from 0 to phase maximum
  458 + else if (pmin > pmax) {
  459 + if (pmin < 1.0) {
  460 + if (index >= size()) {
  461 + m_pmin.push_back(pmin);
  462 + m_pmax.push_back(1.0);
  463 + }
  464 + else {
  465 + m_pmin.insert(m_pmin.begin()+index, pmin);
  466 + m_pmax.insert(m_pmax.begin()+index, 1.0);
  467 + }
  468 + }
  469 + if (pmax > 0.0) {
  470 + if (index >= size()) {
  471 + m_pmin.push_back(0.0);
  472 + m_pmax.push_back(pmax);
  473 + }
  474 + else {
  475 + m_pmin.insert(m_pmin.begin()+index, 0.0);
  476 + m_pmax.insert(m_pmax.begin()+index, pmax);
  477 + }
  478 + }
  479 + }
  480 +
  481 + // Return
  482 + return;
  483 +}
src/obs/Makefile.am
1 ############################################################################# 1 #############################################################################
2 # Makefile.am for obs module # 2 # Makefile.am for obs module #
3 # ------------------------------------------------------------------------- # 3 # ------------------------------------------------------------------------- #
4 -# Copyright (C) 2016 Juergen Knoedlseder # 4 +# Copyright (C) 2016-2017 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 #
@@ -44,6 +44,7 @@ sources = GEnergies.cpp \ @@ -44,6 +44,7 @@ sources = GEnergies.cpp \
44 GGti.cpp \ 44 GGti.cpp \
45 GRoi.cpp \ 45 GRoi.cpp \
46 GEbounds.cpp \ 46 GEbounds.cpp \
  47 + GPhases.cpp \
47 GResponse.cpp \ 48 GResponse.cpp \
48 GInstDir.cpp \ 49 GInstDir.cpp \
49 GPhotons.cpp \ 50 GPhotons.cpp \
test/test_GObservation.cpp
@@ -69,6 +69,8 @@ void TestGObservation::set(void) @@ -69,6 +69,8 @@ void TestGObservation::set(void)
69 "Test GEnergies class"); 69 "Test GEnergies class");
70 append(static_cast<pfunction>(&TestGObservation::test_ebounds), 70 append(static_cast<pfunction>(&TestGObservation::test_ebounds),
71 "Test GEbounds class"); 71 "Test GEbounds class");
  72 + append(static_cast<pfunction>(&TestGObservation::test_phases),
  73 + "Test GPhases class");
72 append(static_cast<pfunction>(&TestGObservation::test_photons), 74 append(static_cast<pfunction>(&TestGObservation::test_photons),
73 "Test GPhotons class"); 75 "Test GPhotons class");
74 append(static_cast<pfunction>(&TestGObservation::test_observations_optimizer), 76 append(static_cast<pfunction>(&TestGObservation::test_observations_optimizer),
@@ -1343,6 +1345,74 @@ void TestGObservation::test_photons(void) @@ -1343,6 +1345,74 @@ void TestGObservation::test_photons(void)
1343 1345
1344 1346
1345 /***********************************************************************//** 1347 /***********************************************************************//**
  1348 + * @brief Test GPhases
  1349 + ***************************************************************************/
  1350 +void TestGObservation::test_phases(void)
  1351 +{
  1352 + // Test void constructor
  1353 + test_try("Void constructor");
  1354 + try {
  1355 + GPhases phases;
  1356 + test_try_success();
  1357 + }
  1358 + catch (std::exception &e) {
  1359 + test_try_failure(e);
  1360 + }
  1361 +
  1362 + // Manipulate GPhases starting from an empty object
  1363 + GPhases phases;
  1364 + test_value(phases.size(), 0);
  1365 + test_assert(phases.is_empty(), "Test for empty GPhases object");
  1366 +
  1367 + // Add one phase interval
  1368 + phases.append(0.3, 0.5);
  1369 + test_value(phases.size(), 1);
  1370 + test_value(phases.pmin(0), 0.3);
  1371 + test_value(phases.pmax(0), 0.5);
  1372 + test_assert(!phases.is_empty(), "Test for non-empty GPhases object");
  1373 +
  1374 + // Remove phase interval
  1375 + phases.remove(0);
  1376 + test_value(phases.size(), 0);
  1377 + test_assert(phases.is_empty(), "Test for empty GPhases object");
  1378 +
  1379 + // Append two phase intervals
  1380 + phases.append(0.3, 0.5);
  1381 + phases.append(0.4, 0.7);
  1382 + test_value(phases.pmin(0), 0.3);
  1383 + test_value(phases.pmax(0), 0.5);
  1384 + test_value(phases.pmin(1), 0.4);
  1385 + test_value(phases.pmax(1), 0.7);
  1386 + test_value(phases.size(), 2);
  1387 + test_assert(!phases.is_empty(), "Test for non-empty GPhases object");
  1388 +
  1389 + // Copy phase intervals
  1390 + GPhases phases2(phases);
  1391 + test_value(phases2.pmin(0), 0.3);
  1392 + test_value(phases2.pmax(0), 0.5);
  1393 + test_value(phases2.pmin(1), 0.4);
  1394 + test_value(phases2.pmax(1), 0.7);
  1395 + test_value(phases2.size(), 2);
  1396 + test_assert(!phases2.is_empty(), "Test for non-empty GPhases object");
  1397 +
  1398 + // Clear object
  1399 + phases.clear();
  1400 + test_value(phases.size(), 0);
  1401 + test_assert(phases.is_empty(), "Test for empty GPhases object");
  1402 +
  1403 + // Extend photons
  1404 + phases.append(0.3, 0.5);
  1405 + phases.append(0.4, 0.7);
  1406 + phases.extend(phases);
  1407 + test_value(phases.size(), 4);
  1408 + test_assert(!phases.is_empty(), "Test for non-empty GPhases object");
  1409 +
  1410 + // Return
  1411 + return;
  1412 +}
  1413 +
  1414 +
  1415 +/***********************************************************************//**
1346 * @brief Test GObservations::likelihood 1416 * @brief Test GObservations::likelihood
1347 ***************************************************************************/ 1417 ***************************************************************************/
1348 void TestGObservation::test_observations_optimizer(void) 1418 void TestGObservation::test_observations_optimizer(void)
test/test_GObservation.hpp
@@ -49,6 +49,7 @@ public: @@ -49,6 +49,7 @@ public:
49 virtual std::string classname(void) const { return "TestGObservation"; } 49 virtual std::string classname(void) const { return "TestGObservation"; }
50 void test_ebounds(void); 50 void test_ebounds(void);
51 void test_gti(void); 51 void test_gti(void);
  52 + void test_phases(void);
52 void test_photons(void); 53 void test_photons(void);
53 void test_time_reference(void); 54 void test_time_reference(void);
54 void test_time(void); 55 void test_time(void);