GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GPhases.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GPhases.cpp - Phase intervals class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2017-2022 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  ***************************************************************************/
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  ***************************************************************************/
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  ***************************************************************************/
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  ***************************************************************************/
185 {
186  return new GPhases(*this);
187 }
188 
189 
190 /***********************************************************************//**
191  * @brief Check whether phase is contained in phases
192  *
193  * @param[in] phase Phase.
194  * @returns Phase is contained in phases.
195  *
196  * Checks whether a phase is contained in one of the phase intervals. The
197  * lower phase bound is included while the upper phase bound is excluded
198  * by the check.
199  ***************************************************************************/
200 bool GPhases::contains(const double& phase) const
201 {
202  // Initialise containment flag
203  bool contained = false;
204 
205  // Check if phase is contained in one of the phase intervals
206  for (int i = 0; i < size(); ++i) {
207  if (phase >= m_pmin[i] && phase < m_pmax[i]) {
208  contained = true;
209  break;
210  }
211  }
212 
213  // Return containment flag
214  return contained;
215 }
216 
217 
218 /***********************************************************************//**
219  * @brief Append phase interval
220  *
221  * @param[in] pmin Lower boundary of phase interval.
222  * @param[in] pmax Upper boundary of phase interval.
223  *
224  * Appends a phase interval at the end of the container.
225  ***************************************************************************/
226 void GPhases::append(const double& pmin, const double& pmax)
227 {
228  // Insert phase interval at the end of the list
229  insert_interval(size(), pmin, pmax);
230 
231  // Return
232  return;
233 }
234 
235 
236 /***********************************************************************//**
237  * @brief Remove phase interval
238  *
239  * @param[in] index Phase interval index (0,...,size()-1).
240  *
241  * Removes phase interval at @p index from the container. All intervals
242  * after the specified @p index are moved forward by one position.
243  ***************************************************************************/
244 void GPhases::remove(const int& index)
245 {
246  #if defined(G_RANGE_CHECK)
247  // If index is outside boundary then throw an error
248  if (index < 0 || index >= size()) {
249  throw GException::out_of_range(G_REMOVE, "Phase interval", index,
250  size());
251  }
252  #endif
253 
254  // Remove lower and upper boundaries
255  m_pmin.erase(m_pmin.begin() + index);
256  m_pmax.erase(m_pmax.begin() + index);
257 
258  // Return
259  return;
260 }
261 
262 
263 /***********************************************************************//**
264  * @brief Reserve space for phase intervals
265  *
266  * @param[in] num Number of elements.
267  ***************************************************************************/
268 void GPhases::reserve(const int& num)
269 {
270  // Reserves memory
271  m_pmin.reserve(num);
272  m_pmax.reserve(num);
273 
274  // Return
275  return;
276 }
277 
278 
279 /***********************************************************************//**
280  * @brief Append phase intervals
281  *
282  * @param[in] phases Phase intervals.
283  *
284  * Append phase intervals to the container.
285  ***************************************************************************/
286 void GPhases::extend(const GPhases& phases)
287 {
288  // Continue only if phase intervals are not empty
289  if (!phases.is_empty()) {
290 
291  // Get size. Note that we extract the size first to avoid an
292  // endless loop that arises when a container is appended to
293  // itself.
294  int num = phases.size();
295 
296  // Resize the boundary vectors
297  reserve(size() + num);
298 
299  // Loop over all elements and append them to container
300  for (int i = 0; i < num; ++i) {
301  m_pmin.push_back(phases.pmin(i));
302  m_pmax.push_back(phases.pmax(i));
303  }
304 
305  } // endif: Phase intervals were not empty
306 
307  // Return
308  return;
309 }
310 
311 
312 /***********************************************************************//**
313  * @brief Returns lower boundary for a given phase interval
314  *
315  * @param[in] index Phase interval index (0,...,size()-1).
316  * @return Lower boundary of phase interval.
317  *
318  * @exception GException::out_of_range
319  * Specified index is out of range.
320  ***************************************************************************/
321 double GPhases::pmin(const int& index) const
322 {
323  #if defined(G_RANGE_CHECK)
324  // If index is outside boundary then throw an error
325  if (index < 0 || index >= size()) {
326  throw GException::out_of_range(G_PMIN, "Phase interval", index,
327  size());
328  }
329  #endif
330 
331  // Return
332  return (m_pmin[index]);
333 }
334 
335 
336 /***********************************************************************//**
337  * @brief Returns upper boundary for a given phase interval
338  *
339  * @param[in] index Phase interval index (0,...,size()-1).
340  * @return Upper boundary of phase interval.
341  *
342  * @exception GException::out_of_range
343  * Specified index is out of range.
344  ***************************************************************************/
345 double GPhases::pmax(const int& index) const
346 {
347  #if defined(G_RANGE_CHECK)
348  // If index is outside boundary then throw an error
349  if (index < 0 || index >= size()) {
350  throw GException::out_of_range(G_PMAX, "Phase interval", index,
351  size());
352  }
353  #endif
354 
355  // Return
356  return (m_pmax[index]);
357 }
358 
359 
360 /***********************************************************************//**
361  * @brief Returns total length of phase intervals
362  *
363  * @return Total length of phase intervals.
364  ***************************************************************************/
365 double GPhases::length(void) const
366 {
367  // Initialise length
368  double length = 0.0;
369 
370  // Loop over all intervals and add their length
371  for (int i = 0; i < size(); ++i) {
372  length += (m_pmax[i] - m_pmin[i]);
373  }
374 
375  // Return
376  return length;
377 }
378 
379 
380 /***********************************************************************//**
381  * @brief Print phase intervals
382  *
383  * @param[in] chatter Chattiness.
384  * @return String containing phase interval information.
385  ***************************************************************************/
386 std::string GPhases::print(const GChatter& chatter) const
387 {
388  // Initialise result string
389  std::string result;
390 
391  // Continue only if chatter is not silent
392  if (chatter != SILENT) {
393 
394  // Append header
395  result.append("=== GPhases ===");
396 
397  // Append phase interval information
398  result.append("\n"+gammalib::parformat("Number of phase intervals"));
399  result.append(gammalib::str(size()));
400 
401  // Append phases
402  for (int i = 0; i < size(); ++i) {
403  result.append("\n"+gammalib::parformat("Phase interval "+
404  gammalib::str(i+1)));
405  result.append(gammalib::str(m_pmin[i]));
406  result.append(" - ");
407  result.append(gammalib::str(m_pmax[i]));
408  }
409 
410  } // endif: chatter was not silent
411 
412  // Return result
413  return result;
414 }
415 
416 
417 /*==========================================================================
418  = =
419  = Private methods =
420  = =
421  ==========================================================================*/
422 
423 /***********************************************************************//**
424  * @brief Initialise class members
425  ***************************************************************************/
427 {
428  // Initialise members
429  m_pmin.clear();
430  m_pmax.clear();
431 
432  // Return
433  return;
434 }
435 
436 
437 /***********************************************************************//**
438  * @brief Copy class members
439  *
440  * @param[in] phases Phase intervals.
441  ***************************************************************************/
442 void GPhases::copy_members(const GPhases& phases)
443 {
444  // Copy attributes
445  m_pmin = phases.m_pmin;
446  m_pmax = phases.m_pmax;
447 
448  // Return
449  return;
450 }
451 
452 
453 /***********************************************************************//**
454  * @brief Delete class members
455  ***************************************************************************/
457 {
458  // Return
459  return;
460 }
461 
462 
463 /***********************************************************************//**
464  * @brief Insert phase interval
465  *
466  * @param[in] index Index after which interval is inserted.
467  * @param[in] pmin Lower boundary of interval.
468  * @param[in] pmax Upper boundary of interval.
469  *
470  * @exception GException::invalid_argument
471  * Invalid phase interval boundaries specified
472  *
473  * Inserts a phase interval before the interval with the specified @p index.
474  * If no interval with the specified index exists then append the interval
475  * at the end of the existing phase intervals.
476  ***************************************************************************/
477 void GPhases::insert_interval(const int& index,
478  const double& pmin,
479  const double& pmax)
480 {
481  // Throw an exception if phase minimum is outside the range [0,1]
482  if (pmin < 0.0 || pmin > 1.0) {
483  std::string msg = "Phase minimum "+gammalib::str(pmin)+
484  " outside the valid range [0,1]. Please "
485  "specify phase interval boundaries comprised "
486  "within 0 and 1.";
488  }
489 
490  // Throw an exception if phase minimum is outside the range [0,1]
491  if (pmax < 0.0 || pmax > 1.0) {
492  std::string msg = "Phase maximum "+gammalib::str(pmax)+
493  " outside the valid range [0,1]. Please "
494  "specify phase interval boundaries comprised "
495  "within 0 and 1.";
497  }
498 
499  // If phase minimum is smaller than phase maximum then append or insert
500  // a single interval ...
501  if (pmin < pmax) {
502  if (index >= size()) {
503  m_pmin.push_back(pmin);
504  m_pmax.push_back(pmax);
505  }
506  else {
507  m_pmin.insert(m_pmin.begin()+index, pmin);
508  m_pmax.insert(m_pmax.begin()+index, pmax);
509  }
510  }
511 
512  // ... otherwise if the phase minimum is larger than the maximum then
513  // consider this a wrap around interval and append or insert one interval
514  // from phase minimum to 1 and another interval from 0 to phase maximum
515  else if (pmin > pmax) {
516  if (pmin < 1.0) {
517  if (index >= size()) {
518  m_pmin.push_back(pmin);
519  m_pmax.push_back(1.0);
520  }
521  else {
522  m_pmin.insert(m_pmin.begin()+index, pmin);
523  m_pmax.insert(m_pmax.begin()+index, 1.0);
524  }
525  }
526  if (pmax > 0.0) {
527  if (index >= size()) {
528  m_pmin.push_back(0.0);
529  m_pmax.push_back(pmax);
530  }
531  else {
532  m_pmin.insert(m_pmin.begin()+index, 0.0);
533  m_pmax.insert(m_pmax.begin()+index, pmax);
534  }
535  }
536  }
537 
538  // Return
539  return;
540 }
void clear(void)
Clear phase intervals.
Definition: GPhases.cpp:166
void remove(const int &index)
Remove phase interval.
Definition: GPhases.cpp:244
#define G_REMOVE
Definition: GPhases.cpp:36
#define G_INSERT_INTERVAL
Definition: GPhases.cpp:39
double length(void) const
Returns total length of phase intervals.
Definition: GPhases.cpp:365
#define G_PMIN
Definition: GPhases.cpp:37
void append(const double &pmin, const double &pmax)
Append phase interval.
Definition: GPhases.cpp:226
double pmax(const int &index) const
Returns upper boundary for a given phase interval.
Definition: GPhases.cpp:345
void reserve(const int &num)
Reserve space for phase intervals.
Definition: GPhases.cpp:268
int size(void) const
Return number of phase intervals.
Definition: GPhases.hpp:102
#define G_PMAX
Definition: GPhases.cpp:38
Gammalib tools definition.
GPhases * clone(void) const
Clone phase intervals.
Definition: GPhases.cpp:184
virtual ~GPhases(void)
Destructor.
Definition: GPhases.cpp:114
bool is_empty(void) const
Signal if there are no phase intervals.
Definition: GPhases.hpp:114
void init_members(void)
Initialise class members.
Definition: GPhases.cpp:426
Phase intervals class interface definition.
void insert_interval(const int &index, const double &pmin, const double &pmax)
Insert phase interval.
Definition: GPhases.cpp:477
bool contains(const double &phase) const
Check whether phase is contained in phases.
Definition: GPhases.cpp:200
GChatter
Definition: GTypemaps.hpp:33
void copy_members(const GPhases &phases)
Copy class members.
Definition: GPhases.cpp:442
void extend(const GPhases &phases)
Append phase intervals.
Definition: GPhases.cpp:286
std::vector< double > m_pmax
Definition: GPhases.hpp:80
Exception handler interface definition.
void free_members(void)
Delete class members.
Definition: GPhases.cpp:456
GPhases & operator=(const GPhases &phases)
Assignment operator.
Definition: GPhases.cpp:136
Phase Intervals class.
Definition: GPhases.hpp:42
std::vector< double > m_pmin
Definition: GPhases.hpp:79
double pmin(const int &index) const
Returns lower boundary for a given phase interval.
Definition: GPhases.cpp:321
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
GPhases(void)
Void constructor.
Definition: GPhases.cpp:59
std::string print(const GChatter &chatter=NORMAL) const
Print phase intervals.
Definition: GPhases.cpp:386
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489