GammaLib 2.0.0
Loading...
Searching...
No Matches
GTimeReference.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GTimeReference.cpp - Time reference class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2012-2021 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 GTimeReference.cpp
23 * @brief Time reference class interface implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GTimeReference.hpp"
32#include "GTools.hpp"
33#include "GException.hpp"
34#include "GFitsHDU.hpp"
35#include "GXmlElement.hpp"
36
37/* __ Constants __________________________________________________________ */
38
39/* __ Method name definitions ____________________________________________ */
40#define G_READ "GTimeReference::read(GFitsHDU&)"
41#define G_READ_XML "GTimeReference::read(GXmlElement&)"
42#define G_WRITE_XML "GTimeReference::write(GXmlElement&)"
43#define G_SET "GTimeReference::set(double&, std::string&, std::string&, "\
44 "std::string&)"
45
46/* __ Macros _____________________________________________________________ */
47
48/* __ Coding definitions _________________________________________________ */
49
50/* __ Debug definitions __________________________________________________ */
51
52
53/*==========================================================================
54 = =
55 = Constructors/destructors =
56 = =
57 ==========================================================================*/
58
59/***********************************************************************//**
60 * @brief Void constructor
61 ***************************************************************************/
63{
64 // Initialise private members
66
67 // Return
68 return;
69}
70
71
72/***********************************************************************//**
73 * @brief Copy constructor
74 *
75 * @param[in] ref Time reference.
76 ***************************************************************************/
78{
79 // Initialise private members
81
82 // Copy members
83 copy_members(ref);
84
85 // Return
86 return;
87}
88
89
90/***********************************************************************//**
91 * @brief Time reference constructor
92 *
93 * @param[in] mjdref Reference MJD (days).
94 * @param[in] timeunit Time unit ("sec(s)", "day(s)").
95 * @param[in] timesys Time system (ignored so far).
96 * @param[in] timeref Time reference (ignored so far).
97 *
98 * Sets the time reference from a MJD reference day, a time unit, a time
99 * system and a time reference.
100 ***************************************************************************/
102 const std::string& timeunit,
103 const std::string& timesys,
104 const std::string& timeref)
105{
106 // Initialise private members
107 init_members();
108
109 // Set time reference
111
112 // Return
113 return;
114}
115
116
117/***********************************************************************//**
118 * @brief Time reference constructor
119 *
120 * @param[in] mjdrefi Integer part of reference MJD (days).
121 * @param[in] mjdreff Fractional part of reference MJD (days).
122 * @param[in] timeunit Time unit (sec, days).
123 * @param[in] timesys Time system (TT).
124 * @param[in] timeref Local time reference.
125 *
126 * Sets the time reference from a MJD reference day (specified by an integer
127 * and a fractional part), a time unit, a time system and a time reference.
128 ***************************************************************************/
130 const double& mjdreff,
131 const std::string& timeunit,
132 const std::string& timesys,
133 const std::string& timeref)
134{
135 // Initialise private members
136 init_members();
137
138 // Set time reference
140
141 // Return
142 return;
143}
144
145
146/***********************************************************************//**
147 * @brief FITS header constructor
148 *
149 * @param[in] hdu FITS extension.
150 *
151 * Constructs time reference from the information found in the FITS header.
152 * See GTimeReference::read for more information on the expected format.
153 ***************************************************************************/
155{
156 // Initialise private members
157 init_members();
158
159 // Read reference from FITS header
160 read(hdu);
161
162 // Return
163 return;
164}
165
166
167/***********************************************************************//**
168 * @brief Destructor
169 ***************************************************************************/
171{
172 // Free members
173 free_members();
174
175 // Return
176 return;
177}
178
179
180/*==========================================================================
181 = =
182 = Operators =
183 = =
184 ==========================================================================*/
185
186/***********************************************************************//**
187 * @brief Assignment operator
188 *
189 * @param[in] ref Time reference.
190 ***************************************************************************/
192{
193 // Execute only if object is not identical
194 if (this != &ref) {
195
196 // Free members
197 free_members();
198
199 // Initialise private members
200 init_members();
201
202 // Copy members
203 copy_members(ref);
204
205 } // endif: object was not identical
206
207 // Return
208 return *this;
209}
210
211
212/*==========================================================================
213 = =
214 = Public methods =
215 = =
216 ==========================================================================*/
217
218/***********************************************************************//**
219 * @brief Clear time reference
220 ***************************************************************************/
222{
223 // Free members
224 free_members();
225
226 // Initialise members
227 init_members();
228
229 // Return
230 return;
231}
232
233
234/***********************************************************************//**
235 * @brief Clone object
236 *
237 * @return Pointer to deep copy of time reference.
238 ***************************************************************************/
240{
241 // Clone this image
242 return new GTimeReference(*this);
243}
244
245
246/***********************************************************************//**
247 * @brief Read time reference from FITS header
248 *
249 * @param[in] hdu FITS extension.
250 *
251 * GException::invalid_value
252 * No valid reference MJD found in header.
253 *
254 * Reads the time reference information from a FITS header. The method
255 * requires either the keyword "MJDREF" or the pair of keywords "MJDREFI"
256 * and "MJDREFF" to be set. The following keywords are optional (the
257 * assumed default values in absent of the keywords is given in parentheses):
258 *
259 * TIMEUNIT ("s")
260 * TIMESYS ("TT")
261 * TIMEREF ("LOCAL")
262 *
263 ***************************************************************************/
265{
266 // Get reference MJD
267 double mjdref = (hdu.has_card("MJDREF")) ? hdu.real("MJDREF") : 0.0;
268 int mjdrefi = (hdu.has_card("MJDREFI")) ? hdu.integer("MJDREFI") : 0;
269 double mjdreff = (hdu.has_card("MJDREFF")) ? hdu.real("MJDREFF") : 0.0;
270
271 // Get remaining keywords. To accept a large variety of FITS headers,
272 // all keywords are optionally.
273 std::string timeunit = (hdu.has_card("TIMEUNIT")) ? hdu.string("TIMEUNIT") : "s";
274 std::string timesys = (hdu.has_card("TIMESYS")) ? hdu.string("TIMESYS") : "TT";
275 std::string timeref = (hdu.has_card("TIMEREF")) ? hdu.string("TIMEREF") : "LOCAL";
276
277 // Set time reference
278 if (hdu.has_card("MJDREF")) {
280 }
281 else if (hdu.has_card("MJDREFI") && hdu.has_card("MJDREFF")) {
283 }
284 else {
285 std::string msg = "No valid time reference keywords found in FITS "
286 "header. The FITS header must contain either the "
287 "keyword \"MJDREF\" or the keyword pair"
288 " \"MJDREFI\" and \"MJDREFF\".";
290 }
291
292 // Return
293 return;
294}
295
296
297/***********************************************************************//**
298 * @brief Write time reference into FITS header
299 *
300 * @param[in] hdu FITS extension.
301 *
302 * Writes or updates the time reference information in a FITS header.
303 * Depending of whether the keyword "MJDREF" or the pair of keywords "MJDREFI"
304 * and "MJDREFF" exist already in the header, the method either writes the
305 * reference MJD as floating point value, or split into an integer and a
306 * fractional part. If nothing has been written yet, splitting into an
307 * integer and fractional part will be used as this preserves the highest
308 * possible accuracy.
309 *
310 * The following additional keywords are written:
311 * TIMEUNIT
312 * TIMESYS
313 * TIMEREF
314 *
315 ***************************************************************************/
317{
318 // Case A: use floating point reference MJD
319 if (hdu.has_card("MJDREF")) {
320 hdu.card("MJDREF", mjdref(), "[days] Time reference MJD");
321 hdu.card("TIMEUNIT", timeunit(), "Time unit");
322 hdu.card("TIMESYS", timesys(), "Time system");
323 hdu.card("TIMEREF", timeref(), "Time reference");
324 }
325
326 // Case B: use fractional reference MJD
327 else {
328 hdu.card("MJDREFI", mjdrefi(), "[days] Integer part of time reference MJD");
329 hdu.card("MJDREFF", mjdreff(), "[days] Fractional part of time reference MJD");
330 hdu.card("TIMEUNIT", timeunit(), "Time unit");
331 hdu.card("TIMESYS", timesys(), "Time system");
332 hdu.card("TIMEREF", timeref(), "Time reference");
333 }
334
335 // Return
336 return;
337}
338
339
340/***********************************************************************//**
341 * @brief Read time reference from XML element
342 *
343 * @param[in] xml XML element.
344 *
345 * @exception GException::invalid_value
346 * Invalid XML format encountered.
347 *
348 * Reads the time reference from an XML element. The format of the time
349 * reference is
350 *
351 * <parameter name="TimeReference" mjdrefi="..." mjdreff="..."
352 * timeunit="..." timesys="..." timeref="..."/>
353 *
354 ***************************************************************************/
356{
357 // Clear time reference
358 clear();
359
360 // Get time reference parameter
361 const GXmlElement* par = gammalib::xml_get_par(G_READ_XML, xml, "TimeReference");
362
363 // Initialise reference values
364 int mjdrefi;
365 double mjdreff;
366 std::string timeunit;
367 std::string timesys;
368 std::string timeref;
369
370 // Extract attributes
371 if (par->has_attribute("mjdrefi")) {
372 mjdrefi = gammalib::toint(par->attribute("mjdrefi"));
373 }
374 else {
375 std::string msg = "Attribute \"mjdrefi\" not found in XML parameter"
376 " \"TimeReference\"."
377 " Please verify the XML format.";
379 }
380 if (par->has_attribute("mjdreff")) {
381 mjdreff = gammalib::todouble(par->attribute("mjdreff"));
382 }
383 else {
384 std::string msg = "Attribute \"mjdreff\" not found in XML parameter"
385 " \"TimeReference\"."
386 " Please verify the XML format.";
388 }
389 if (par->has_attribute("timeunit")) {
390 timeunit = par->attribute("timeunit");
391 }
392 else {
393 std::string msg = "Attribute \"timeunit\" not found in XML parameter"
394 " \"TimeReference\"."
395 " Please verify the XML format.";
397 }
398 if (par->has_attribute("timesys")) {
399 timesys = par->attribute("timesys");
400 }
401 else {
402 std::string msg = "Attribute \"timesys\" not found in XML parameter"
403 " \"TimeReference\"."
404 " Please verify the XML format.";
406 }
407 if (par->has_attribute("timeref")) {
408 timeref = par->attribute("timeref");
409 }
410 else {
411 std::string msg = "Attribute \"timeref\" not found in XML parameter"
412 " \"TimeReference\"."
413 " Please verify the XML format.";
415 }
416
417 // Set time reference
419
420 // Return
421 return;
422}
423
424
425/***********************************************************************//**
426 * @brief Write time reference into XML element
427 *
428 * @param[in] xml XML element.
429 *
430 * Writes the time reference into an XML element. The format of the time
431 * reference is
432 *
433 * <parameter name="TimeReference" mjdrefi="..." mjdreff="..."
434 * timeunit="..." timesys="..." timeref="..."/>
435 *
436 ***************************************************************************/
438{
439 // Get parameter
440 GXmlElement* par = gammalib::xml_need_par(G_WRITE_XML, xml, "TimeReference");
441
442 // Write time reference
443 par->attribute("mjdrefi", gammalib::str(mjdrefi()));
444 par->attribute("mjdreff", gammalib::str(mjdreff()));
445 par->attribute("timeunit", timeunit());
446 par->attribute("timesys", timesys());
447 par->attribute("timeref", timeref());
448
449 // Return
450 return;
451}
452
453
454/***********************************************************************//**
455 * @brief Set time reference
456 *
457 * @param[in] mjdref Reference MJD (days).
458 * @param[in] timeunit Time unit ("s", "d", "sec(s)", "day(s)").
459 * @param[in] timesys Time system.
460 * @param[in] timeref Time reference.
461 *
462 * @exception GException::invalid_argument
463 * Invalid time unit specified.
464 *
465 * Sets the time reference from a MJD reference day, a time unit, a time
466 * system and a time reference.
467 *
468 * @todo Implement checking of "timesys" and "timeref" parameters.
469 ***************************************************************************/
470void GTimeReference::set(const double& mjdref,
471 const std::string& timeunit,
472 const std::string& timesys,
473 const std::string& timeref)
474{
475 // Check timeunit string
476 std::string ltimeunit = gammalib::tolower(timeunit);
477 if (ltimeunit == "d" || ltimeunit == "day" || ltimeunit == "days") {
478 m_unit_sec = false;
479 }
480 else if (ltimeunit == "s" || ltimeunit == "sec" || ltimeunit == "secs") {
481 m_unit_sec = true;
482 }
483 else {
484 std::string msg = "Invalid time unit \""+timeunit+"\" specified. "
485 "Please specify one of \"d\", \"day\", \"days\", "
486 "\"s\", \"sec\" or \"secs\"";
488 }
489
490 // Set members
492 m_timeunit = ltimeunit;
495
496 // Return
497 return;
498}
499
500
501/***********************************************************************//**
502 * @brief Set time reference
503 *
504 * @param[in] mjdrefi Integer part of reference MJD (days).
505 * @param[in] mjdreff Fractional part of reference MJD (days).
506 * @param[in] timeunit Time unit (sec, days).
507 * @param[in] timesys Time system (TT).
508 * @param[in] timeref Local time reference.
509 *
510 * Sets the time reference from a MJD reference day (specified by an integer
511 * and a fractional part), a time unit, a time system and a time reference.
512 ***************************************************************************/
513void GTimeReference::set(const int& mjdrefi,
514 const double& mjdreff,
515 const std::string& timeunit,
516 const std::string& timesys,
517 const std::string& timeref)
518{
519 // Compute reference MJD
520 double mjdref = double(mjdrefi) + mjdreff;
521
522 // Set time
524
525 // Return
526 return;
527}
528
529
530/***********************************************************************//**
531 * @brief Return MJD reference (units: days)
532 *
533 * @return Modified Julian reference day (days).
534 *
535 * Returns the Modified Julian reference day.
536 ***************************************************************************/
537const double& GTimeReference::mjdref(void) const
538{
539 // Return MDJ reference
540 return m_mjdref;
541}
542
543
544/***********************************************************************//**
545 * @brief Returns integer part of MJD reference (units: days)
546 *
547 * @return Integer part of Modified Julian reference day (days).
548 *
549 * Returns the integer part of the Modified Julian reference day.
550 ***************************************************************************/
552{
553 // Return integer part of MJD reference
554 return int(m_mjdref);
555}
556
557
558/***********************************************************************//**
559 * @brief Returns fractional part of MJD reference (units: days)
560 *
561 * @return Fractional part of Modified Julian reference day (days).
562 *
563 * Returns the fractional part of the Modified Julian reference day.
564 ***************************************************************************/
565double GTimeReference::mjdreff(void) const
566{
567 // Return fractional part of MJD reference
568 return (m_mjdref-double(mjdrefi()));
569}
570
571
572/***********************************************************************//**
573 * @brief Return time unit
574 *
575 * @return Time unit.
576 *
577 * Returns the reference time unit.
578 ***************************************************************************/
579const std::string& GTimeReference::timeunit(void) const
580{
581 // Return time unit
582 return m_timeunit;
583}
584
585
586/***********************************************************************//**
587 * @brief Return time system
588 *
589 * @return Time system.
590 *
591 * Returns the reference time system.
592 ***************************************************************************/
593const std::string& GTimeReference::timesys(void) const
594{
595 // Return time system
596 return m_timesys;
597}
598
599
600/***********************************************************************//**
601 * @brief Return time reference
602 *
603 * @return Time reference.
604 *
605 * Returns the reference time reference.
606 ***************************************************************************/
607const std::string& GTimeReference::timeref(void) const
608{
609 // Return time reference
610 return m_timeref;
611}
612
613
614/***********************************************************************//**
615 * @brief Return the time unit in seconds
616 *
617 * @return Time unit in seconds.
618 *
619 * Returns 1 if the time using is in seconds and 86400 if the time unit is
620 * in days.
621 ***************************************************************************/
623{
624 // Set time unit in seconds
625 double unit = (m_unit_sec) ? 1.0 : gammalib::sec_in_day;
626
627 // Return time unit
628 return unit;
629}
630
631
632/***********************************************************************//**
633 * @brief Print time reference
634 *
635 * @param[in] chatter Chattiness (defaults to NORMAL).
636 * @return String containing the time reference.
637 ***************************************************************************/
638std::string GTimeReference::print(const GChatter& chatter) const
639{
640 // Initialise result string
641 std::string result;
642
643 // Continue only if chatter is not silent
644 if (chatter != SILENT) {
645
646 // Append header
647 result.append("=== GTimeReference ===");
648
649 // Append information
650 result.append("\n"+gammalib::parformat("MJD reference time"));
651 result.append(gammalib::str(mjdref()));
652 result.append("\n"+gammalib::parformat("Time unit")+timeunit());
653 result.append("\n"+gammalib::parformat("Time system")+timesys());
654 result.append("\n"+gammalib::parformat("Time reference")+timeref());
655
656 } // endif: chatter was not silent
657
658 // Return
659 return result;
660}
661
662
663/*==========================================================================
664 = =
665 = Private methods =
666 = =
667 ==========================================================================*/
668
669/***********************************************************************//**
670 * @brief Initialise class members
671 ***************************************************************************/
673{
674 // Initialise members
675 m_mjdref = 0.0;
676 m_timeunit = "secs";
677 m_timesys = "TT";
678 m_timeref = "LOCAL";
679 m_unit_sec = true;
680
681 // Return
682 return;
683}
684
685
686/***********************************************************************//**
687 * @brief Copy class members
688 *
689 * @param[in] ref Time reference.
690 ***************************************************************************/
692{
693 // Copy members
694 m_mjdref = ref.m_mjdref;
696 m_timesys = ref.m_timesys;
697 m_timeref = ref.m_timeref;
699
700 // Return
701 return;
702}
703
704
705/***********************************************************************//**
706 * @brief Delete class members
707 ***************************************************************************/
709{
710 // Return
711 return;
712}
#define G_READ
#define G_WRITE_XML
Definition GEbounds.cpp:45
#define G_READ_XML
Definition GEbounds.cpp:44
#define G_SET
Definition GEnergies.cpp:46
Exception handler interface definition.
Abstract FITS extension base class definition.
Time reference class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
XML element node class interface definition.
Abstract FITS extension base class.
Definition GFitsHDU.hpp:51
bool has_card(const int &cardno) const
Check existence of header card.
Definition GFitsHDU.hpp:233
double real(const std::string &keyname) const
Return card value as double precision.
Definition GFitsHDU.hpp:423
std::string string(const std::string &keyname) const
Return card value as string.
Definition GFitsHDU.hpp:410
GFitsHeaderCard & card(const int &cardno)
Return header card.
Definition GFitsHDU.hpp:259
int integer(const std::string &keyname) const
Return card value as integer.
Definition GFitsHDU.hpp:436
Implements a time reference.
GTimeReference * clone(void) const
Clone object.
std::string m_timesys
Time system.
void write(GFitsHDU &hdu) const
Write time reference into FITS header.
void set(const double &mrdref, const std::string &timeunit, const std::string &timesys="TT", const std::string &timeref="LOCAL")
Set time reference.
double mjdreff(void) const
Returns fractional part of MJD reference (units: days)
GTimeReference & operator=(const GTimeReference &ref)
Assignment operator.
double m_mjdref
Time MJD reference (days)
double unitseconds(void) const
Return the time unit in seconds.
const double & mjdref(void) const
Return MJD reference (units: days)
void clear(void)
Clear time reference.
int mjdrefi(void) const
Returns integer part of MJD reference (units: days)
std::string print(const GChatter &chatter=NORMAL) const
Print time reference.
const std::string & timeunit(void) const
Return time unit.
void read(const GFitsHDU &hdu)
Read time reference from FITS header.
bool m_unit_sec
True: unit is seconds, False: unit is days.
void init_members(void)
Initialise class members.
std::string m_timeref
Time reference.
virtual ~GTimeReference(void)
Destructor.
void copy_members(const GTimeReference &ref)
Copy class members.
const std::string & timeref(void) const
Return time reference.
const std::string & timesys(void) const
Return time system.
void free_members(void)
Delete class members.
std::string m_timeunit
Time unit.
GTimeReference(void)
Void constructor.
XML element node class.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
bool has_attribute(const std::string &name) const
Check if element has a given attribute.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
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
double todouble(const std::string &arg)
Convert string into double precision value.
Definition GTools.cpp:926
std::string tolower(const std::string &s)
Convert string to lower case.
Definition GTools.cpp:955
int toint(const std::string &arg)
Convert string into integer value.
Definition GTools.cpp:821
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
const double sec_in_day
Definition GTools.hpp:49
std::string toupper(const std::string &s)
Convert string to upper case.
Definition GTools.cpp:941