GammaLib 2.0.0
Loading...
Searching...
No Matches
GEnergy.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GEnergy.cpp - Energy class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-2014 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 GEnergy.cpp
23 * @brief Energy value class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <cfloat>
32#include <cmath>
33#include "GEnergy.hpp"
34#include "GTools.hpp"
35#include "GException.hpp"
36
37/* __ Constants __________________________________________________________ */
38
39/* __ Method name definitions ____________________________________________ */
40#define G_CONSTRUCT "GEnergy::GEnergy(double&, std::string&)"
41#define G_OPERATOR1 "GEnergy::operator()(double&, std::string&)"
42#define G_OPERATOR2 "GEnergy::operator()(std::string&)"
43#define G_ANGSTROM_GET "GEnergy::Angstrom()"
44#define G_ANGSTROM_SET "GEnergy::Angstrom(double&)"
45#define G_LOG10_GET "GEnergy::log10(std::string&)"
46#define G_LOG10_SET "GEnergy::log10(double&, std::string&)"
47
48/* __ Macros _____________________________________________________________ */
49
50/* __ Coding definitions _________________________________________________ */
51
52/* __ Debug definitions __________________________________________________ */
53
54
55/*==========================================================================
56 = =
57 = Constructors/destructors =
58 = =
59 ==========================================================================*/
60
61/***********************************************************************//**
62 * @brief Void constructor
63 ***************************************************************************/
65{
66 // Initialise private members
68
69 // Return
70 return;
71}
72
73
74/***********************************************************************//**
75 * @brief Copy constructor
76 *
77 * @param[in] eng Energy.
78 ***************************************************************************/
80{
81 // Initialise private members
83
84 // Copy members
85 copy_members(eng);
86
87 // Return
88 return;
89}
90
91
92/***********************************************************************//**
93 * @brief Energy constructor
94 *
95 * @param[in] eng Energy.
96 * @param[in] unit Energy unit (one of erg(s), keV, MeV, GeV, TeV).
97 *
98 * Construct energy from an energy value and unit. The constructor interprets
99 * the unit string and performs automatic conversion of the energy value.
100 ***************************************************************************/
101GEnergy::GEnergy(const double& eng, const std::string& unit)
102{
103 // Initialise private members
104 init_members();
105
106 // Set energy according to unit string
107 this->operator()(eng, unit);
108
109 // Return
110 return;
111}
112
113
114/***********************************************************************//**
115 * @brief Destructor
116 ***************************************************************************/
118{
119 // Free members
120 free_members();
121
122 // Return
123 return;
124}
125
126
127/*==========================================================================
128 = =
129 = Operators =
130 = =
131 ==========================================================================*/
132
133/***********************************************************************//**
134 * @brief Assignment operator
135 *
136 * @param[in] eng Energy.
137 * @return Energy.
138 ***************************************************************************/
140{
141 // Execute only if object is not identical
142 if (this != &eng) {
143
144 // Free members
145 free_members();
146
147 // Initialise private members for clean destruction
148 init_members();
149
150 // Copy members
151 copy_members(eng);
152
153 } // endif: object was not identical
154
155 // Return
156 return *this;
157}
158
159
160/***********************************************************************//**
161 * @brief Unit set operator
162 *
163 * @param[in] eng Energy.
164 * @param[in] unit Energy unit (one of erg(s), keV, MeV, GeV, TeV, Angstrom).
165 *
166 * @exception GException::invalid_argument
167 * Invalid energy unit specified.
168 *
169 * Construct energy from an energy value and unit. The constructor interprets
170 * the unit string and performs automatic conversion of the energy value.
171 ***************************************************************************/
172void GEnergy::operator()(const double& eng, const std::string& unit)
173{
174 // Set energy according to unit string
175 std::string eunit = gammalib::strip_whitespace(gammalib::tolower(unit));
176 if (eunit == "erg" || eunit == "ergs") {
177 this->erg(eng);
178 }
179 else if (eunit == "kev") {
180 this->keV(eng);
181 }
182 else if (eunit == "mev") {
183 this->MeV(eng);
184 }
185 else if (eunit == "gev") {
186 this->GeV(eng);
187 }
188 else if (eunit == "tev") {
189 this->TeV(eng);
190 }
191 else if (eunit == "angstrom") {
192 this->Angstrom(eng);
193 }
194 else {
196 "Valid energy units are \"erg(s)\", \"keV\", \"MeV\","
197 " \"GeV\", \"TeV\", or \"Angstrom\" (case insensitive).");
198 }
199
200 // Return
201 return;
202}
203
204
205/***********************************************************************//**
206 * @brief Unit access operator
207 *
208 * @param[in] unit Energy unit (one of erg(s), keV, MeV, GeV, TeV, Angstrom).
209 * @return Energy in requested units.
210 *
211 * @exception GException::invalid_argument
212 * Invalid energy unit specified.
213 *
214 * Returns the energy in the requested units.
215 ***************************************************************************/
216double GEnergy::operator()(const std::string& unit) const
217{
218 // Initialise energy
219 double energy = 0.0;
220
221 // Set energy according to unit string
222 std::string eunit = gammalib::tolower(unit);
223 if (eunit == "erg" || eunit == "ergs") {
224 energy = this->erg();
225 }
226 else if (eunit == "kev") {
227 energy = this->keV();
228 }
229 else if (eunit == "mev") {
230 energy = this->MeV();
231 }
232 else if (eunit == "gev") {
233 energy = this->GeV();
234 }
235 else if (eunit == "tev") {
236 energy = this->TeV();
237 }
238 else if (eunit == "angstrom") {
239 energy = this->Angstrom();
240 }
241 else {
243 "Valid energy units are \"erg(s)\", \"keV\", \"MeV\","
244 " \"GeV\", \"TeV\", or \"Angstrom\" (case insensitive).");
245 }
246
247 // Return energy
248 return energy;
249}
250
251
252/*==========================================================================
253 = =
254 = Public methods =
255 = =
256 ==========================================================================*/
257
258/***********************************************************************//**
259 * @brief Clear instance
260 ***************************************************************************/
262{
263 // Free members
264 free_members();
265
266 // Initialise private members
267 init_members();
268
269 // Return
270 return;
271}
272
273
274/***********************************************************************//**
275 * @brief Clone object
276 *
277 * @return Pointer to deep copy of energy.
278 ***************************************************************************/
280{
281 // Clone this image
282 return new GEnergy(*this);
283}
284
285
286/***********************************************************************//**
287 * @brief Return energy in erg
288 *
289 * @return Energy in erg.
290 ***************************************************************************/
291double GEnergy::erg(void) const
292{
293 // Compute energy
294 double energy = m_energy * gammalib::MeV2erg;
295
296 // Return energy
297 return energy;
298}
299
300
301/***********************************************************************//**
302 * @brief Return energy in keV
303 *
304 * @return Energy in keV.
305 ***************************************************************************/
306double GEnergy::keV(void) const
307{
308 // Compute energy
309 double energy = m_energy * 1.0e+3;
310
311 // Return energy
312 return energy;
313}
314
315
316/***********************************************************************//**
317 * @brief Return energy in MeV
318 *
319 * @return Energy in MeV.
320 ***************************************************************************/
321double GEnergy::MeV(void) const
322{
323 // Return energy
324 return m_energy;
325}
326
327
328/***********************************************************************//**
329 * @brief Return energy in GeV
330 *
331 * @return Energy in GeV.
332 ***************************************************************************/
333double GEnergy::GeV(void) const
334{
335 // Compute energy
336 double energy = m_energy * 1.0e-3;
337
338 // Return energy
339 return energy;
340}
341
342
343/***********************************************************************//**
344 * @brief Return energy in TeV
345 *
346 * @return Energy in TeV.
347 ***************************************************************************/
348double GEnergy::TeV(void) const
349{
350 // Compute energy
351 double energy = m_energy * 1.0e-6;
352
353 // Return energy
354 return energy;
355}
356
357
358/***********************************************************************//**
359 * @brief Return energy as wavelength in Angstrom
360 *
361 * @return Energy as wavelength in Angstrom (1e-10 metres).
362 *
363 * @exception GException::invalid_value
364 * Cannot convert zero energy into a wavelength.
365 ***************************************************************************/
366double GEnergy::Angstrom(void) const
367{
368 // Throw exception if energy is zero
369 if (m_energy == 0) {
371 "Cannot convert energy of 0 MeV into Angstrom.");
372 }
373
374 // Compute wavelength
375 double wavelength = gammalib::MeV2Angstrom/m_energy;
376
377 // Return wavelength in Angstrom
378 return wavelength;
379}
380
381
382/***********************************************************************//**
383 * @brief Return log10 of energy in erg
384 *
385 * @return Energy in log10 erg.
386 *
387 * Returns the log10 of the energy in erg.
388 ***************************************************************************/
389double GEnergy::log10erg(void) const
390{
391 // Set offset
392 const double offset = std::log10(gammalib::MeV2erg);
393
394 // Return log10 energy
395 return (log10MeV()+offset);
396}
397
398
399/***********************************************************************//**
400 * @brief Return log10 of energy in keV
401 *
402 * @return Energy in log10 keV.
403 *
404 * Returns the log10 of the energy in keV.
405 ***************************************************************************/
406double GEnergy::log10keV(void) const
407{
408 // Return log10 energy
409 return (log10MeV()+3.0);
410}
411
412
413/***********************************************************************//**
414 * @brief Return log10 of energy in MeV
415 *
416 * @return Energy in log10 MeV.
417 *
418 * Returns the log10 of the energy in MeV. The result is stored internally
419 * and not recomputed when the method is called again with the same energy
420 * value. This speeds up computation. In case that the energy is not positive
421 * the method returns DBL_MIN.
422 ***************************************************************************/
423double GEnergy::log10MeV(void) const
424{
425 // If required compute log10 of energy.
426 if (!m_has_log10) {
427 m_elog10 = (m_energy > 0.0) ? std::log10(m_energy) : DBL_MIN;
428 m_has_log10 = true;
429 }
430
431 // Return log10 energy
432 return m_elog10;
433}
434
435
436/***********************************************************************//**
437 * @brief Return log10 of energy in GeV
438 *
439 * @return Energy in log10 GeV.
440 *
441 * Returns the log10 of the energy in GeV.
442 ***************************************************************************/
443double GEnergy::log10GeV(void) const
444{
445 // Return log10 energy
446 return (log10MeV()-3.0);
447}
448
449
450/***********************************************************************//**
451 * @brief Return log10 of energy in TeV
452 *
453 * @return Energy in log10 TeV.
454 *
455 * Returns the log10 of the energy in TeV.
456 ***************************************************************************/
457double GEnergy::log10TeV(void) const
458{
459 // Return log10 energy
460 return (log10MeV()-6.0);
461}
462
463
464/***********************************************************************//**
465 * @brief Set log10 of energy with unit specification
466 *
467 * @param[in] unit Unit of log10 of energy.
468 * @return eng log10 of energy.
469 *
470 * @exception GException::invalid_argument
471 * Unit argument is not valid.
472 ***************************************************************************/
473double GEnergy::log10(const std::string& unit) const
474{
475 // Initialise result
476 double logE = 0.0;
477
478 // Set energy according to unit string
479 std::string eunit = gammalib::tolower(unit);
480 if (eunit == "erg" || eunit == "ergs") {
481 logE = this->log10erg();
482 }
483 else if (eunit == "kev") {
484 logE = this->log10keV();
485 }
486 else if (eunit == "mev") {
487 logE = this->log10MeV();
488 }
489 else if (eunit == "gev") {
490 logE = this->log10GeV();
491 }
492 else if (eunit == "tev") {
493 logE = this->log10TeV();
494 }
495 else {
497 "Valid energy units are \"erg(s)\", \"keV\", \"MeV\","
498 " \"GeV\", or \"TeV\" (case insensitive).");
499 }
500
501 // Return
502 return logE;
503}
504
505
506/***********************************************************************//**
507 * @brief Set energy in erg
508 *
509 * @param[in] eng Energy in erg.
510 ***************************************************************************/
511void GEnergy::erg(const double& eng)
512{
513 // Set energy
515
516 // Signals that log10 of energy is not valid
517 m_has_log10 = false;
518
519 // Return
520 return;
521}
522
523
524/***********************************************************************//**
525 * @brief Set energy in keV
526 *
527 * @param[in] eng Energy in keV.
528 ***************************************************************************/
529void GEnergy::keV(const double& eng)
530{
531 // Set energy
532 m_energy = eng * 1.0e-3;
533
534 // Signals that log10 of energy is not valid
535 m_has_log10 = false;
536
537 // Return
538 return;
539}
540
541
542/***********************************************************************//**
543 * @brief Set energy in MeV
544 *
545 * @param[in] eng Energy in MeV.
546 ***************************************************************************/
547void GEnergy::MeV(const double& eng)
548{
549 // Set energy
550 m_energy = eng;
551
552 // Signals that log10 of energy is not valid
553 m_has_log10 = false;
554
555 // Return
556 return;
557}
558
559
560/***********************************************************************//**
561 * @brief Set energy in GeV
562 *
563 * @param[in] eng Energy in GeV.
564 ***************************************************************************/
565void GEnergy::GeV(const double& eng)
566{
567 // Set energy
568 m_energy = eng * 1.0e+3;
569
570 // Signals that log10 of energy is not valid
571 m_has_log10 = false;
572
573 // Return
574 return;
575}
576
577
578/***********************************************************************//**
579 * @brief Set energy in TeV
580 *
581 * @param[in] eng Energy in TeV.
582 ***************************************************************************/
583void GEnergy::TeV(const double& eng)
584{
585 // Set energy
586 m_energy = eng * 1.0e+6;
587
588 // Signals that log10 of energy is not valid
589 m_has_log10 = false;
590
591 // Return
592 return;
593}
594
595
596/***********************************************************************//**
597 * @brief Set energy from wavelength in Angstrom
598 *
599 * @param[in] wavelength Wavelength in Angstrom.
600 *
601 * @exception GException::invalid_argument
602 * Cannot set energy from zero wavelength.
603 ***************************************************************************/
604void GEnergy::Angstrom(const double& wavelength)
605{
606 // Throw exception if wavelength is zero
607 if (wavelength == 0) {
609 "Cannot set energy from a wavelength that is zero.");
610 }
611
612 // Set energy
613 m_energy = gammalib::MeV2Angstrom / wavelength;
614
615 // Signals that log10 of energy is not valid
616 m_has_log10 = false;
617
618 // Return
619 return;
620}
621
622
623/***********************************************************************//**
624 * @brief Set log10 of energy in erg
625 *
626 * @param[in] eng log10 of energy in erg.
627 ***************************************************************************/
628void GEnergy::log10erg(const double& eng)
629{
630 // Set offset
631 const double offset = std::log10(gammalib::MeV2erg);
632
633 // Set energy
634 log10MeV(eng-offset);
635
636 // Return
637 return;
638}
639
640
641/***********************************************************************//**
642 * @brief Set log10 of energy in keV
643 *
644 * @param[in] eng log10 of energy in keV.
645 ***************************************************************************/
646void GEnergy::log10keV(const double& eng)
647{
648 // Set energy
649 log10MeV(eng-3.0);
650
651 // Return
652 return;
653}
654
655
656/***********************************************************************//**
657 * @brief Set log10 of energy in MeV
658 *
659 * @param[in] eng log10 of energy in MeV.
660 ***************************************************************************/
661void GEnergy::log10MeV(const double& eng)
662{
663 // Set energy
664 m_elog10 = eng;
665 m_energy = std::pow(10.0, eng);
666 m_has_log10 = true;
667
668 // Return
669 return;
670}
671
672
673/***********************************************************************//**
674 * @brief Set log10 of energy in GeV
675 *
676 * @param[in] eng log10 of energy in GeV.
677 ***************************************************************************/
678void GEnergy::log10GeV(const double& eng)
679{
680 // Set energy
681 log10MeV(eng+3.0);
682
683 // Return
684 return;
685}
686
687
688/***********************************************************************//**
689 * @brief Set log10 of energy in TeV
690 *
691 * @param[in] eng log10 of energy in TeV.
692 ***************************************************************************/
693void GEnergy::log10TeV(const double& eng)
694{
695 // Set energy
696 log10MeV(eng+6.0);
697
698 // Return
699 return;
700}
701
702
703/***********************************************************************//**
704 * @brief Set log10 of energy with unit specification
705 *
706 * @param[in] eng log10 of energy.
707 * @param[in] unit Unit of log10 of energy.
708 *
709 * @exception GException::invalid_argument
710 * Unit argument is not valid.
711 ***************************************************************************/
712void GEnergy::log10(const double& eng, const std::string& unit)
713{
714 // Set energy according to unit string
715 std::string eunit = gammalib::tolower(unit);
716 if (eunit == "erg" || eunit == "ergs") {
717 this->log10erg(eng);
718 }
719 else if (eunit == "kev") {
720 this->log10keV(eng);
721 }
722 else if (eunit == "mev") {
723 this->log10MeV(eng);
724 }
725 else if (eunit == "gev") {
726 this->log10GeV(eng);
727 }
728 else if (eunit == "tev") {
729 this->log10TeV(eng);
730 }
731 else {
733 "Valid energy units are \"erg(s)\", \"keV\", \"MeV\","
734 " \"GeV\", or \"TeV\" (case insensitive).");
735 }
736
737 // Return
738 return;
739}
740
741
742/***********************************************************************//**
743 * @brief Print energy
744 *
745 * @param[in] chatter Chattiness (defaults to NORMAL).
746 * @return String containing energy information.
747 ***************************************************************************/
748std::string GEnergy::print(const GChatter& chatter) const
749{
750 // Initialise result string
751 std::string result;
752
753 // Continue only if chatter is not silent
754 if (chatter != SILENT) {
755
756 // Append energy
757 if (TeV() >= 1000.0) {
758 result.append(gammalib::str(TeV()/1000.0)+" PeV");
759 }
760 else if (GeV() >= 1000.0) {
761 result.append(gammalib::str(TeV())+" TeV");
762 }
763 else if (MeV() >= 1000.0) {
764 result.append(gammalib::str(GeV())+" GeV");
765 }
766 else if (keV() >= 1000.0) {
767 result.append(gammalib::str(MeV())+" MeV");
768 }
769 else {
770 result.append(gammalib::str(keV())+" keV");
771 }
772
773 // VERBOSE: append energy and log10 energy
774 if (chatter == VERBOSE) {
775 result.append(" (E="+gammalib::str(m_energy));
776 if (m_has_log10) {
777 result.append(", log10(E)="+gammalib::str(m_elog10)+")");
778 }
779 else {
780 result.append(", no log10(E) value)");
781 }
782 }
783
784 } // endif: chatter was not silent
785
786 // Return
787 return result;
788}
789
790
791/*==========================================================================
792 = =
793 = Private methods =
794 = =
795 ==========================================================================*/
796
797/***********************************************************************//**
798 * @brief Initialise class members
799 ***************************************************************************/
801{
802 // Initialise members
803 m_energy = 0.0;
804 m_elog10 = DBL_MIN;
805 m_has_log10 = false;
806
807 // Return
808 return;
809}
810
811
812/***********************************************************************//**
813 * @brief Copy class members
814 *
815 * @param[in] eng Energy.
816 ***************************************************************************/
818{
819 // Copy time
820 m_energy = eng.m_energy;
821 m_elog10 = eng.m_elog10;
823
824 // Return
825 return;
826}
827
828
829/***********************************************************************//**
830 * @brief Delete class members
831 ***************************************************************************/
833{
834 // Return
835 return;
836}
#define G_ANGSTROM_GET
Definition GEnergy.cpp:43
#define G_OPERATOR1
Definition GEnergy.cpp:41
#define G_LOG10_SET
Definition GEnergy.cpp:46
#define G_OPERATOR2
Definition GEnergy.cpp:42
#define G_LOG10_GET
Definition GEnergy.cpp:45
#define G_ANGSTROM_SET
Definition GEnergy.cpp:44
Energy value class definition.
Exception handler interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
@ VERBOSE
Definition GTypemaps.hpp:38
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
double log10(const std::string &unit) const
Set log10 of energy with unit specification.
Definition GEnergy.cpp:473
double GeV(void) const
Return energy in GeV.
Definition GEnergy.cpp:333
double Angstrom(void) const
Return energy as wavelength in Angstrom.
Definition GEnergy.cpp:366
double m_energy
Energy in MeV.
Definition GEnergy.hpp:117
double keV(void) const
Return energy in keV.
Definition GEnergy.cpp:306
void operator()(const double &eng, const std::string &unit)
Unit set operator.
Definition GEnergy.cpp:172
double log10TeV(void) const
Return log10 of energy in TeV.
Definition GEnergy.cpp:457
double log10GeV(void) const
Return log10 of energy in GeV.
Definition GEnergy.cpp:443
double MeV(void) const
Return energy in MeV.
Definition GEnergy.cpp:321
double log10MeV(void) const
Return log10 of energy in MeV.
Definition GEnergy.cpp:423
void free_members(void)
Delete class members.
Definition GEnergy.cpp:832
GEnergy(void)
Void constructor.
Definition GEnergy.cpp:64
void copy_members(const GEnergy &eng)
Copy class members.
Definition GEnergy.cpp:817
std::string print(const GChatter &chatter=NORMAL) const
Print energy.
Definition GEnergy.cpp:748
double log10keV(void) const
Return log10 of energy in keV.
Definition GEnergy.cpp:406
GEnergy & operator=(const GEnergy &eng)
Assignment operator.
Definition GEnergy.cpp:139
void clear(void)
Clear instance.
Definition GEnergy.cpp:261
double TeV(void) const
Return energy in TeV.
Definition GEnergy.cpp:348
double erg(void) const
Return energy in erg.
Definition GEnergy.cpp:291
double log10erg(void) const
Return log10 of energy in erg.
Definition GEnergy.cpp:389
void init_members(void)
Initialise class members.
Definition GEnergy.cpp:800
virtual ~GEnergy(void)
Destructor.
Definition GEnergy.cpp:117
bool m_has_log10
log10 of energy is valid
Definition GEnergy.hpp:119
GEnergy * clone(void) const
Clone object.
Definition GEnergy.cpp:279
double m_elog10
log10 of energy in MeV
Definition GEnergy.hpp:118
const double erg2MeV
Definition GTools.hpp:46
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
std::string tolower(const std::string &s)
Convert string to lower case.
Definition GTools.cpp:955
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
Definition GTools.cpp:80
const double MeV2Angstrom
Definition GTools.hpp:47
const double MeV2erg
Definition GTools.hpp:45