Commit 37b8b1c944e2f140033e6985ec99a1e37d3c149f

Authored by Jürgen Knödlseder
1 parent 2a198690

Replace log flag by string in GEbounds class (#2881)

ChangeLog
... ... @@ -27,6 +27,7 @@
27 27 Fix GTime.utc() precision bug (#2917)
28 28 Add GTime.datetime() method and add optional precision to GTime.utc() (#2909)
29 29 Remove obsolete methods from GCTAResponseCache class (#2893)
  30 + Replace log flag by string in GEbounds class (#2881)
30 31 Allow RoI centres different from pointing direction in unbinned analysis
31 32 (#2695)
32 33 Add GSkyDir::moon() method (#1855)
... ...
... ... @@ -46,7 +46,8 @@ The following methods have been added:
46 46 - GSkyMap::extract() - Extract section of sky map
47 47 - GSkyMap::region_circle() - Get bounding region circle of sky map
48 48 - GSkyRegionCircle::operator==() - Equality operator
49   -- GSkyRegionCircle::operator!=() - Non-equality operator
  49 +- GSkyRegionCircle::operator!=() - Non-equality operator
  50 +- GEbounds::set() - Set energy boundaries for different methods
50 51 - GModelPar::has_factor_min() - Test if parameter has factor minimum
51 52 - GModelPar::has_factor_max() - Test if parameter has factor maximum
52 53 - GModelPar::remove_factor_min - Remove factor minimum
... ... @@ -64,6 +65,8 @@ The following methods have been added:
64 65 - GCOMDri::cone_content() - Get DRI content within event cone
65 66  
66 67 The following methods have been removed:
  68 +- GEbounds::set_lin() - method is now private
  69 +- GEbounds::set_log() - method is now private
67 70 - GModelSpatialDiffuseCube::maps()
68 71 - GModelSpatialDiffuseCube::pixels()
69 72  
... ... @@ -78,6 +81,7 @@ The arguments for the following methods have been changed:
78 81 - GTime::utc(int&) - Add optional precision value
79 82 - GSkyDir::posang(GSkyDir&, std::string&) - Add optional coordinate system string
80 83 - GSkyDir::posang_dir(GSkyDir&, std::string&) - Add optional coordinate system string
  84 +- GEbounds::GEbounds(int&, GEnergy&, GEnergy&, std::string&, double&) - Replace bool by string and double
81 85  
82 86 The return value of the following methods has been changed:
83 87 - none
... ... @@ -178,6 +182,14 @@ Add GTime.datetime() method to the Python interface to convert times from and
178 182 to datetime.datetime objects. Add an optional precision argument to the GTime.utc()
179 183 to set the number of digits after the comma for the seconds (#2909).
180 184  
  185 +The interface of the GEbounds constructor that sets a given number of energy
  186 +boundaries was changed. The bool argument that toggled between linear and
  187 +logarithmic spacing was replaced by a string that can take the values "LIN",
  188 +"LOG" or "POW". For the "POW" method an additional optional argument was added
  189 +to specify the power-law index. The GEbounds::set() method was added with the
  190 +same method arguments, and the former set_lin() and set_log() methods were
  191 +made private (#2881).
  192 +
181 193 Add GTime.julian_epoch() methods that return the Julian epoch for a given time
182 194 (#1854).
183 195  
... ...
doc/source/admin/release_history/1.7.rst
... ... @@ -55,6 +55,8 @@ Improvements
55 55 * Add ``GGti::overlap()`` method.
56 56 * [`2909 <https://cta-redmine.irap.omp.eu/issues/2909>`_] -
57 57 Add ``GTime.datetime()`` method and add optional precision to ``GTime.utc()`` method.
  58 +* [`2881 <https://cta-redmine.irap.omp.eu/issues/2881>`_] -
  59 + Replace ``log`` flag by ``string`` in ``GEbounds`` class.
58 60 * [`2695 <https://cta-redmine.irap.omp.eu/issues/2695>`_] -
59 61 Allow RoI centres different from pointing direction in unbinned analysis.
60 62 * [`1855 <https://cta-redmine.irap.omp.eu/issues/1855>`_] -
... ...
include/GEbounds.hpp
1 1 /***************************************************************************
2 2 * GEbounds.hpp - Energy boundaries class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2020 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -71,8 +71,11 @@ public:
71 71 explicit GEbounds(const GEnergies& energies);
72 72 GEbounds(const GEbounds& ebds);
73 73 GEbounds(const GEnergy& emin, const GEnergy& emax);
74   - GEbounds(const int& num, const GEnergy& emin, const GEnergy& emax,
75   - const bool& log = true);
  74 + GEbounds(const int& num,
  75 + const GEnergy& emin,
  76 + const GEnergy& emax,
  77 + const std::string& method = "LOG",
  78 + const double& gamma = 1.0);
76 79 virtual ~GEbounds(void);
77 80  
78 81 // Operators
... ... @@ -92,8 +95,11 @@ public:
92 95 void reserve(const int& num);
93 96 void extend(const GEbounds& ebds);
94 97 void set(const GEnergies& energies);
95   - void set_lin(const int& num, const GEnergy& emin, const GEnergy& emax);
96   - void set_log(const int& num, const GEnergy& emin, const GEnergy& emax);
  98 + void set(const int& num,
  99 + const GEnergy& emin,
  100 + const GEnergy& emax,
  101 + const std::string& method = "LOG",
  102 + const double& gamma = 1.0);
97 103 void load(const GFilename& filename);
98 104 void save(const GFilename& filename,
99 105 const bool& clobber = false,
... ... @@ -118,7 +124,6 @@ public:
118 124 bool contains(const GEnergy& emin, const GEnergy& emax) const;
119 125 std::string print(const GChatter& chatter = NORMAL) const;
120 126  
121   -
122 127 protected:
123 128 // Protected methods
124 129 void init_members(void);
... ... @@ -126,6 +131,11 @@ protected:
126 131 void free_members(void);
127 132 void set_attributes(void);
128 133 void insert_eng(const int& index, const GEnergy& emin, const GEnergy& emax);
  134 + void set_lin(const int& num, const GEnergy& emin, const GEnergy& emax);
  135 + void set_log(const int& num, const GEnergy& emin, const GEnergy& emax);
  136 + void set_pow(const int& num, const GEnergy& emin, const GEnergy& emax,
  137 + const double& gamma);
  138 +
129 139  
130 140 // Protected data area
131 141 int m_num; //!< Number of energy boundaries
... ...
inst/cta/src/GCTAModelAeffBackground.cpp
... ... @@ -563,8 +563,10 @@ GCTAEventList* GCTAModelAeffBackground::mc(const GObservation&amp; obs,
563 563 // a fixed energy sampling for an instance of GModelSpectralNodes.
564 564 // This is analogous to to the GCTAModelIrfBackground::mc method.
565 565 // We make sure that only non-negative nodes get appended.
566   - GEbounds spectral_ebounds =
567   - GEbounds(m_n_mc_energies, ebounds.emin(), ebounds.emax(), true);
  566 + GEbounds spectral_ebounds(m_n_mc_energies,
  567 + ebounds.emin(),
  568 + ebounds.emax(),
  569 + "LOG");
568 570 GModelSpectralNodes spectral;
569 571 for (int i = 0; i < spectral_ebounds.size(); ++i) {
570 572 GEnergy energy = spectral_ebounds.elogmean(i);
... ...
pyext/GEbounds.i
1 1 /***************************************************************************
2 2 * GEbounds.i - Energy boundaries class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2018 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2020 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -49,8 +49,11 @@ public:
49 49 explicit GEbounds(const GEnergies& energies);
50 50 GEbounds(const GEbounds& ebds);
51 51 GEbounds(const GEnergy& emin, const GEnergy& emax);
52   - GEbounds(const int& num, const GEnergy& emin, const GEnergy& emax,
53   - const bool& log = true);
  52 + GEbounds(const int& num,
  53 + const GEnergy& emin,
  54 + const GEnergy& emax,
  55 + const std::string& method = "LOG",
  56 + const double& gamma = 1.0);
54 57 virtual ~GEbounds(void);
55 58  
56 59 // Methods
... ... @@ -67,8 +70,11 @@ public:
67 70 void reserve(const int& num);
68 71 void extend(const GEbounds& ebds);
69 72 void set(const GEnergies& energies);
70   - void set_lin(const int& num, const GEnergy& emin, const GEnergy& emax);
71   - void set_log(const int& num, const GEnergy& emin, const GEnergy& emax);
  73 + void set(const int& num,
  74 + const GEnergy& emin,
  75 + const GEnergy& emax,
  76 + const std::string& method = "LOG",
  77 + const double& gamma = 1.0);
72 78 void load(const GFilename& filename);
73 79 void save(const GFilename& filename,
74 80 const bool& clobber = false,
... ...
src/obs/GEbounds.cpp
1 1 /***************************************************************************
2 2 * GEbounds.cpp - Energy boundary class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2020 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -41,8 +41,8 @@
41 41 #include "GXmlElement.hpp"
42 42  
43 43 /* __ Method name definitions ____________________________________________ */
44   -#define G_SET_LIN "GEbounds::set_lin(int&, GEnergy&, GEnergy&)"
45   -#define G_SET_LOG "GEbounds::set_log(int&, GEnergy&, GEnergy&)"
  44 +#define G_SET "GEbounds::set(int&, GEnergy&, GEnergy&, std::string&, "\
  45 + "double&)"
46 46 #define G_READ_XML "GEbounds::read(GXmlElement&)"
47 47 #define G_WRITE_XML "GEbounds::write(GXmlElement&)"
48 48 #define G_REMOVE "GEbounds::remove(int&)"
... ... @@ -54,6 +54,9 @@
54 54 #define G_ELOGMEAN "GEbounds::elogmean(int&)"
55 55 #define G_EWIDTH "GEbounds::ewidth(int&)"
56 56 #define G_INSERT_ENG "GEbounds::insert_eng(int&, GEnergy&, GEnergy&)"
  57 +#define G_SET_LIN "GEbounds::set_lin(int&, GEnergy&, GEnergy&)"
  58 +#define G_SET_LOG "GEbounds::set_log(int&, GEnergy&, GEnergy&)"
  59 +#define G_SET_POW "GEbounds::set_pow(int&, GEnergy&, GEnergy&, double&)"
57 60  
58 61 /* __ Macros _____________________________________________________________ */
59 62  
... ... @@ -186,25 +189,25 @@ GEbounds::GEbounds(const GEnergy&amp; emin, const GEnergy&amp; emax)
186 189 * @param[in] num Number of energy intervals.
187 190 * @param[in] emin Minimum energy of first interval.
188 191 * @param[in] emax Maximum energy of last interval.
189   - * @param[in] log Use logarithmic spacing? (defaults to true).
  192 + * @param[in] method Energy spacing method (one of "LIN", "LOG" or "POW").
  193 + * @param[in] gamma Power law index for @p POW method.
190 194 *
191 195 * Constructs energy boundaries by defining @p num successive energy
192   - * intervals between @p emin and @p emax. The @p log parameter controls
193   - * whether the energy spacing is logarihmic (default) or linear.
  196 + * intervals between @p emin and @p emax. The @p method parameter controls
  197 + * the energy spacing of the energy boundaries. See the set() method for
  198 + * more information.
194 199 ***************************************************************************/
195   -GEbounds::GEbounds(const int& num, const GEnergy& emin, const GEnergy& emax,
196   - const bool& log)
  200 +GEbounds::GEbounds(const int& num,
  201 + const GEnergy& emin,
  202 + const GEnergy& emax,
  203 + const std::string& method,
  204 + const double& gamma)
197 205 {
198 206 // Initialise members
199 207 init_members();
200 208  
201 209 // Set intervals
202   - if (log) {
203   - this->set_log(num, emin, emax);
204   - }
205   - else {
206   - this->set_lin(num, emin, emax);
207   - }
  210 + set(num, emin, emax, method, gamma);
208 211  
209 212 // Return
210 213 return;
... ... @@ -572,119 +575,44 @@ void GEbounds::set(const GEnergies&amp; energies)
572 575 * @param[in] num Number of energy intervals.
573 576 * @param[in] emin Minimum energy of first interval.
574 577 * @param[in] emax Maximum energy of last interval.
  578 + * @param[in] method Energy spacing method (one of "LIN", "LOG" or "POW").
  579 + * @param[in] gamma Power law index for @p POW method.
575 580 *
576 581 * @exception GException::invalid_argument
577 582 * Minimum energy is larger than the maximum energy.
578 583 *
579   - * Creates @p num linearly spaced energy boundaries running from @p emin to
580   - * @p emax. If @p num is not a positive integer, no energy
581   - * boundaries will be set.
582   - ***************************************************************************/
583   -void GEbounds::set_lin(const int& num, const GEnergy& emin, const GEnergy& emax)
584   -{
585   - // Initialise members
586   - clear();
587   -
588   - // Continue only if the requested number of energy boundaries is positive
589   - if (num > 0) {
590   -
591   - // Throw an exception if the maximum energy is smaller than the
592   - // minimum energy
593   - if (emin > emax) {
594   - std::string msg = "Minimum energy "+emin.print()+" is larger than "
595   - "maximum energy "+emax.print()+". Please provide "
596   - "a minimum energy that is not larger than the "
597   - "maximum energy.";
598   - throw GException::invalid_argument(G_SET_LIN, msg);
599   - }
600   -
601   - // Compute bin width
602   - GEnergy ebin = (emax - emin)/double(num);
603   -
604   - // Append boundaries
605   - GEnergy min = emin;
606   - GEnergy max = emin + ebin;
607   - for (int i = 0; i < num; ++i) {
608   - append(min, max);
609   - min += ebin;
610   - max += ebin;
611   - }
612   -
613   - // Set attributes
614   - set_attributes();
615   -
616   - } // endif: number of energy boundaries was positive
617   -
618   - // Return
619   - return;
620   -}
621   -
622   -
623   -/***********************************************************************//**
624   - * @brief Set logarithmically spaced energy intervals
625   - *
626   - * @param[in] num Number of energy intervals.
627   - * @param[in] emin Minimum energy of first interval.
628   - * @param[in] emax Maximum energy of last interval.
  584 + * Sets energy boundaries by defining @p num successive energy intervals
  585 + * between @p emin and @p emax. The @p method parameter controls the energy
  586 + * spacing of the energy boundaries. See the set_lin(), set_log() and
  587 + * set_pow() methods for more information.
629 588 *
630   - * @exception GException::invalid_argument
631   - * Minimum or maximum energy are not positive or minimum energy
632   - * is larger than the maximum energy.
633   - *
634   - * Creates @p num logarithmically spaced energy boundaries running from
635   - * @p emin to @p emax. If @p num is not a positive integer, no energy
636   - * boundaries will be set.
  589 + * If @p num is not a positive integer, no energy boundaries will be set.
637 590 ***************************************************************************/
638   -void GEbounds::set_log(const int& num, const GEnergy& emin, const GEnergy& emax)
  591 +void GEbounds::set(const int& num,
  592 + const GEnergy& emin,
  593 + const GEnergy& emax,
  594 + const std::string& method,
  595 + const double& gamma)
639 596 {
640   - // Initialise members
641   - clear();
  597 + // Convert method to upper-case string
  598 + std::string umethod = gammalib::toupper(method);
642 599  
643   - // Continue only if the requested number of energy boundaries is positive
644   - if (num > 0) {
645   -
646   - // Throw an exception if the minimum or maximum energy is not positive
647   - if (emin.MeV() <= 0.0) {
648   - std::string msg = "Non-positive minimum energy "+emin.print()+
649   - " specified. Please provide a positive minimum "
650   - "energy value.";
651   - throw GException::invalid_argument(G_SET_LOG, msg);
652   - }
653   - if (emax.MeV() <= 0.0) {
654   - std::string msg = "Non-positive maximum energy "+emax.print()+
655   - " specified. Please provide a positive minimum "
656   - "energy value.";
657   - throw GException::invalid_argument(G_SET_LOG, msg);
658   - }
659   -
660   - // Throw an exception if the maximum energy is smaller than the
661   - // minimum energy
662   - if (emin > emax) {
663   - std::string msg = "Minimum energy "+emin.print()+" is larger than "
664   - "maximum energy "+emax.print()+". Please provide "
665   - "a minimum energy that is not larger than the "
666   - "maximum energy.";
667   - throw GException::invalid_argument(G_SET_LOG, msg);
668   - }
669   -
670   - // Compute bin width
671   - double elogmin = std::log10(emin.MeV());
672   - double elogmax = std::log10(emax.MeV());
673   - double elogbin = (elogmax - elogmin)/double(num);
674   -
675   - // Append boundaries
676   - GEnergy min;
677   - GEnergy max;
678   - for (int i = 0; i < num; ++i) {
679   - min.MeV(std::pow(10.0, double(i)*elogbin + elogmin));
680   - max.MeV(std::pow(10.0, double(i+1)*elogbin + elogmin));
681   - append(min, max);
682   - }
683   -
684   - // Set attributes
685   - set_attributes();
686   -
687   - } // endif: number of energy boundaries was positive
  600 + // Dispatch to corresponding set methos
  601 + if (umethod == "LIN") {
  602 + set_lin(num, emin, emax);
  603 + }
  604 + else if (umethod == "LOG") {
  605 + set_log(num, emin, emax);
  606 + }
  607 + else if (umethod == "POW") {
  608 + set_pow(num, emin, emax, gamma);
  609 + }
  610 + else {
  611 + std::string msg = "Invalid energy spacing method \""+umethod+"\" "
  612 + "specified. Please provide one of \"LIN\", \"LOG\""
  613 + ", or \"POW\".";
  614 + throw GException::invalid_argument(G_SET, msg);
  615 + }
688 616  
689 617 // Return
690 618 return;
... ... @@ -1458,6 +1386,245 @@ void GEbounds::insert_eng(const int&amp; index,
1458 1386 }
1459 1387  
1460 1388  
  1389 +/***********************************************************************//**
  1390 + * @brief Set linearly spaced energy intervals
  1391 + *
  1392 + * @param[in] num Number of energy intervals.
  1393 + * @param[in] emin Minimum energy of first interval.
  1394 + * @param[in] emax Maximum energy of last interval.
  1395 + *
  1396 + * @exception GException::invalid_argument
  1397 + * Minimum energy is larger than the maximum energy.
  1398 + *
  1399 + * Creates \f$N\f$ linearly spaced energy boundaries running from
  1400 + * \f$E_{\rm min}\f$ to \f$E_{\rm max}\f$ defined by
  1401 + *
  1402 + * \f[
  1403 + * E_{\rm min}^{(i)} = E_{\rm min} + \frac{E_{\rm max} - E_{\rm min}}{N}
  1404 + * \times i
  1405 + * \f]
  1406 + *
  1407 + * and
  1408 + *
  1409 + * \f[
  1410 + * E_{\rm max}^{(i)} = E_{\rm min} + \frac{E_{\rm max} - E_{\rm min}}{N}
  1411 + * \times (i + 1)
  1412 + * \f]
  1413 + *
  1414 + * If @p num is not positive the method will do nothing.
  1415 + ***************************************************************************/
  1416 +void GEbounds::set_lin(const int& num, const GEnergy& emin, const GEnergy& emax)
  1417 +{
  1418 + // Continue only if the requested number of energy boundaries is positive
  1419 + if (num > 0) {
  1420 +
  1421 + // Throw an exception if the maximum energy is smaller than the
  1422 + // minimum energy
  1423 + if (emin > emax) {
  1424 + std::string msg = "Minimum energy "+emin.print()+" is larger than "
  1425 + "maximum energy "+emax.print()+". Please provide "
  1426 + "a minimum energy that is not larger than the "
  1427 + "maximum energy.";
  1428 + throw GException::invalid_argument(G_SET_LIN, msg);
  1429 + }
  1430 +
  1431 + // Compute bin width
  1432 + GEnergy ebin = (emax - emin)/double(num);
  1433 +
  1434 + // Append boundaries
  1435 + GEnergy min = emin;
  1436 + GEnergy max = emin + ebin;
  1437 + for (int i = 0; i < num; ++i) {
  1438 + append(min, max);
  1439 + min += ebin;
  1440 + max += ebin;
  1441 + }
  1442 +
  1443 + // Set attributes
  1444 + set_attributes();
  1445 +
  1446 + } // endif: number of energy boundaries was positive
  1447 +
  1448 + // Return
  1449 + return;
  1450 +}
  1451 +
  1452 +
  1453 +/***********************************************************************//**
  1454 + * @brief Set logarithmically spaced energy intervals
  1455 + *
  1456 + * @param[in] num Number of energy intervals.
  1457 + * @param[in] emin Minimum energy of first interval.
  1458 + * @param[in] emax Maximum energy of last interval.
  1459 + *
  1460 + * @exception GException::invalid_argument
  1461 + * Minimum or maximum energy are not positive or minimum energy
  1462 + * is larger than the maximum energy.
  1463 + *
  1464 + * Creates \f$N\f$ logarithmically spaced energy boundaries running from
  1465 + * \f$E_{\rm min}\f$ to \f$E_{\rm max}\f$ defined by
  1466 + *
  1467 + * \f[
  1468 + * E_{\rm min}^{(i)} = 10^{\log_{10} E_{\rm min} +
  1469 + * \frac{\log_{10} E_{\rm max} -
  1470 + * \log_{10} E_{\rm min}}{N}
  1471 + * \times i}
  1472 + * \f]
  1473 + *
  1474 + * and
  1475 + *
  1476 + * \f[
  1477 + * E_{\rm max}^{(i)} = 10^{\log_{10} E_{\rm min} +
  1478 + * \frac{\log_{10} E_{\rm max} -
  1479 + * \log_{10} E_{\rm min}}{N}
  1480 + * \times (i + 1)}
  1481 + * \f]
  1482 + *
  1483 + * If @p num is not positive the method will do nothing.
  1484 + ***************************************************************************/
  1485 +void GEbounds::set_log(const int& num, const GEnergy& emin, const GEnergy& emax)
  1486 +{
  1487 + // Initialise members
  1488 + clear();
  1489 +
  1490 + // Continue only if the requested number of energy boundaries is positive
  1491 + if (num > 0) {
  1492 +
  1493 + // Throw an exception if the minimum or maximum energy is not positive
  1494 + if (emin.MeV() <= 0.0) {
  1495 + std::string msg = "Non-positive minimum energy "+emin.print()+
  1496 + " specified. Please provide a positive minimum "
  1497 + "energy value.";
  1498 + throw GException::invalid_argument(G_SET_LOG, msg);
  1499 + }
  1500 + if (emax.MeV() <= 0.0) {
  1501 + std::string msg = "Non-positive maximum energy "+emax.print()+
  1502 + " specified. Please provide a positive minimum "
  1503 + "energy value.";
  1504 + throw GException::invalid_argument(G_SET_LOG, msg);
  1505 + }
  1506 +
  1507 + // Throw an exception if the maximum energy is smaller than the
  1508 + // minimum energy
  1509 + if (emin > emax) {
  1510 + std::string msg = "Minimum energy "+emin.print()+" is larger than "
  1511 + "maximum energy "+emax.print()+". Please provide "
  1512 + "a minimum energy that is not larger than the "
  1513 + "maximum energy.";
  1514 + throw GException::invalid_argument(G_SET_LOG, msg);
  1515 + }
  1516 +
  1517 + // Compute bin width
  1518 + double elogmin = std::log10(emin.MeV());
  1519 + double elogmax = std::log10(emax.MeV());
  1520 + double elogbin = (elogmax - elogmin)/double(num);
  1521 +
  1522 + // Append boundaries
  1523 + GEnergy min;
  1524 + GEnergy max;
  1525 + for (int i = 0; i < num; ++i) {
  1526 + min.MeV(std::pow(10.0, double(i)*elogbin + elogmin));
  1527 + max.MeV(std::pow(10.0, double(i+1)*elogbin + elogmin));
  1528 + append(min, max);
  1529 + }
  1530 +
  1531 + // Set attributes
  1532 + set_attributes();
  1533 +
  1534 + } // endif: number of energy boundaries was positive
  1535 +
  1536 + // Return
  1537 + return;
  1538 +}
  1539 +
  1540 +
  1541 +/***********************************************************************//**
  1542 + * @brief Set power-law spaced energy intervals
  1543 + *
  1544 + * @param[in] num Number of energy intervals.
  1545 + * @param[in] emin Minimum energy of first interval.
  1546 + * @param[in] emax Maximum energy of last interval.
  1547 + * @param[in] gamma Power law index.
  1548 + *
  1549 + * @exception GException::invalid_argument
  1550 + * Minimum or maximum energy are not positive or minimum energy
  1551 + * is larger than the maximum energy.
  1552 + *
  1553 + * Creates \f$N\f$ power-law spaced energy boundaries running from
  1554 + * \f$E_{\rm min}\f$ to \f$E_{\rm max}\f$.
  1555 + *
  1556 + * If @p num is not positive the method will do nothing.
  1557 + ***************************************************************************/
  1558 +void GEbounds::set_pow(const int& num,
  1559 + const GEnergy& emin,
  1560 + const GEnergy& emax,
  1561 + const double& gamma)
  1562 +{
  1563 + // Initialise members
  1564 + clear();
  1565 +
  1566 + // Continue only if the requested number of energy boundaries is positive
  1567 + if (num > 0) {
  1568 +
  1569 + // Throw an exception if the minimum or maximum energy is not positive
  1570 + if (emin.MeV() <= 0.0) {
  1571 + std::string msg = "Non-positive minimum energy "+emin.print()+
  1572 + " specified. Please provide a positive minimum "
  1573 + "energy value.";
  1574 + throw GException::invalid_argument(G_SET_POW, msg);
  1575 + }
  1576 + if (emax.MeV() <= 0.0) {
  1577 + std::string msg = "Non-positive maximum energy "+emax.print()+
  1578 + " specified. Please provide a positive minimum "
  1579 + "energy value.";
  1580 + throw GException::invalid_argument(G_SET_POW, msg);
  1581 + }
  1582 +
  1583 + // Throw an exception if the maximum energy is smaller than the
  1584 + // minimum energy
  1585 + if (emin > emax) {
  1586 + std::string msg = "Minimum energy "+emin.print()+" is larger than "
  1587 + "maximum energy "+emax.print()+". Please provide "
  1588 + "a minimum energy that is not larger than the "
  1589 + "maximum energy.";
  1590 + throw GException::invalid_argument(G_SET_POW, msg);
  1591 + }
  1592 +
  1593 + // Precomputation
  1594 + double a = 1.0 - gamma;
  1595 + double c = (a == 0.0) ? 1.0 / (std::log(emax.MeV()) - std::log(emin.MeV()))
  1596 + : a / (std::pow(emax.MeV(),a) - std::pow(emin.MeV(),a));
  1597 + //double b = double(c*(num-1.0));
  1598 + double b = double(c*num);
  1599 +
  1600 + // Append boundaries
  1601 + double e = emin.MeV();
  1602 + for (int i = 0; i < num; ++i) {
  1603 +
  1604 + // Compute upper bin boundary
  1605 + double log_e_next = (a == 0.0)
  1606 + ? 1.0/b + std::log(e)
  1607 + : std::log(a/b + std::pow(e,a)) / a;
  1608 + double e_next = std::exp(log_e_next);
  1609 +
  1610 + // Append energy bin
  1611 + append(GEnergy(e, "MeV"), GEnergy(e_next, "MeV"));
  1612 +
  1613 + // Store upper boundary as next lower boundary
  1614 + e = e_next;
  1615 +
  1616 + }
  1617 +
  1618 + // Set attributes
  1619 + set_attributes();
  1620 +
  1621 + } // endif: number of energy boundaries was positive
  1622 +
  1623 + // Return
  1624 + return;
  1625 +}
  1626 +
  1627 +
1461 1628 /*==========================================================================
1462 1629 = =
1463 1630 = Friends =
... ...
test/test_GObservation.cpp
... ... @@ -201,7 +201,7 @@ void TestGObservation::test_ebounds(void)
201 201  
202 202 // Check linear boundaries
203 203 ebds.clear();
204   - ebds.set_lin(2, GEnergy(1.0, "MeV"), GEnergy(3.0, "MeV"));
  204 + ebds.set(2, GEnergy(1.0, "MeV"), GEnergy(3.0, "MeV"), "LIN");
205 205 test_value(ebds.size(), 2, "GEbounds should have 2 elements.");
206 206 test_assert(!ebds.is_empty(), "GEbounds should not be empty.");
207 207 test_value(ebds.emin(0).MeV(), 1.0, 1.0e-10, "Bin 0 minimum energy should be 1.");
... ... @@ -213,7 +213,19 @@ void TestGObservation::test_ebounds(void)
213 213  
214 214 // Check logarithmic boundaries
215 215 ebds.clear();
216   - ebds.set_log(2, GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV"));
  216 + ebds.set(2, GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV"), "LOG");
  217 + test_value(ebds.size(), 2, "GEbounds should have 2 elements.");
  218 + test_assert(!ebds.is_empty(), "GEbounds should not be empty.");
  219 + test_value(ebds.emin(0).MeV(), 1.0, 1.0e-10, "Bin 0 minimum energy should be 1.");
  220 + test_value(ebds.emin(1).MeV(), 10.0, 1.0e-10, "Bin 1 minimum energy should be 10.");
  221 + test_value(ebds.emax(0).MeV(), 10.0, 1.0e-10, "Bin 0 maximum energy should be 10.");
  222 + test_value(ebds.emax(1).MeV(), 100.0, 1.0e-10, "Bin 1 maximum energy should be 100.");
  223 + test_value(ebds.emin().MeV(), 1.0, 1.0e-10, "Minimum energy should be 1.");
  224 + test_value(ebds.emax().MeV(), 100.0, 1.0e-10, "Maximum energy should be 100.");
  225 +
  226 + // Check power-law boundaries
  227 + ebds.clear();
  228 + ebds.set(2, GEnergy(1.0, "MeV"), GEnergy(100.0, "MeV"), "POW", 1.0);
217 229 test_value(ebds.size(), 2, "GEbounds should have 2 elements.");
218 230 test_assert(!ebds.is_empty(), "GEbounds should not be empty.");
219 231 test_value(ebds.emin(0).MeV(), 1.0, 1.0e-10, "Bin 0 minimum energy should be 1.");
... ... @@ -238,7 +250,7 @@ void TestGObservation::test_ebounds(void)
238 250 test_value(ebds.emax().MeV(), 1000.0, 1.0e-10, "Maximum energy should be 1000.");
239 251  
240 252 // Check emean, elogmean and ewidth methods
241   - ebds.set_log(1, GEnergy(1.0, "MeV"), GEnergy(10.0, "MeV"));
  253 + ebds.set(1, GEnergy(1.0, "MeV"), GEnergy(10.0, "MeV"), "LOG");
242 254 test_value(ebds.emean(0).MeV(), 5.5, 1.0e-10, "Mean energy should be 5.5.");
243 255 test_value(ebds.elogmean(0).MeV(), 3.16227766017, 1.0e-10, "Log mean energy should be 3.16227766017.");
244 256 test_value(ebds.ewidth(0).MeV(), 9.0, 1.0e-10, "Energy width should be 9.0.");
... ... @@ -259,7 +271,7 @@ void TestGObservation::test_ebounds(void)
259 271 // Check constructing of linear invalid energy boundaries
260 272 test_try("Test constructing of linear invalid energy boundaries");
261 273 try {
262   - GEbounds bad(10, GEnergy(100.0, "MeV"), GEnergy(10.0, "MeV"), false);
  274 + GEbounds bad(10, GEnergy(100.0, "MeV"), GEnergy(10.0, "MeV"), "LIN");
263 275 test_try_failure("Constructing of linear invalid energy boundaries "
264 276 "shall throw an exception.");
265 277 }
... ... @@ -273,7 +285,7 @@ void TestGObservation::test_ebounds(void)
273 285 // Check constructing of logarithmic invalid energy boundaries
274 286 test_try("Test constructing of logarithmic invalid energy boundaries");
275 287 try {
276   - GEbounds bad(10, GEnergy(100.0, "MeV"), GEnergy(10.0, "MeV"), true);
  288 + GEbounds bad(10, GEnergy(100.0, "MeV"), GEnergy(10.0, "MeV"), "LOG");
277 289 test_try_failure("Constructing of logarithmic invalid energy "
278 290 "boundaries shall throw an exception.");
279 291 }
... ... @@ -287,7 +299,7 @@ void TestGObservation::test_ebounds(void)
287 299 // Check constructing of logarithmic invalid energy boundaries
288 300 test_try("Test constructing of logarithmic invalid energy boundaries");
289 301 try {
290   - GEbounds bad(10, GEnergy(0.0, "MeV"), GEnergy(10.0, "MeV"), true);
  302 + GEbounds bad(10, GEnergy(0.0, "MeV"), GEnergy(10.0, "MeV"), "LOG");
291 303 test_try_failure("Constructing of logarithmic invalid energy "
292 304 "boundaries shall throw an exception.");
293 305 }
... ... @@ -301,7 +313,7 @@ void TestGObservation::test_ebounds(void)
301 313 // Check constructing of logarithmic invalid energy boundaries
302 314 test_try("Test constructing of logarithmic invalid energy boundaries");
303 315 try {
304   - GEbounds bad(10, GEnergy(10.0, "MeV"), GEnergy(0.0, "MeV"), true);
  316 + GEbounds bad(10, GEnergy(10.0, "MeV"), GEnergy(0.0, "MeV"), "LOG");
305 317 test_try_failure("Constructing of logarithmic invalid energy "
306 318 "boundaries shall throw an exception.");
307 319 }
... ... @@ -1370,7 +1382,7 @@ void TestGObservation::test_energies(void)
1370 1382 test_value(energies[2].MeV(), 100.0, 1.0e-10, "Energy 2 should be 100 MeV.");
1371 1383  
1372 1384 // Check energy boundary set method
1373   - GEbounds ebds1(2, GEnergy(1.0, "MeV"), GEnergy(3.0, "MeV"), false);
  1385 + GEbounds ebds1(2, GEnergy(1.0, "MeV"), GEnergy(3.0, "MeV"), "LIN");
1374 1386 energies.set(ebds1);
1375 1387 test_value(energies.size(), 3, "GEbounds constructor (3 elements)");
1376 1388 test_value(energies[0].MeV(), 1.0, 1.0e-10, "GEbounds constructor (3 elements)");
... ...
test/test_GObservation.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib observation module.
3 3 #
4   -# Copyright (C) 2012-2019 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2020 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -361,7 +361,7 @@ class Test(gammalib.GPythonTestSuite):
361 361 """
362 362 # Setup energies container
363 363 ebounds = gammalib.GEbounds(10, gammalib.GEnergy(1.0, 'MeV'),
364   - gammalib.GEnergy(11.0, 'MeV'), False)
  364 + gammalib.GEnergy(11.0, 'MeV'), 'LIN')
365 365  
366 366 # Test ebounds[start:end]
367 367 self.test_value(len(ebounds[3:5]), 2)
... ...
test/test_GXspec.cpp
1 1 /***************************************************************************
2 2 * test_GXspec.hpp - Test Xspec module *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2013-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2013-2020 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -88,7 +88,7 @@ void TestGXspec::test_GPha(void)
88 88 test_value(pha1.ancrfile(), "", "Check if empty PHA has empty ARF");
89 89  
90 90 // Test energy boundary constructor, filling and accessing
91   - GEbounds ebds2(9, GEnergy(1.0, "TeV"), GEnergy(10.0, "TeV"), false);
  91 + GEbounds ebds2(9, GEnergy(1.0, "TeV"), GEnergy(10.0, "TeV"), "LIN");
92 92 GPha pha2(ebds2);
93 93 pha2.exposure(1234.5);
94 94 pha2.backfile("background");
... ...