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