GammaLib 2.0.0
Loading...
Searching...
No Matches
GLATEventList.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GLATEventList.cpp - Fermi/LAT event list class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2009-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 GLATEventList.cpp
23 * @brief Fermi/LAT event list class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <typeinfo>
32#include <cstdio> // std::sprintf
33#include "GException.hpp"
34#include "GTools.hpp"
35#include "GFilename.hpp"
36#include "GFitsTable.hpp"
39#include "GFitsTableLongCol.hpp"
41#include "GLATEventList.hpp"
42
43/* __ Method name definitions ____________________________________________ */
44#define G_OPERATOR "GLATEventList::operator[](int&)"
45#define G_ROI "GLATEventList::roi(GRoi&)"
46
47/* __ Macros _____________________________________________________________ */
48
49/* __ Coding definitions _________________________________________________ */
50
51/* __ Debug definitions __________________________________________________ */
52
53
54/*==========================================================================
55 = =
56 = Constructors/destructors =
57 = =
58 ==========================================================================*/
59
60/***********************************************************************//**
61 * @brief Void constructor
62 ***************************************************************************/
64{
65 // Initialise class members for clean destruction
67
68 // Return
69 return;
70}
71
72
73/***********************************************************************//**
74 * @brief File name constructor
75 *
76 * @param[in] filename Event list filename.
77 *
78 * Construct event list object by loading the events from a FITS file.
79 ***************************************************************************/
81{
82 // Initialise members
84
85 // Load event list
86 load(filename);
87
88 // Return
89 return;
90}
91
92
93/***********************************************************************//**
94 * @brief Copy constructor
95 *
96 * @param[in] list LAT event list.
97 ***************************************************************************/
99{
100 // Initialise members
101 init_members();
102
103 // Copy members
104 copy_members(list);
105
106 // Return
107 return;
108}
109
110
111/***********************************************************************//**
112 * @brief Destructor
113 ***************************************************************************/
115{
116 // Free members
117 free_members();
118
119 // Return
120 return;
121}
122
123
124/*==========================================================================
125 = =
126 = Operators =
127 = =
128 ==========================================================================*/
129
130/***********************************************************************//**
131 * @brief Assignment operator
132 *
133 * @param[in] list Fermi/LAT event list.
134 * @return Fermi/LAT event list.
135 ***************************************************************************/
137{
138 // Execute only if object is not identical
139 if (this != &list) {
140
141 // Copy base class members
142 this->GEventList::operator=(list);
143
144 // Free members
145 free_members();
146
147 // Initialise members
148 init_members();
149
150 // Copy members
151 copy_members(list);
152
153 } // endif: object was not identical
154
155 // Return this object
156 return *this;
157}
158
159
160/***********************************************************************//**
161 * @brief Event atom access operator
162 *
163 * @param[in] index Event index [0,...,size()-1].
164 *
165 * @exception GException::out_of_range
166 * Event index outside valid range.
167 *
168 * Returns pointer to an event atom.
169 ***************************************************************************/
171{
172 // Optionally check if the index is valid
173 #if defined(G_RANGE_CHECK)
174 if (index < 0 || index >= size()) {
175 throw GException::out_of_range(G_OPERATOR, "Event index", index, size());
176 }
177 #endif
178
179 // Return pointer
180 return (&(m_events[index]));
181}
182
183
184/***********************************************************************//**
185 * @brief Event atom access operator
186 *
187 * @param[in] index Event index [0,...,size()-1].
188 *
189 * @exception GException::out_of_range
190 * Event index outside valid range.
191 *
192 * Returns pointer to an event atom.
193 ***************************************************************************/
194const GLATEventAtom* GLATEventList::operator[](const int& index) const
195{
196 // Optionally check if the index is valid
197 #if defined(G_RANGE_CHECK)
198 if (index < 0 || index >= size()) {
199 throw GException::out_of_range(G_OPERATOR, "Event index", index, size());
200 }
201 #endif
202
203 // Return pointer
204 return (&(m_events[index]));
205}
206
207
208/*==========================================================================
209 = =
210 = Public methods =
211 = =
212 ==========================================================================*/
213
214/***********************************************************************//**
215 * @brief Clear event list
216 ***************************************************************************/
218{
219 // Free class members (base and derived classes, derived class first)
220 free_members();
222 this->GEvents::free_members();
223
224 // Initialise members
225 this->GEvents::init_members();
227 init_members();
228
229 // Return
230 return;
231}
232
233
234/***********************************************************************//**
235 * @brief Clone event list
236 *
237 * @return Pointer to deep copy of Fermi/LAT event list.
238 ***************************************************************************/
240{
241 return new GLATEventList(*this);
242}
243
244
245/***********************************************************************//**
246 * @brief Load LAT events from FITS file
247 *
248 * @param[in] filename FITS filename.
249 *
250 * This method loads LAT events from a FT1 file.
251 ***************************************************************************/
252void GLATEventList::load(const GFilename& filename)
253{
254 // Open FITS file
255 GFits fits(filename);
256
257 // Read event list from FITS file
258 read(fits);
259
260 // Close FITS file
261 fits.close();
262
263 // Return
264 return;
265}
266
267
268/***********************************************************************//**
269 * @brief Save LAT events
270 *
271 * @param[in] filename FITS filename.
272 * @param[in] clobber Overwrite existing FITS file (default=false).
273 *
274 * This method saves LAT events into a FT1 file.
275 *
276 * @todo To be implemented.
277 ***************************************************************************/
278void GLATEventList::save(const GFilename& filename,
279 const bool& clobber) const
280{
281 // Return
282 return;
283}
284
285
286/***********************************************************************//**
287 * @brief Read LAT events from FITS file.
288 *
289 * @param[in] file FITS file.
290 *
291 * This method read the LAT event list from a FITS file.
292 *
293 * The method clears the object before loading, thus any events residing in
294 * the object before loading will be lost.
295 ***************************************************************************/
296void GLATEventList::read(const GFits& file)
297{
298 // Clear object
299 clear();
300
301 // Get HDU (pointer is always valid)
303
304 // Read event data
305 read_events(hdu);
306
307 // Read data selection keywords
308 read_ds_keys(hdu);
309
310 // If we have a GTI extension, then read Good Time Intervals from that
311 // extension
314 m_gti.read(gti);
315 }
316
317 // ... otherwise build GTI from TSTART and TSTOP
318 else {
319
320 // Read start and stop time
321 double tstart = hdu.real("TSTART");
322 double tstop = hdu.real("TSTOP");
323
324 // Create time reference from header information
325 GTimeReference timeref(hdu);
326
327 // Set start and stop time
328 GTime start(tstart);
329 GTime stop(tstop);
330
331 // Append start and stop time as single time interval to GTI
332 m_gti.append(start, stop);
333
334 // Set GTI time reference
335 m_gti.reference(timeref);
336
337 } // endelse: GTI built from TSTART and TSTOP
338
339 // Return
340 return;
341}
342
343
344/***********************************************************************//**
345 * @brief Write LAT event list into FITS file.
346 *
347 * @param[in] file FITS file.
348 *
349 * Write the LAT event list into FITS file.
350 *
351 * @todo To be implemented.
352 ***************************************************************************/
354{
355 // Return
356 return;
357}
358
359
360/***********************************************************************//**
361 * @brief Set Region of Interest
362 *
363 * @param[in] roi Region of Interest.
364 *
365 * @exception GException::invalid_argument
366 * Region of Interest @p roi in not a LAT Region of Interest.
367 ***************************************************************************/
368void GLATEventList::roi(const GRoi& roi)
369{
370 // Cast RoI dynamically
371 const GLATRoi* latroi = dynamic_cast<const GLATRoi*>(&roi);
372
373 // Throw exception if RoI is not of correct type
374 if (latroi == NULL) {
375 std::string cls = std::string(typeid(&roi).name());
376 std::string msg = "Invalid RoI type \""+cls+"\" specified. Please "
377 "specify a \"GLATRoi\" instance as argument.";
379 }
380
381 // Copy RoI
382 m_roi = *latroi;
383
384 // Return
385 return;
386}
387
388
389/***********************************************************************//**
390 * @brief Append event to event list
391 *
392 * @param[in] event Event.
393 *
394 * Appends an event to the end of the event list.
395 ***************************************************************************/
397{
398 // Append event
399 m_events.push_back(event);
400
401 // Return
402 return;
403}
404
405
406/***********************************************************************//**
407 * @brief Remove events from event list
408 *
409 * @param[in] index Index from which on events should be removed.
410 * @param[in] number Number of event to remove (default: 1).
411 *
412 * Removes events from the event list. This method does nothing if @p index
413 * points beyond the event list. The method does also gently accept
414 * @p number arguments where @p index + @p number reach beyond the event
415 * list. In that case, all events from event @p index on will be removed.
416 ***************************************************************************/
417void GLATEventList::remove(const int& index, const int& number)
418{
419 // Continue only if index is valid
420 if (index < size()) {
421
422 // Determine number of elements to remove
423 int n_remove = (index + number > size()) ? size() - index : number;
424
425 // Remove events
426 m_events.erase(m_events.begin() + index,
427 m_events.begin() + index + n_remove);
428
429 } // endif: index was valid
430
431 // Return
432 return;
433}
434
435
436/***********************************************************************//**
437 * @brief Print event list information
438 *
439 * @param[in] chatter Chattiness.
440 * @return String containing event list information.
441 ***************************************************************************/
442std::string GLATEventList::print(const GChatter& chatter) const
443{
444 // Initialise result string
445 std::string result;
446
447 // Continue only if chatter is not silent
448 if (chatter != SILENT) {
449
450 // Append header
451 result.append("=== GLATEventList ===");
452
453 // Append information
454 result.append("\n"+gammalib::parformat("Number of events") +
456
457 // Append DS keywords
458 result.append("\n"+gammalib::parformat("Number of DS keywords"));
459 result.append(gammalib::str(m_ds_type.size()));
460 for (int i = 0; i < m_ds_type.size(); ++i) {
461 result.append("\n"+gammalib::parformat(" Data selection"));
462 result.append("Type="+m_ds_type[i]);
463 if (m_ds_unit[i].length() > 0) {
464 result.append(" Unit="+m_ds_unit[i]);
465 }
466 if (m_ds_reference[i].length() > 0) {
467 result.append(" Reference="+m_ds_reference[i]);
468 }
469 }
470
471 // Append diffuse keywords
472 result.append("\n"+gammalib::parformat("Number of diffuse models"));
473 result.append(gammalib::str(m_difrsp_label.size()));
474 for (int i = 0; i < m_difrsp_label.size(); ++i) {
475 result.append("\n"+gammalib::parformat(" Diffuse component"));
476 result.append(m_difrsp_label[i]);
477 }
478
479 } // endif: chatter was not silent
480
481 // Return result
482 return result;
483}
484
485
486/*==========================================================================
487 = =
488 = Private methods =
489 = =
490 ==========================================================================*/
491
492/***********************************************************************//**
493 * @brief Initialise class members
494 ***************************************************************************/
496{
497 // Initialise members
498 m_roi.clear();
499 m_events.clear();
500 m_difrsp_label.clear();
501 m_ds_type.clear();
502 m_ds_unit.clear();
503 m_ds_value.clear();
504 m_ds_reference.clear();
505
506 // Return
507 return;
508}
509
510
511/***********************************************************************//**
512 * @brief Copy class members
513 *
514 * @param[in] list LAT event list.
515 ***************************************************************************/
517{
518 // Copy members
519 m_roi = list.m_roi;
520 m_events = list.m_events;
522 m_ds_type = list.m_ds_type;
523 m_ds_unit = list.m_ds_unit;
524 m_ds_value = list.m_ds_value;
526
527 // Return
528 return;
529}
530
531
532/***********************************************************************//**
533 * @brief Delete class members
534 ***************************************************************************/
536{
537 // Return
538 return;
539}
540
541
542/***********************************************************************//**
543 * @brief Read LAT events from FITS table.
544 *
545 * @param[in] table Event table.
546 *
547 * Read the LAT events from the event table.
548 ***************************************************************************/
550{
551 // Clear existing events
552 m_events.clear();
553
554 // Extract number of events in FT1 file
555 int num = table.integer("NAXIS2");
556
557 // If there are events then load them
558 if (num > 0) {
559
560 // Reserve data
561 m_events.reserve(num);
562
563 // Get column pointers
564 const GFitsTableCol* ptr_time = table["TIME"];
565 const GFitsTableCol* ptr_energy = table["ENERGY"];
566 const GFitsTableCol* ptr_ra = table["RA"];
567 const GFitsTableCol* ptr_dec = table["DEC"];
568 const GFitsTableCol* ptr_theta = table["THETA"];
569 const GFitsTableCol* ptr_phi = table["PHI"];
570 const GFitsTableCol* ptr_zenith = table["ZENITH_ANGLE"];
571 const GFitsTableCol* ptr_azimuth = table["EARTH_AZIMUTH_ANGLE"];
572 const GFitsTableCol* ptr_eid = table["EVENT_ID"];
573 const GFitsTableCol* ptr_rid = table["RUN_ID"];
574 const GFitsTableCol* ptr_recon = table["RECON_VERSION"];
575 const GFitsTableCol* ptr_calib = table["CALIB_VERSION"];
576 const GFitsTableCol* ptr_class = table["EVENT_CLASS"];
577 const GFitsTableCol* ptr_conv = table["CONVERSION_TYPE"];
578 const GFitsTableCol* ptr_ltime = table["LIVETIME"];
579
580 // Copy data from columns into GLATEventAtom objects
581 GLATEventAtom event;
582 for (int i = 0; i < num; ++i) {
583 event.m_time.set(ptr_time->real(i), m_gti.reference());
584 event.m_energy.MeV(ptr_energy->real(i));
585 event.m_dir.dir().radec_deg(ptr_ra->real(i), ptr_dec->real(i));
586 event.m_theta = ptr_theta->real(i);
587 event.m_phi = ptr_phi->real(i);
588 event.m_zenith_angle = ptr_zenith->real(i);
589 event.m_earth_azimuth_angle = ptr_azimuth->real(i);
590 event.m_event_id = ptr_eid->integer(i);
591 event.m_run_id = ptr_rid->integer(i);
592 event.m_recon_version = ptr_recon->integer(i);
593 event.m_calib_version[0] = ptr_calib->integer(i,0);
594 event.m_calib_version[1] = ptr_calib->integer(i,1);
595 event.m_calib_version[2] = ptr_calib->integer(i,2);
596 event.m_event_class = ptr_class->integer(i);
597 event.m_conversion_type = ptr_conv->integer(i);
598 event.m_livetime = ptr_ltime->real(i);
599 m_events.push_back(event);
600 }
601
602 // Extract number of diffuse response labels
603 int num_difrsp = table.integer("NDIFRSP");
604
605 // Allocate diffuse response components
606 if (num_difrsp > 0) {
607
608 // Reserve space
609 m_difrsp_label.reserve(num_difrsp);
610
611 // Allocate components
612 for (int i = 0; i < num; ++i) {
613 m_events[i].m_difrsp = new double[num_difrsp];
614 }
615
616 // Load diffuse columns
617 for (int k = 0; k < num_difrsp; ++k) {
618
619 // Allocate space for keyword name
620 char keyword[10];
621
622 // Set keyword name
623 std::sprintf(keyword, "DIFRSP%d", k);
624
625 // Get DIFRSP label
626 if (table.has_card(std::string(keyword))) {
627 m_difrsp_label.push_back(table.string(std::string(keyword)));
628 }
629 else {
630 m_difrsp_label.push_back("NONE");
631 }
632
633 // Get column pointer
634 const GFitsTableCol* ptr_dif = table[std::string(keyword)];
635
636 // Copy data from columns into GLATEventAtom objects
637 for (int i = 0; i < num; ++i) {
638 m_events[i].m_difrsp[k] = ptr_dif->real(i);
639 }
640
641 } // endfor: looped over diffuse columns
642
643 } // endif: diffuse components found
644
645 } // endif: events found
646
647 // Return
648 return;
649}
650
651
652/***********************************************************************//**
653 * @brief Read data selection keywords from FITS HDU.
654 *
655 * @param[in] hdu FITS HDU pointer.
656 *
657 * @todo Declared header card const in to GFitsHDU.
658 * @todo Add check key method to GFitsHDU to avoid unneccesary try/catch
659 * blocks.
660 ***************************************************************************/
662{
663 // Get number of data selection keys
664 int ds_num = hdu.integer("NDSKEYS");
665
666 // Get data selection keys
667 if (ds_num > 0) {
668
669 // Circumvent const correctness. We need this because the header()
670 // card method is not declared const. This should be corrected.
671 //GFitsHDU* ptr = (GFitsHDU*)&hdu;
672
673 // Reserve space
674 m_ds_type.reserve(ds_num);
675 m_ds_unit.reserve(ds_num);
676 m_ds_value.reserve(ds_num);
677 m_ds_reference.reserve(ds_num);
678
679 // Allocate space for the keyword
680 char keyword[10];
681
682 // Get columns
683 for (int i = 0; i < ds_num; ++i) {
684
685 // Get DSTYPnn
686 std::sprintf(keyword, "DSTYP%d", i+1);
687 if (hdu.has_card(std::string(keyword))) {
688 m_ds_type.push_back(hdu.string(std::string(keyword)));
689 }
690 else {
691 m_ds_type.push_back("");
692 }
693
694 // Get DSUNInn
695 std::sprintf(keyword, "DSUNI%d", i+1);
696 if (hdu.has_card(std::string(keyword))) {
697 m_ds_unit.push_back(hdu.string(std::string(keyword)));
698 }
699 else {
700 m_ds_unit.push_back("");
701 }
702
703 // Get DSVALnn
704 std::sprintf(keyword, "DSVAL%d", i+1);
705 if (hdu.has_card(std::string(keyword))) {
706 m_ds_value.push_back(hdu.string(std::string(keyword)));
707 }
708 else {
709 m_ds_value.push_back("");
710 }
711
712 // Get DSREFnn
713 std::sprintf(keyword, "DSREF%d", i+1);
714 if (hdu.has_card(std::string(keyword))) {
715 m_ds_reference.push_back(hdu.string(std::string(keyword)));
716 }
717 else {
718 m_ds_reference.push_back("");
719 }
720
721 } // endfor: looped over data selection keys
722
723 } // endif: there were data selection keys
724
725 // Return
726 return;
727}
#define G_OPERATOR
Definition GArf.cpp:44
#define G_ROI
Exception handler interface definition.
Filename class interface definition.
FITS table double column class interface definition.
FITS table float column class interface definition.
FITS table long integer column class interface definition.
FITS table short integer column class interface definition.
FITS table abstract base class interface definition.
Fermi/LAT event list class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Abstract event atom container class.
virtual GEventList & operator=(const GEventList &list)
Assignment operator.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
void free_members(void)
Delete class members.
Definition GEvents.cpp:206
GGti m_gti
Good time intervals covered by events.
Definition GEvents.hpp:112
const GTime & tstart(void) const
Return start time.
Definition GEvents.hpp:146
const GGti & gti(void) const
Return Good Time Intervals.
Definition GEvents.hpp:134
void init_members(void)
Initialise class members.
Definition GEvents.cpp:176
const GTime & tstop(void) const
Return stop time.
Definition GEvents.hpp:158
Filename class.
Definition GFilename.hpp:62
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
int integer(const std::string &keyname) const
Return card value as integer.
Definition GFitsHDU.hpp:436
Abstract interface for FITS table column.
virtual int integer(const int &row, const int &inx=0) const =0
virtual double real(const int &row, const int &inx=0) const =0
Abstract interface for FITS 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
void close(void)
Close FITS file.
Definition GFits.cpp:1342
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition GFits.cpp:482
void reference(const GTimeReference &ref)
Set time reference for Good Time Intervals.
Definition GGti.hpp:257
void read(const GFitsTable &table)
Read Good Time Intervals and time reference from FITS table.
Definition GGti.cpp:753
void append(const GTime &tstart, const GTime &tstop)
Append Good Time Interval.
Definition GGti.cpp:269
Fermi/LAT event atom class.
GTime m_time
Event time.
Fermi/LAT event list class.
std::vector< std::string > m_ds_type
Data selection types.
std::vector< GLATEventAtom > m_events
Events.
void read_ds_keys(const GFitsHDU &hdu)
Read data selection keywords from FITS HDU.
void remove(const int &index, const int &number=1)
Remove events from event list.
std::vector< std::string > m_ds_reference
Data selection references.
GLATEventList(void)
Void constructor.
virtual void clear(void)
Clear event list.
void append(const GLATEventAtom &event)
Append event to event list.
virtual void write(GFits &file) const
Write LAT event list into FITS file.
std::vector< std::string > m_difrsp_label
Diffuse response model labels.
virtual GLATEventList * clone(void) const
Clone event list.
virtual int size(void) const
Return number of events in list.
virtual const GLATRoi & roi(void) const
Return Region of Interest.
virtual void load(const GFilename &filename)
Load LAT events from FITS file.
void copy_members(const GLATEventList &list)
Copy class members.
std::vector< std::string > m_ds_value
Data selection values.
virtual ~GLATEventList(void)
Destructor.
virtual void save(const GFilename &filename, const bool &clobber=false) const
Save LAT events.
virtual int number(void) const
Return number of events in list.
virtual void read(const GFits &file)
Read LAT events from FITS file.
void free_members(void)
Delete class members.
std::vector< std::string > m_ds_unit
Data selection units.
void read_events(const GFitsTable &hdu)
Read LAT events from FITS table.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print event list information.
void init_members(void)
Initialise class members.
GLATRoi m_roi
Region of interest.
virtual GLATEventAtom * operator[](const int &index)
Event atom access operator.
virtual GLATEventList & operator=(const GLATEventList &list)
Assignment operator.
Fermi/LAT region of interest class.
Definition GLATRoi.hpp:45
virtual void clear(void)
Clear region of interest.
Definition GLATRoi.cpp:160
Interface for the region of interest classes.
Definition GRoi.hpp:48
Implements a time reference.
Time class.
Definition GTime.hpp:55
void set(const double &time, const GTimeReference &ref)
Set time given in specified reference.
Definition GTime.cpp:1005
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 std::string extname_gti
Definition GGti.hpp:44
const std::string extname_lat_events