GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GEbounds.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GEbounds.cpp - Energy boundary class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2009-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 GEbounds.cpp
23  * @brief Energy boundary class implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <cmath>
32 #include "GException.hpp"
33 #include "GTools.hpp"
34 #include "GFilename.hpp"
35 #include "GEbounds.hpp"
36 #include "GEnergies.hpp"
37 #include "GFits.hpp"
38 #include "GFitsTable.hpp"
39 #include "GFitsBinTable.hpp"
40 #include "GFitsTableDoubleCol.hpp"
41 #include "GXmlElement.hpp"
42 
43 /* __ Method name definitions ____________________________________________ */
44 #define G_READ_XML "GEbounds::read(GXmlElement&)"
45 #define G_WRITE_XML "GEbounds::write(GXmlElement&)"
46 #define G_REMOVE_INX "GEbounds::remove(int&)"
47 #define G_REMOVE_ENG "GEbounds::remove(GEnergy&, GEnergy&)"
48 #define G_EMIN_SET "GEbounds::emin(int&, GEnergy&)"
49 #define G_EMAX_SET "GEbounds::emax(int&, GEnergy&)"
50 #define G_EMIN_GET "GEbounds::emin(int&)"
51 #define G_EMAX_GET "GEbounds::emax(int&)"
52 #define G_EMEAN "GEbounds::emean(int&)"
53 #define G_ELOGMEAN "GEbounds::elogmean(int&)"
54 #define G_EWIDTH "GEbounds::ewidth(int&)"
55 #define G_INSERT_ENG "GEbounds::insert_eng(int&, GEnergy&, GEnergy&)"
56 
57 /* __ Macros _____________________________________________________________ */
58 
59 /* __ Coding definitions _________________________________________________ */
60 
61 /* __ Debug definitions __________________________________________________ */
62 
63 
64 /*==========================================================================
65  = =
66  = Constructors/destructors =
67  = =
68  ==========================================================================*/
69 
70 /***********************************************************************//**
71  * @brief Constructor
72  ***************************************************************************/
74 {
75  // Initialise class members for clean destruction
76  init_members();
77 
78  // Return
79  return;
80 }
81 
82 
83 /***********************************************************************//**
84  * @brief FITS file constructor
85  *
86  * @param[in] filename FITS file name.
87  *
88  * Constructs energy boundaries from a FITS file.
89  ***************************************************************************/
90 GEbounds::GEbounds(const GFilename& filename)
91 {
92  // Initialise members
93  init_members();
94 
95  // Load FITS file
96  load(filename);
97 
98  // Return
99  return;
100 }
101 
102 
103 /***********************************************************************//**
104  * @brief XML element constructor
105  *
106  * @param[in] xml XML element.
107  *
108  * Constructs energy boundaries from an XML element.
109  ***************************************************************************/
111 {
112  // Initialise members
113  init_members();
114 
115  // Read energy boundaries from XML element
116  read(xml);
117 
118  // Return
119  return;
120 }
121 
122 
123 /***********************************************************************//**
124  * @brief Energy container constructor
125  *
126  * @param[in] energies Energy container.
127  *
128  * Constructs energy boundaries from an energy container.
129  ***************************************************************************/
131 {
132  // Initialise members
133  init_members();
134 
135  // Set energy boundaries from energy container
136  set(energies);
137 
138  // Return
139  return;
140 }
141 
142 
143 /***********************************************************************//**
144  * @brief Copy constructor
145  *
146  * @param[in] ebds Energy boundaries.
147  ***************************************************************************/
149 {
150  // Initialise class members for clean destruction
151  init_members();
152 
153  // Copy members
154  copy_members(ebds);
155 
156  // Return
157  return;
158 }
159 
160 
161 /***********************************************************************//**
162  * @brief Single energy band constructor
163  *
164  * @param[in] emin Minimum energy of the interval.
165  * @param[in] emax Maximum energy of the interval.
166  *
167  * Constructs energy boundaries for one (emin, emax) energy band.
168  ***************************************************************************/
169 GEbounds::GEbounds(const GEnergy& emin, const GEnergy& emax)
170 {
171  // Initialise members
172  init_members();
173 
174  // Append energies
175  append(emin, emax);
176 
177  // Return
178  return;
179 }
180 
181 
182 /***********************************************************************//**
183  * @brief Interval constructor
184  *
185  * @param[in] num Number of energy intervals.
186  * @param[in] emin Minimum energy of first interval.
187  * @param[in] emax Maximum energy of last interval.
188  * @param[in] method Energy spacing method (one of "LIN", "LOG" or "POW").
189  * @param[in] gamma Power law index for @p POW method.
190  *
191  * Constructs energy boundaries by defining @p num successive energy
192  * intervals between @p emin and @p emax. The @p method parameter controls
193  * the energy spacing of the energy boundaries. See the set() method for
194  * more information.
195  ***************************************************************************/
196 GEbounds::GEbounds(const int& num,
197  const GEnergy& emin,
198  const GEnergy& emax,
199  const std::string& method,
200  const double& gamma)
201 {
202  // Initialise members
203  init_members();
204 
205  // Set intervals
206  set(num, emin, emax, method, gamma);
207 
208  // Return
209  return;
210 }
211 
212 
213 /***********************************************************************//**
214  * @brief Destructor
215  ***************************************************************************/
217 {
218  // Free members
219  free_members();
220 
221  // Return
222  return;
223 }
224 
225 
226 /*==========================================================================
227  = =
228  = Operators =
229  = =
230  ==========================================================================*/
231 
232 /***********************************************************************//**
233  * @brief Assignment operator
234  *
235  * @param[in] ebds Energy boundaries to be assigned.
236  * @return Energy boundaries.
237  ***************************************************************************/
239 {
240  // Execute only if object is not identical
241  if (this != &ebds) {
242 
243  // Free members
244  free_members();
245 
246  // Initialise private members for clean destruction
247  init_members();
248 
249  // Copy members
250  copy_members(ebds);
251 
252  } // endif: object was not identical
253 
254  // Return this object
255  return *this;
256 }
257 
258 
259 /*==========================================================================
260  = =
261  = Public methods =
262  = =
263  ==========================================================================*/
264 
265 /***********************************************************************//**
266  * @brief Clear energy boundaries
267  ***************************************************************************/
268 void GEbounds::clear(void)
269 {
270  // Free members
271  free_members();
272 
273  // Initialise private members
274  init_members();
275 
276  // Return
277  return;
278 }
279 
280 
281 /***********************************************************************//**
282  * @brief Clone energy boundaries
283  *
284  * @return Pointer to deep copy of energy boundaries.
285  ***************************************************************************/
287 {
288  return new GEbounds(*this);
289 }
290 
291 
292 /***********************************************************************//**
293  * @brief Append energy interval
294  *
295  * @param[in] emin Minimum energy of interval.
296  * @param[in] emax Maximum energy of interval.
297  *
298  * Appends an energy interval to the end of the energy boundaries
299  * container.
300  ***************************************************************************/
301 void GEbounds::append(const GEnergy& emin, const GEnergy& emax)
302 {
303  // Append interval at the end
304  insert_eng(m_num, emin, emax);
305 
306  // Return
307  return;
308 }
309 
310 
311 /***********************************************************************//**
312  * @brief Insert energy interval
313  *
314  * @param[in] emin Minimum energy of interval.
315  * @param[in] emax Maximum energy of interval.
316  *
317  * Inserts an energy interval into the energy boundaries after the first
318  * boundary that has a minimum energy smaller than @p emin. The method
319  * implicitely assumes that the intervals are ordered by increasing minimum
320  * energy.
321  ***************************************************************************/
322 void GEbounds::insert(const GEnergy& emin, const GEnergy& emax)
323 {
324  // Determine index at which interval should be inserted
325  int inx = 0;
326  for (; inx < m_num; ++inx) {
327  if (emin < m_min[inx])
328  break;
329  }
330 
331  // Insert interval
332  insert_eng(inx, emin, emax);
333 
334  // Return
335  return;
336 }
337 
338 
339 /***********************************************************************//**
340  * @brief Merge all overlapping or connecting successive energy intervals
341  *
342  * Merges all overlapping or connecting successive energy intervals. The
343  * method implicitely assumes that the intervals are ordered by increasing
344  * minimum energy.
345  *
346  * Note that the method does not actually reduce the memory size but just
347  * updates the information on the number of elements in the array.
348  ***************************************************************************/
349 void GEbounds::merge(void)
350 {
351  // Find overlaps
352  int i = 0;
353  int num = m_num;
354  while (i < num-1) {
355 
356  // If current energy interval overlaps with successor then merge both
357  // intervals, move all remaining intervals one position up, and
358  // reduce the number of elements
359  if (m_min[i+1] <= m_max[i]) {
360  m_min[i] = (m_min[i] < m_min[i+1]) ? m_min[i] : m_min[i+1];
361  m_max[i] = (m_max[i] > m_max[i+1]) ? m_max[i] : m_max[i+1];
362  for (int k = i+2; k < num; ++k) {
363  m_min[k-1] = m_min[k];
364  m_max[k-1] = m_max[k];
365  }
366  num--;
367  }
368 
369  // Otherwise increment interval index
370  else {
371  i++;
372  }
373 
374  } // endwhile: there were still intervals to check
375 
376  // Update number of elements in object
377  m_num = num;
378 
379  // Return
380  return;
381 }
382 
383 
384 /***********************************************************************//**
385  * @brief Merge energy interval into energy boundaries
386  *
387  * @param[in] emin Minimum energy of interval.
388  * @param[in] emax Maximum energy of interval.
389  *
390  * Inserts an energy interval into the energy boundaries after the first
391  * boundary that has a minimum energy smaller than @p emin and then merges
392  * any overlapping or connecting energy boundaries. The method implicitely
393  * assumes that the intervals are ordered by increasing minimum energy.
394  ***************************************************************************/
395 void GEbounds::merge(const GEnergy& emin, const GEnergy& emax)
396 {
397  // Determine index at which interval should be inserted
398  int inx = 0;
399  for (; inx < m_num; ++inx) {
400  if (emin < m_min[inx])
401  break;
402  }
403 
404  // Insert interval
405  insert_eng(inx, emin, emax);
406 
407  // Merge any overlapping energy intervals
408  merge();
409 
410  // Return
411  return;
412 }
413 
414 
415 /***********************************************************************//**
416  * @brief Remove energy interval
417  *
418  * @param[in] index Energy interval index [0,...,size()[.
419  *
420  * Removes energy interval at @p index from the energy boundaries container.
421  * All intervals after the specified @p index are moved forward by one
422  * position.
423  *
424  * Note that the method does not actually reduce the memory size but just
425  * updates the information on the number of elements in the array.
426  ***************************************************************************/
427 void GEbounds::remove(const int& index)
428 {
429  #if defined(G_RANGE_CHECK)
430  // If index is outside boundary then throw an error
431  if (index < 0 || index >= m_num) {
432  throw GException::out_of_range(G_REMOVE_INX, "Energy interval index",
433  index, m_num);
434  }
435  #endif
436 
437  // Move all elements located after index forward
438  for (int i = index+1; i < m_num; ++i) {
439  m_min[i-1] = m_min[i];
440  m_max[i-1] = m_max[i];
441  }
442 
443  // Reduce number of elements by one
444  m_num--;
445 
446  // Update attributes
447  set_attributes();
448 
449  // Return
450  return;
451 }
452 
453 
454 /***********************************************************************//**
455  * @brief Remove energy interval from energy boundaries
456  *
457  * @param[in] emin Minimum energy of interval.
458  * @param[in] emax Maximum energy of interval.
459  *
460  * @exception GException::invalid_argument
461  * Minimum energy larger than maximum energy
462  *
463  * Removes an energy interval from the energy boundaries. If the energy
464  * interval is fully enclosed in an existing energy boundary, the energy
465  * boundary will be split into two, excluding the specified energy interval.
466  * If the energy interval corresponds exactly to an existing energy boundary
467  * the corresponding energy boundary will be removed. Otherwise the existing
468  * energy boundaries will be adjusted to exclude the specified energy
469  * interval.
470  ***************************************************************************/
471 void GEbounds::remove(const GEnergy& emin, const GEnergy& emax)
472 {
473  // Throw an exception if energy interval is invalid
474  if (emin > emax) {
475  std::string msg = "Invalid energy interval specified. Minimum"
476  " energy "+emin.print(NORMAL)+" can not be"
477  " larger than maximum energy "+
478  emax.print(NORMAL)+".";
480  }
481 
482  // Loop over all elements
483  for (int inx = 0; inx < m_num; ++inx) {
484 
485  // If energy interval corresponds exactly to the energy
486  // boundary then remove the element
487  if ((m_min[inx] == emin) && (m_max[inx] == emax)) {
488  this->remove(inx);
489  break;
490  }
491 
492  // ... otherwise, if energy interval is enclosed in energy boundary
493  // then split the element into two
494  else if ((m_min[inx] < emin) && (m_max[inx] > emax)) {
495  GEnergy emin_old = m_min[inx];
496  GEnergy emax_old = m_max[inx];
497  this->remove(inx);
498  this->insert(emin_old, emin);
499  this->insert(emax, emax_old);
500  break;
501  }
502 
503  // ... otherwise
504  else {
505 
506  // If emin is comprised in energy interval then set maximum
507  // energy to interval start
508  if ((m_min[inx] <= emin) && (m_max[inx] >= emin)) {
509  m_max[inx] = emin;
510  }
511 
512  // If emax is comprised in energy interval then set minimum
513  // energy to interval end
514  if ((m_min[inx] <= emax) && (m_max[inx] >= emax)) {
515  m_min[inx] = emax;
516  }
517 
518  }
519 
520  } // endfor: looped over boundaries
521 
522  // Update attributes
523  set_attributes();
524 
525  // Return
526  return;
527 }
528 
529 
530 /***********************************************************************//**
531  * @brief Reserve space for energy intervals
532  *
533  * @param[in] num Number of elements.
534  *
535  * This method does nothing (it is needed to satisfy the GContainer
536  * interface).
537  ***************************************************************************/
538 void GEbounds::reserve(const int& num)
539 {
540  // Return
541  return;
542 }
543 
544 
545 /***********************************************************************//**
546  * @brief Append energy boundaries
547  *
548  * @param[in] ebds Energy boundaries.
549  *
550  * Append energy boundaries to the container.
551  ***************************************************************************/
552 void GEbounds::extend(const GEbounds& ebds)
553 {
554  // Do nothing if energy boundaries are empty
555  if (!ebds.is_empty()) {
556 
557  // Allocate new intervals
558  int num = m_num+ebds.size();
559  GEnergy* min = new GEnergy[num];
560  GEnergy* max = new GEnergy[num];
561 
562  // Initialise index
563  int inx = 0;
564 
565  // Copy existing intervals
566  for (; inx < m_num; ++inx) {
567  min[inx] = m_min[inx];
568  max[inx] = m_max[inx];
569  }
570 
571  // Append intervals
572  for (int i = 0; i < ebds.size(); ++i, ++inx) {
573  min[inx] = ebds.m_min[i];
574  max[inx] = ebds.m_max[i];
575  }
576 
577  // Free memory
578  if (m_min != NULL) delete [] m_min;
579  if (m_max != NULL) delete [] m_max;
580 
581  // Set new memory
582  m_min = min;
583  m_max = max;
584 
585  // Set number of elements
586  m_num = num;
587 
588  // Set attributes
589  set_attributes();
590 
591  } // endif: energy boundaries were not empty
592 
593  // Return
594  return;
595 }
596 
597 
598 /***********************************************************************//**
599  * @brief Set energy boundaries from energy container
600  *
601  * @param[in] energies Energy container.
602  *
603  * Sets the energy boundaries from an energy container. Each two subsequent
604  * energies in the energy container will form an energy boundary. This
605  * means that n energies will lead to n-1 energy boundaries with the
606  * following mapping:
607  *
608  * [energies[0], energies[1]]
609  * [energies[1], energies[2]]
610  * ...
611  * [energies[n-2], energies[n-1]]
612  *
613  * If there is only one energy in the container the following empty energy
614  * boundary will be appended:
615  *
616  * [energies[0], energies[0]]
617  ***************************************************************************/
618 void GEbounds::set(const GEnergies& energies)
619 {
620  // Initialise members
621  clear();
622 
623  // Get number of energies in container
624  int num = energies.size();
625 
626  // If there is only one energy in the container then append an empty
627  // energy boundary
628  if (num == 1) {
629  append(energies[0], energies[0]);
630  }
631 
632  // ... otherwise if there is more than one energy in the container
633  // then append subsequent energies as boundaries
634  else if (num > 1) {
635  for (int i = 0; i < num-1; ++i) {
636  append(energies[i], energies[i+1]);
637  }
638  }
639 
640  // Set attributes
641  set_attributes();
642 
643  // Return
644  return;
645 }
646 
647 
648 /***********************************************************************//**
649  * @brief Set energy intervals
650  *
651  * @param[in] num Number of energy intervals.
652  * @param[in] emin Minimum energy of first interval.
653  * @param[in] emax Maximum energy of last interval.
654  * @param[in] method Energy spacing method (one of "LIN", "LOG" or "POW").
655  * @param[in] gamma Power law index for @p POW method.
656  *
657  * Sets energy boundaries by defining @p num successive energy intervals
658  * between @p emin and @p emax. The @p method parameter controls the energy
659  * spacing of the energy boundaries. See the GEnergies::set() method for
660  * more information.
661  ***************************************************************************/
662 void GEbounds::set(const int& num,
663  const GEnergy& emin,
664  const GEnergy& emax,
665  const std::string& method,
666  const double& gamma)
667 {
668  // Set energies
669  GEnergies energies(num+1, emin, emax, method, gamma);
670 
671  // Set energy boundaries from energies
672  set(energies);
673 
674  // Return
675  return;
676 }
677 
678 
679 /***********************************************************************//**
680  * @brief Load energy boundaries from FITS file
681  *
682  * @param[in] filename FITS file name.
683  *
684  * Loads the energy boundaries from a FITS file.
685  *
686  * If no extension name is provided, the energy boundaries are loaded from
687  * the `EBOUNDS` extension.
688  ***************************************************************************/
689 void GEbounds::load(const GFilename& filename)
690 {
691  // Open FITS file
692  GFits fits(filename);
693 
694  // Get energy boundary table
695  const GFitsTable& table = *fits.table(filename.extname(gammalib::extname_ebounds));
696 
697  // Read energy boundaries from table
698  read(table);
699 
700  // Close FITS file
701  fits.close();
702 
703  // Return
704  return;
705 }
706 
707 
708 /***********************************************************************//**
709  * @brief Save energy boundaries into FITS file
710  *
711  * @param[in] filename FITS file name.
712  * @param[in] clobber Overwrite an existing energy boundaries extension?
713  * @param[in] unit Energy unit
714  *
715  * Saves energy boundaries into a FITS file. If a file with the given
716  * @p filename does not yet exist it will be created, otherwise the method
717  * opens the existing file. Energy boundaries can only be appended to an
718  * existing file if the @p clobber flag is set to "true" (otherwise an
719  * exception is thrown).
720  *
721  * The method will append a binary FITS table containing the energy
722  * boundaries to the FITS file. The extension name can be specified as part
723  * of the @p filename. For example the @p filename
724  *
725  * myfile.fits[ENERGY BOUNDARIES]
726  *
727  * will save the energy boundaries in the `ENERGY BOUNDARIES` extension of
728  * the "myfile.fits" file. If the extension exists already in the file it
729  * will be replaced, otherwise a new extension will be created. If no
730  * extension name is provided, the method will use `EBOUNDS` as the default
731  * extension name for energy boundaries.
732  ***************************************************************************/
733 void GEbounds::save(const GFilename& filename,
734  const bool& clobber,
735  const std::string& unit) const
736 {
737  // Open or create FITS file (without extension name since the requested
738  // extension may not yet exist in the file)
739  GFits fits(filename.url(), true);
740 
741  // Write energy boundaries to FITS file
742  write(fits, filename.extname(gammalib::extname_ebounds), unit);
743 
744  // Save to file
745  fits.save(clobber);
746 
747  // Return
748  return;
749 }
750 
751 
752 /***********************************************************************//**
753  * @brief Read energy boundaries from FITS table
754  *
755  * @param[in] table FITS table.
756  *
757  * Reads the energy boundaries from a FITS table. The method interprets the
758  * energy units provide in the FITS header. If no energy units are found it
759  * is assumed that the energies are stored in units of keV.
760  ***************************************************************************/
761 void GEbounds::read(const GFitsTable& table)
762 {
763  // Free members
764  free_members();
765 
766  // Initialise attributes
767  init_members();
768 
769  // Extract energy boundary information from FITS table
770  m_num = table.integer("NAXIS2");
771  if (m_num > 0) {
772 
773  // Allocate memory
774  m_min = new GEnergy[m_num];
775  m_max = new GEnergy[m_num];
776 
777  // Get units
778  std::string emin_unit = table["E_MIN"]->unit();
779  std::string emax_unit = table["E_MAX"]->unit();
780  if (emin_unit.empty()) {
781  emin_unit = "keV";
782  }
783  if (emax_unit.empty()) {
784  emax_unit = "keV";
785  }
786 
787  // Copy information
788  for (int i = 0; i < m_num; ++i) {
789  m_min[i](table["E_MIN"]->real(i), emin_unit);
790  m_max[i](table["E_MAX"]->real(i), emax_unit);
791  }
792 
793  // Set attributes
794  set_attributes();
795 
796  } // endif: there were channels to read
797 
798  // Return
799  return;
800 }
801 
802 
803 /***********************************************************************//**
804  * @brief Write energy boundaries into FITS object
805  *
806  * @param[in] fits FITS file.
807  * @param[in] extname Energy boundary extension name.
808  * @param[in] unit Energy units.
809  *
810  * Writes the energy boundaries into a FITS object. The @p unit parameter
811  * specifies in which unit the energies are written. By default, the energy
812  * units are keV.
813  *
814  * @todo Write header keywords.
815  ***************************************************************************/
817  const std::string& extname,
818  const std::string& unit) const
819 {
820  // Create energy boundary columns
821  GFitsTableDoubleCol cemin("E_MIN", m_num);
822  GFitsTableDoubleCol cemax("E_MAX", m_num);
823 
824  // Fill energy boundary columns
825  for (int i = 0; i < m_num; ++i) {
826  cemin(i) = m_min[i](unit);
827  cemax(i) = m_max[i](unit);
828  }
829 
830  // Set energy units
831  cemin.unit(unit);
832  cemax.unit(unit);
833 
834  // Create binary table
835  GFitsBinTable table(m_num);
836  table.append(cemin);
837  table.append(cemax);
838  table.extname(extname);
839 
840  // If the FITS object contains already an extension with the same
841  // name then remove now this extension
842  if (fits.contains(extname)) {
843  fits.remove(extname);
844  }
845 
846  // Append energy boundary table to FITS file
847  fits.append(table);
848 
849  // Return
850  return;
851 }
852 
853 
854 /***********************************************************************//**
855  * @brief Read energy boundaries from XML element
856  *
857  * @param[in] xml XML element.
858  *
859  * @exception GException::invalid_value
860  * Invalid XML format encountered.
861  *
862  * Read energy boundaries from an XML element. The format of the energy
863  * boundaries is
864  *
865  * <parameter name="EnergyBoundaries" emin="0.1" emax="10.0"/>
866  *
867  * The units of the @a emin and @a emax parameters are MeV.
868  ***************************************************************************/
869 void GEbounds::read(const GXmlElement& xml)
870 {
871  // Clear energy boundaries
872  clear();
873 
874  // Get energy boundaries parameter
875  const GXmlElement* par = gammalib::xml_get_par(G_READ_XML, xml,
876  "EnergyBoundaries");
877 
878  // Extract position attributes
879  if (par->has_attribute("emin") && par->has_attribute("emax")) {
880  double emin = gammalib::todouble(par->attribute("emin"));
881  double emax = gammalib::todouble(par->attribute("emax"));
882  append(GEnergy(emin, "MeV"), GEnergy(emax, "MeV"));
883  }
884  else {
885  std::string msg = "Attributes \"emin\" and/or \"emax\" not found"
886  " in XML parameter \"EnergyBoundaries\"."
887  " Please verify the XML format.";
889  }
890 
891  // Set attribues
892  set_attributes();
893 
894  // Return
895  return;
896 }
897 
898 
899 /***********************************************************************//**
900  * @brief Write energy boundaries into XML element
901  *
902  * @param[in] xml XML element.
903  *
904  * Writes energy boundaries into an XML element. The format of the energy
905  * boundaries is
906  *
907  * <parameter name="EnergyBoundaries" emin="0.1" emax="10.0"/>
908  *
909  * The units of the @a emin and @a emax parameters are MeV.
910  *
911  * This method does nothing if the energy boundaries are empty.
912  ***************************************************************************/
913 void GEbounds::write(GXmlElement& xml) const
914 {
915  // Continue only if there are energy boundaries
916  if (!is_empty()) {
917 
918  // Get parameter
920  "EnergyBoundaries");
921 
922  // Write attributes
923  par->attribute("emin", gammalib::str(emin().MeV()));
924  par->attribute("emax", gammalib::str(emax().MeV()));
925 
926  } // endif: energy boundaries were not empty
927 
928  // Return
929  return;
930 }
931 
932 
933 /***********************************************************************//**
934  * @brief Returns energy bin index for a given energy
935  *
936  * @param[in] eng Energy.
937  * @return Bin index.
938  *
939  * Returns the energy boundary bin index for a given energy. By convention,
940  * the limits for an energy bin are defined as
941  *
942  * min <= energy < max
943  *
944  * i.e. and energy equals to max falls above the largest energy.
945  *
946  * If the energy falls outside all boundaries, -1 is returned.
947  ***************************************************************************/
948 int GEbounds::index(const GEnergy& eng) const
949 {
950  // Initialise index with 'not found'
951  int index = -1;
952 
953  // Search all energy boundaries for containment
954  for (int i = 0; i < m_num; ++i) {
955  if (eng >= m_min[i] && eng < m_max[i]) {
956  index = i;
957  break;
958  }
959  }
960 
961  // Return index
962  return index;
963 }
964 
965 
966 /***********************************************************************//**
967  * @brief Set minimum energy for a given energy interval
968  *
969  * @param[in] index Energy interval index (0,...,size()-1).
970  * @param[in] energy Minimum energy of interval.
971  *
972  * @exception GException::out_of_range
973  * Specified index is out of range.
974  *
975  * Sets the minimum energy for the energy interval @p index.
976  ***************************************************************************/
977 void GEbounds::emin(const int& index, const GEnergy& energy)
978 {
979  #if defined(G_RANGE_CHECK)
980  // Throw an exception if index is outside valid range
981  if (index < 0 || index >= m_num) {
983  "Minimum energy of interval",
984  index, m_num);
985  }
986  #endif
987 
988  // Set minimum energy
989  m_min[index] = energy;
990 
991  // Set attributes
992  set_attributes();
993 
994  // Return
995  return;
996 }
997 
998 
999 /***********************************************************************//**
1000  * @brief Set maximum energy for a given energy interval
1001  *
1002  * @param[in] index Energy interval index (0,...,size()-1).
1003  * @param[in] energy Maximum energy of interval.
1004  *
1005  * @exception GException::out_of_range
1006  * Specified index is out of range.
1007  *
1008  * Sets the maximum energy for the energy interval @p index.
1009  ***************************************************************************/
1010 void GEbounds::emax(const int& index, const GEnergy& energy)
1011 {
1012  #if defined(G_RANGE_CHECK)
1013  // Throw an exception if index is outside valid range
1014  if (index < 0 || index >= m_num) {
1016  "Maximum energy of interval",
1017  index, m_num);
1018  }
1019  #endif
1020 
1021  // Set maximum energy
1022  m_max[index] = energy;
1023 
1024  // Set attributes
1025  set_attributes();
1026 
1027  // Return
1028  return;
1029 }
1030 
1031 
1032 /***********************************************************************//**
1033  * @brief Returns minimum energy for a given energy interval
1034  *
1035  * @param[in] index Energy interval index (0,...,size()-1).
1036  * @return Minimum energy of interval.
1037  *
1038  * @exception GException::out_of_range
1039  * Specified index is out of range.
1040  ***************************************************************************/
1041 GEnergy GEbounds::emin(const int& index) const
1042 {
1043  #if defined(G_RANGE_CHECK)
1044  // Throw an exception if index is outside valid range
1045  if (index < 0 || index >= m_num) {
1047  "Minimum energy of interval",
1048  index, m_num);
1049  }
1050  #endif
1051 
1052  // Return minimum energy
1053  return (m_min[index]);
1054 }
1055 
1056 
1057 /***********************************************************************//**
1058  * @brief Returns maximum energy for a given energy interval
1059  *
1060  * @param[in] index Energy interval index (0,...,size()-1).
1061  * @return Maximum energy of interval.
1062  *
1063  * @exception GException::out_of_range
1064  * Specified index is out of range.
1065  ***************************************************************************/
1066 GEnergy GEbounds::emax(const int& index) const
1067 {
1068  #if defined(G_RANGE_CHECK)
1069  // Throw an exception if index is outside valid range
1070  if (index < 0 || index >= m_num) {
1072  "Maximum energy of interval",
1073  index, m_num);
1074  }
1075  #endif
1076 
1077  // Return maximum energy
1078  return (m_max[index]);
1079 }
1080 
1081 
1082 /***********************************************************************//**
1083  * @brief Returns mean energy for a given energy interval
1084  *
1085  * @param[in] index Energy interval index [0,...,size()[.
1086  * @return Mean energy of interval.
1087  *
1088  * @exception GException::out_of_range
1089  * Specified index is out of range.
1090  *
1091  * Computes the mean energy
1092  * \f$0.5 * (E_{\rm min} + E_{\rm max})\f$
1093  * for the energy interval @p index.
1094  ***************************************************************************/
1095 GEnergy GEbounds::emean(const int& index) const
1096 {
1097  #if defined(G_RANGE_CHECK)
1098  // If index is outside boundary then throw an error
1099  if (index < 0 || index >= m_num) {
1100  throw GException::out_of_range(G_EMEAN, "Energy interval index",
1101  index, m_num);
1102  }
1103  #endif
1104 
1105  // Compute mean energy
1106  GEnergy emean = 0.5 * (m_min[index] + m_max[index]);
1107 
1108  // Return
1109  return emean;
1110 }
1111 
1112 
1113 /***********************************************************************//**
1114  * @brief Returns logarithmic mean energy for a given energy interval
1115  *
1116  * @param[in] index Energy interval index [0,...,size()[.
1117  * @return Logarithmic mean energy of interval.
1118  *
1119  * @exception GException::out_of_range
1120  * Specified index is out of range.
1121  *
1122  * Computes the logarithmic mean energy
1123  * \f$10^{0.5 * (\log E_{\rm min} + \log E_{\rm max})}\f$
1124  * for the energy interval @p index.
1125  ***************************************************************************/
1126 GEnergy GEbounds::elogmean(const int& index) const
1127 {
1128  #if defined(G_RANGE_CHECK)
1129  // If index is outside boundary then throw an error
1130  if (index < 0 || index >= m_num) {
1131  throw GException::out_of_range(G_ELOGMEAN, "Energy interval index",
1132  index, m_num);
1133  }
1134  #endif
1135 
1136  // Compute logarithmic mean energy
1137  GEnergy elogmean;
1138  elogmean.MeV(std::sqrt(m_min[index].MeV() * m_max[index].MeV()));
1139 
1140  // Return
1141  return elogmean;
1142 }
1143 
1144 
1145 /***********************************************************************//**
1146  * @brief Returns energy interval width
1147  *
1148  * @param[in] index Energy interval index [0,...,size()[.
1149  * @return Energy interval width.
1150  *
1151  * @exception GException::out_of_range
1152  * Specified index is out of range.
1153  ***************************************************************************/
1154 GEnergy GEbounds::ewidth(const int& index) const
1155 {
1156  #if defined(G_RANGE_CHECK)
1157  // If index is outside boundary then throw an error
1158  if (index < 0 || index >= m_num) {
1159  throw GException::out_of_range(G_EWIDTH, "Energy interval index",
1160  index, m_num);
1161  }
1162  #endif
1163 
1164  // Return
1165  return (m_max[index]-m_min[index]);
1166 }
1167 
1168 
1169 
1170 
1171 /***********************************************************************//**
1172  * @brief Checks whether energy boundaries contain energy
1173  *
1174  * @param[in] eng Energy to be checked.
1175  * @return True if energy falls in at least one interval, false otherwise.
1176  *
1177  * Checks if the energy @p eng falls in at least one of the energy intervals.
1178  * The method exits when the first matching interval has been found.
1179  ***************************************************************************/
1180 bool GEbounds::contains(const GEnergy& eng) const
1181 {
1182  // Initialise test
1183  bool found = false;
1184 
1185  // Test all energy boundaries
1186  for (int i = 0; i < m_num; ++i) {
1187  if (eng >= m_min[i] && eng <= m_max[i]) {
1188  found = true;
1189  break;
1190  }
1191  }
1192 
1193  // Return result
1194  return found;
1195 }
1196 
1197 
1198 /***********************************************************************//**
1199  * @brief Checks whether energy boundaries contain and energy bin
1200  *
1201  * @param[in] emin Minimum energy of bin to be checked.
1202  * @param[in] emax Maximum energy of bin to be checked.
1203  * @return True if energy bin [emin, emax] is fully contained inside energy
1204  * the boundaries, false otherwiese
1205  *
1206  * Checks if the energy interval [@p emin, @p emax ] falls is fully contained
1207  * by energy boundaries
1208  *
1209  * @todo This method is so far only correct for contiguous energy boundaries.
1210  ***************************************************************************/
1211 bool GEbounds::contains(const GEnergy& emin, const GEnergy& emax) const
1212 {
1213  // Initialise result
1214  bool contained = false;
1215 
1216  // Check if emin, emax is fully contained within this ebounds
1217  if (emin >= m_emin && emax <= m_emax) {
1218  contained = true;
1219  }
1220 
1221  // Return result
1222  return contained;
1223 }
1224 
1225 
1226 /***********************************************************************//**
1227  * @brief Print energy boundaries
1228  *
1229  * @param[in] chatter Chattiness (defaults to NORMAL).
1230  * @return String containing energy boundary information.
1231  ***************************************************************************/
1232 std::string GEbounds::print(const GChatter& chatter) const
1233 {
1234  // Initialise result string
1235  std::string result;
1236 
1237  // Continue only if chatter is not silent
1238  if (chatter != SILENT) {
1239 
1240  // Append Header
1241  result.append("=== GEbounds ===");
1242 
1243  // Append information
1244  result.append("\n"+gammalib::parformat("Number of intervals"));
1245  result.append(gammalib::str(size()));
1246  result.append("\n"+gammalib::parformat("Energy range"));
1247  result.append(emin().print());
1248  result.append(" - ");
1249  result.append(emax().print());
1250 
1251  // If there are multiple energy bins then append them
1252  if (chatter >= EXPLICIT) {
1253  if (size() > 1) {
1254  for (int i = 0; i < size(); ++i) {
1255  result.append("\n");
1256  result.append(gammalib::parformat("Energy interval "+
1257  gammalib::str(i)));
1258  result.append(emin(i).print());
1259  result.append(" - ");
1260  result.append(emax(i).print());
1261  }
1262  }
1263  } // endif: chatter was less than explicit
1264 
1265  } // endif: chatter was not silent
1266 
1267  // Return
1268  return result;
1269 }
1270 
1271 
1272 /*==========================================================================
1273  = =
1274  = Private methods =
1275  = =
1276  ==========================================================================*/
1277 
1278 /***********************************************************************//**
1279  * @brief Initialise class members
1280  ***************************************************************************/
1282 {
1283  // Initialise members
1284  m_num = 0;
1285  m_emin.clear();
1286  m_emax.clear();
1287  m_min = NULL;
1288  m_max = NULL;
1289 
1290  // Return
1291  return;
1292 }
1293 
1294 
1295 /***********************************************************************//**
1296  * @brief Copy class members
1297  *
1298  * @param[in] ebds Energy boundaries.
1299  ***************************************************************************/
1301 {
1302  // Copy attributes
1303  m_num = ebds.m_num;
1304  m_emin = ebds.m_emin;
1305  m_emax = ebds.m_emax;
1306 
1307  // Copy arrays
1308  if (m_num > 0) {
1309  m_min = new GEnergy[m_num];
1310  m_max = new GEnergy[m_num];
1311  for (int i = 0; i < m_num; ++i) {
1312  m_min[i] = ebds.m_min[i];
1313  m_max[i] = ebds.m_max[i];
1314  }
1315  }
1316 
1317  // Return
1318  return;
1319 }
1320 
1321 
1322 /***********************************************************************//**
1323  * @brief Delete class members
1324  ***************************************************************************/
1326 {
1327  // Free memory
1328  if (m_min != NULL) delete [] m_min;
1329  if (m_max != NULL) delete [] m_max;
1330 
1331  // Signal free pointers
1332  m_min = NULL;
1333  m_max = NULL;
1334 
1335  // Return
1336  return;
1337 }
1338 
1339 
1340 /***********************************************************************//**
1341  * @brief Set class attributes
1342  *
1343  * Determines the minimum and maximum energy from all intervals. If no
1344  * interval is present the minimum and maximum energies are cleared.
1345  ***************************************************************************/
1347 {
1348  // If there are intervals then determine the minimum and maximum
1349  // energy from these intervals ...
1350  if (m_num > 0) {
1351  m_emin = m_min[0];
1352  m_emax = m_max[0];
1353  for (int i = 1; i < m_num; ++i) {
1354  if (m_min[i] < m_emin) m_emin = m_min[i];
1355  if (m_max[i] > m_emax) m_emax = m_max[i];
1356  }
1357  }
1358 
1359  // ... otherwise clear the minimum and maximum energy
1360  else {
1361  m_emin.clear();
1362  m_emax.clear();
1363  }
1364 
1365  // Return
1366  return;
1367 }
1368 
1369 
1370 /***********************************************************************//**
1371  * @brief Insert energy interval
1372  *
1373  * @param[in] index Index after with interval is inserted.
1374  * @param[in] emin Minimum energy of interval.
1375  * @param[in] emax Maximum energy of interval.
1376  *
1377  * @exception GException::invalid_argument
1378  * Minimum energy larger than maximum energy
1379  *
1380  * Inserts an energy interval after the specified @p index in the energy
1381  * boundaries. The method does not reorder the intervals by energy, instead
1382  * the client needs to determine the approriate @p index.
1383  *
1384  * Invalid parameters do not produce any exception, but are handled
1385  * transparently. If the interval is invalid (i.e. @p emin > @p emax) an
1386  * exception is thrown. If the @p index is out of the valid range, the
1387  * index will be adjusted to either the first or the last element.
1388  ***************************************************************************/
1389 void GEbounds::insert_eng(const int& index,
1390  const GEnergy& emin,
1391  const GEnergy& emax)
1392 {
1393  // Throw an exception if energy interval is invalid
1394  if (emin > emax) {
1395  std::string msg = "Invalid energy interval specified. Minimum"
1396  " energy "+emin.print(NORMAL)+" can not be"
1397  " larger than maximum energy "+
1398  emax.print(NORMAL)+".";
1400  }
1401 
1402  // Set index
1403  int inx = index;
1404 
1405  // If inx is out of range then adjust it
1406  if (inx < 0) inx = 0;
1407  if (inx > m_num) inx = m_num;
1408 
1409  // Allocate new intervals
1410  int num = m_num+1;
1411  GEnergy* min = new GEnergy[num];
1412  GEnergy* max = new GEnergy[num];
1413 
1414  // Copy intervals before index to be inserted
1415  for (int i = 0; i < inx; ++i) {
1416  min[i] = m_min[i];
1417  max[i] = m_max[i];
1418  }
1419 
1420  // Insert interval
1421  min[inx] = emin;
1422  max[inx] = emax;
1423 
1424  // Copy intervals after index to be inserted
1425  for (int i = inx+1; i < num; ++i) {
1426  min[i] = m_min[i-1];
1427  max[i] = m_max[i-1];
1428  }
1429 
1430  // Free memory
1431  if (m_min != NULL) delete [] m_min;
1432  if (m_max != NULL) delete [] m_max;
1433 
1434  // Set new memory
1435  m_min = min;
1436  m_max = max;
1437 
1438  // Set number of elements
1439  m_num = num;
1440 
1441  // Set attributes
1442  set_attributes();
1443 
1444  // Return
1445  return;
1446 }
1447 
1448 
1449 /*==========================================================================
1450  = =
1451  = Friends =
1452  = =
1453  ==========================================================================*/
1454 
1455 /***********************************************************************//**
1456  * @brief Energy boundaries equality operator friend
1457  *
1458  * @param[in] a First energy boundaries.
1459  * @param[in] b Second energy boundaries.
1460  * @return True if both energy boundaries are identical.
1461  ***************************************************************************/
1462 bool operator==(const GEbounds& a, const GEbounds& b)
1463 {
1464  // Initialise identify flag
1465  bool identity = true;
1466 
1467  // Check that both energy boundaries have the same size
1468  if (a.size() != b.size()) {
1469  identity = false;
1470  }
1471 
1472  // Check all energy boundaries
1473  else {
1474  for (int i = 0; i < a.size(); ++i) {
1475  if ((a.emin(i) != b.emin(i)) || (a.emax(i) != b.emax(i))) {
1476  identity = false;
1477  break;
1478  }
1479  }
1480  }
1481 
1482  // Return identity flag
1483  return identity;
1484 }
GEnergy * m_max
Array of interval maximum energies.
Definition: GEbounds.hpp:141
void unit(const std::string &unit)
Set column unit.
void init_members(void)
Initialise class members.
Definition: GEbounds.cpp:1281
FITS table double column class interface definition.
#define G_WRITE_XML
Definition: GEbounds.cpp:45
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition: GFits.cpp:482
bool contains(const int &extno) const
Check if HDU exists in FITS file.
Definition: GFits.hpp:282
void copy_members(const GEbounds &ebds)
Copy class members.
Definition: GEbounds.cpp:1300
GEnergy m_emin
Minimum energy of all intervals.
Definition: GEbounds.hpp:138
XML element node class interface definition.
GEbounds(void)
Constructor.
Definition: GEbounds.cpp:73
int size(void) const
Return number of energy boundaries.
Definition: GEbounds.hpp:163
void append(const GEnergy &emin, const GEnergy &emax)
Append energy interval.
Definition: GEbounds.cpp:301
GEbounds * clone(void) const
Clone energy boundaries.
Definition: GEbounds.cpp:286
#define G_REMOVE_INX
Definition: GEbounds.cpp:46
#define G_READ_XML
Definition: GEbounds.cpp:44
bool contains(const GEnergy &eng) const
Checks whether energy boundaries contain energy.
Definition: GEbounds.cpp:1180
void set_attributes(void)
Set class attributes.
Definition: GEbounds.cpp:1346
XML element node class.
Definition: GXmlElement.hpp:48
std::string extname(const std::string &defaultname="") const
Return extension name.
Definition: GFilename.cpp:385
GFitsTableCol * append(const GFitsTableCol &column)
Append column to the table.
Definition: GFitsTable.hpp:147
double MeV(void) const
Return energy in MeV.
Definition: GEnergy.cpp:321
void read(const GFitsTable &table)
Read energy boundaries from FITS table.
Definition: GEbounds.cpp:761
#define G_EMAX_SET
Definition: GEbounds.cpp:49
Gammalib tools definition.
FITS file class.
Definition: GFits.hpp:63
GEnergy emean(const int &index) const
Returns mean energy for a given energy interval.
Definition: GEbounds.cpp:1095
FITS file class interface definition.
double min(const GVector &vector)
Computes minimum vector element.
Definition: GVector.cpp:886
GEnergy ewidth(const int &index) const
Returns energy interval width.
Definition: GEbounds.cpp:1154
void write(GFits &file, const std::string &extname=gammalib::extname_ebounds, const std::string &unit="keV") const
Write energy boundaries into FITS object.
Definition: GEbounds.cpp:816
Energy container class.
Definition: GEnergies.hpp:60
int index(const GEnergy &eng) const
Returns energy bin index for a given energy.
Definition: GEbounds.cpp:948
double real(const std::string &keyname) const
Return card value as double precision.
Definition: GFitsHDU.hpp:423
int m_num
Number of energy boundaries.
Definition: GEbounds.hpp:137
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
Definition: GVector.cpp:1358
void extend(const GEbounds &ebds)
Append energy boundaries.
Definition: GEbounds.cpp:552
#define G_EMEAN
Definition: GEbounds.cpp:52
#define G_EWIDTH
Definition: GEbounds.cpp:54
void insert_eng(const int &index, const GEnergy &emin, const GEnergy &emax)
Insert energy interval.
Definition: GEbounds.cpp:1389
void insert(const GEnergy &emin, const GEnergy &emax)
Insert energy interval.
Definition: GEbounds.cpp:322
Energy boundaries container class.
Definition: GEbounds.hpp:60
#define G_INSERT_ENG
Definition: GEbounds.cpp:55
void remove(const int &extno)
Remove HDU from FITS file.
Definition: GFits.cpp:862
const GXmlAttribute * attribute(const int &index) const
Return attribute.
std::string print(const GChatter &chatter=NORMAL) const
Print energy.
Definition: GEnergy.cpp:748
void set(const GEnergies &energies)
Set energy boundaries from energy container.
Definition: GEbounds.cpp:618
Filename class.
Definition: GFilename.hpp:62
Energy container class definition.
const GEnergy & emin(void) const
Return minimum energy of all intervals.
Definition: GEbounds.hpp:187
bool has_attribute(const std::string &name) const
Check if element has a given attribute.
int size(void) const
Return number of energies in container.
Definition: GEnergies.hpp:170
GXmlElement * xml_need_par(const std::string &origin, GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
Definition: GTools.cpp:1637
bool is_empty(void) const
Signal if there are no energy boundaries.
Definition: GEbounds.hpp:175
const std::string extname_ebounds
Definition: GEbounds.hpp:44
Abstract interface for FITS table.
Definition: GFitsTable.hpp:44
std::string print(const GChatter &chatter=NORMAL) const
Print energy boundaries.
Definition: GEbounds.cpp:1232
GChatter
Definition: GTypemaps.hpp:33
GEnergy elogmean(const int &index) const
Returns logarithmic mean energy for a given energy interval.
Definition: GEbounds.cpp:1126
int integer(const std::string &keyname) const
Return card value as integer.
Definition: GFitsHDU.hpp:436
void reserve(const int &num)
Reserve space for energy intervals.
Definition: GEbounds.cpp:538
const std::string & extname(void) const
Return extension name.
Definition: GFitsHDU.hpp:162
void clear(void)
Clear energy boundaries.
Definition: GEbounds.cpp:268
double max(const GVector &vector)
Computes maximum vector element.
Definition: GVector.cpp:915
#define G_EMIN_GET
Definition: GEbounds.cpp:50
GEnergy * m_min
Array of interval minimum energies.
Definition: GEbounds.hpp:140
void free_members(void)
Delete class members.
Definition: GEbounds.cpp:1325
std::string url(void) const
Return Uniform Resource Locator (URL)
Definition: GFilename.hpp:189
GEnergy m_emax
Maximum energy of all intervals.
Definition: GEbounds.hpp:139
#define G_EMIN_SET
Definition: GEbounds.cpp:48
virtual ~GEbounds(void)
Destructor.
Definition: GEbounds.cpp:216
FITS binary table class.
Energy boundaries class interface definition.
void remove(const int &index)
Remove energy interval.
Definition: GEbounds.cpp:427
Exception handler interface definition.
GFitsHDU * append(const GFitsHDU &hdu)
Append HDU to FITS file.
Definition: GFits.cpp:678
FITS binary table class definition.
#define G_REMOVE_ENG
Definition: GEbounds.cpp:47
#define G_ELOGMEAN
Definition: GEbounds.cpp:53
const GEnergy & emax(void) const
Return maximum energy of all intervals.
Definition: GEbounds.hpp:199
bool operator==(const GEnergy &a, const GEnergy &b)
Energy equality operator friend.
Definition: GEnergy.hpp:297
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
#define G_EMAX_GET
Definition: GEbounds.cpp:51
void close(void)
Close FITS file.
Definition: GFits.cpp:1342
void save(const GFilename &filename, const bool &clobber=false, const std::string &unit="keV") const
Save energy boundaries into FITS file.
Definition: GEbounds.cpp:733
const GXmlElement * xml_get_par(const std::string &origin, const GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
Definition: GTools.cpp:1689
GEbounds & operator=(const GEbounds &ebds)
Assignment operator.
Definition: GEbounds.cpp:238
void clear(void)
Clear instance.
Definition: GEnergy.cpp:261
FITS table double column.
void merge(void)
Merge all overlapping or connecting successive energy intervals.
Definition: GEbounds.cpp:349
Filename class interface definition.
double todouble(const std::string &arg)
Convert string into double precision value.
Definition: GTools.cpp:926
Class that handles energies in a unit independent way.
Definition: GEnergy.hpp:48
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489
FITS table abstract base class interface definition.
void load(const GFilename &filename)
Load energy boundaries from FITS file.
Definition: GEbounds.cpp:689