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