GammaLib 2.0.0
Loading...
Searching...
No Matches
GCOMOads.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCOMOads.cpp - COMPTEL Orbit Aspect Data container class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2017-2021 by Juergen Knodlseder *
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 GCOMOads.hpp
23 * @brief COMPTEL Orbit Aspect Data container class implementation
24 * @author Juergen Knodlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GException.hpp"
32#include "GMath.hpp"
33#include "GFits.hpp"
34#include "GFitsTable.hpp"
35#include "GCOMTools.hpp"
36#include "GCOMSupport.hpp"
37#include "GCOMOads.hpp"
38
39/* __ Method name definitions ____________________________________________ */
40#define G_AT "GCOMOads::at(int&)"
41#define G_INSERT "GCOMOads::insert(int&, GCOMOad&)"
42#define G_REMOVE "GCOMOads::remove(int&)"
43#define G_READ "GCOMOads::read(GFitsTable&)"
44
45/* __ Macros _____________________________________________________________ */
46
47/* __ Coding definitions _________________________________________________ */
48//#define G_GEORAD_WARNING
49
50/* __ Debug definitions __________________________________________________ */
51
52
53/*==========================================================================
54 = =
55 = Constructors/destructors =
56 = =
57 ==========================================================================*/
58
59/***********************************************************************//**
60 * @brief Void constructor
61 *
62 * Constructs an empty Orbit Aspect Data container
63 ***************************************************************************/
65{
66 // Initialise class members
68
69 // Return
70 return;
71}
72
73
74/***********************************************************************//**
75 * @brief Filename constructor
76 *
77 * @param[in] filename Orbit Aspect Data FITS file
78 *
79 * Constructs an Orbit Aspect Data container from an OAD FITS file.
80 ***************************************************************************/
82{
83 // Initialise class members
85
86 // Load data
87 load(filename);
88
89 // Return
90 return;
91}
92
93
94/***********************************************************************//**
95 * @brief Copy constructor
96 *
97 * @param[in] oads COMPTEL Orbit Aspect Data container.
98 ***************************************************************************/
100{
101 // Initialise class members
102 init_members();
103
104 // Copy members
105 copy_members(oads);
106
107 // Return
108 return;
109}
110
111
112/***********************************************************************//**
113 * @brief Destructor
114 ***************************************************************************/
116{
117 // Free members
118 free_members();
119
120 // Return
121 return;
122}
123
124
125/*==========================================================================
126 = =
127 = Operators =
128 = =
129 ==========================================================================*/
130
131/***********************************************************************//**
132 * @brief Assignment operator
133 *
134 * @param[in] oads COMPTEL Orbit Aspect Data container.
135 * @return COMPTEL Orbit Aspect Data container.
136 ***************************************************************************/
138{
139 // Execute only if object is not identical
140 if (this != &oads) {
141
142 // Free members
143 free_members();
144
145 // Initialise private members
146 init_members();
147
148 // Copy members
149 copy_members(oads);
150
151 } // endif: object was not identical
152
153 // Return this object
154 return *this;
155}
156
157
158/*==========================================================================
159 = =
160 = Public methods =
161 = =
162 ==========================================================================*/
163
164/***********************************************************************//**
165 * @brief Clear COMPTEL Orbit Aspect Data container
166 ***************************************************************************/
168{
169 // Free members
170 free_members();
171
172 // Initialise private members
173 init_members();
174
175 // Return
176 return;
177}
178
179
180/***********************************************************************//**
181 * @brief Clone COMPTEL Orbit Aspect Data container
182 *
183 * @return Pointer to deep copy of COMPTEL Orbit Aspect Data container.
184 ***************************************************************************/
186{
187 return new GCOMOads(*this);
188}
189
190
191/***********************************************************************//**
192 * @brief Return reference to Orbit Aspect Data
193 *
194 * @param[in] index Orbit Aspect Data index [0,...,size()-1].
195 *
196 * @exception GException::out_of_range
197 * Orbit Aspect Data index is out of range.
198 *
199 * Returns a reference to the Orbit Aspect Data with the specified @p index.
200 ***************************************************************************/
201GCOMOad& GCOMOads::at(const int& index)
202{
203 // Raise exception if index is out of range
204 if (index < 0 || index >= size()) {
205 throw GException::out_of_range(G_AT, "Orbit Aspect Data index",
206 index, size());
207 }
208
209 // Return reference
210 return m_oads[index];
211}
212
213
214/***********************************************************************//**
215 * @brief Return reference to Orbit Aspect Data (const version)
216 *
217 * @param[in] index Orbit Aspect Data index [0,...,size()-1].
218 *
219 * @exception GException::out_of_range
220 * Orbit Aspect Data index is out of range.
221 *
222 * Returns a reference to the Orbit Aspect Data with the specified @p index.
223 ***************************************************************************/
224const GCOMOad& GCOMOads::at(const int& index) const
225{
226 // Raise exception if index is out of range
227 if (index < 0 || index >= size()) {
228 throw GException::out_of_range(G_AT, "Orbit Aspect Data index",
229 index, size());
230 }
231
232 // Return reference
233 return m_oads[index];
234}
235
236
237/***********************************************************************//**
238 * @brief Append Orbit Aspect Data to container
239 *
240 * @param[in] oad Orbit Aspect Data.
241 * @return Reference to appended Orbit Aspect Data.
242 *
243 * Appends Orbit Aspect Data to the container by making a deep copy of the
244 * Orbit Aspect Data.
245 ***************************************************************************/
247{
248 // Append oad to list
249 m_oads.push_back(oad);
250
251 // Return reference
252 return m_oads[size()-1];
253}
254
255
256/***********************************************************************//**
257 * @brief Insert Orbit Aspect Data into container
258 *
259 * @param[in] index Orbit Aspect Data index (0,...,size()-1).
260 * @param[in] oad Orbit Aspect Data.
261 *
262 * @exception GException::out_of_range
263 * Orbit Aspect Data index is out of range.
264 *
265 * Inserts an @p Orbit Aspect Data into the container before the Orbit
266 * Aspect Data with the specified @p index.
267 ***************************************************************************/
268GCOMOad& GCOMOads::insert(const int& index, const GCOMOad& oad)
269{
270 // Compile option: raise exception if index is out of range
271 #if defined(G_RANGE_CHECK)
272 if (is_empty()) {
273 if (index > 0) {
274 throw GException::out_of_range(G_INSERT, "Orbit Aspect Data index",
275 index, size());
276 }
277 }
278 else {
279 if (index < 0 || index >= size()) {
280 throw GException::out_of_range(G_INSERT, "Orbit Aspect Data index",
281 index, size());
282 }
283 }
284 #endif
285
286 // Inserts Orbit Aspect Data
287 m_oads.insert(m_oads.begin()+index, oad);
288
289 // Return reference
290 return m_oads[index];
291}
292
293
294/***********************************************************************//**
295 * @brief Remove Orbit Aspect Data from container
296 *
297 * @param[in] index Orbit Aspect Data index (0,...,size()-1).
298 *
299 * @exception GException::out_of_range
300 * Orbit Aspect Data index is out of range.
301 *
302 * Remove Orbit Aspect Data of specified @p index from container.
303 ***************************************************************************/
304void GCOMOads::remove(const int& index)
305{
306 // Compile option: raise exception if index is out of range
307 #if defined(G_RANGE_CHECK)
308 if (index < 0 || index >= size()) {
309 throw GException::out_of_range(G_REMOVE, "Orbit Aspect Data index",
310 index, size());
311 }
312 #endif
313
314 // Erase Orbit Aspect Data from container
315 m_oads.erase(m_oads.begin() + index);
316
317 // Return
318 return;
319}
320
321
322/***********************************************************************//**
323 * @brief Append Orbit Aspect Data container
324 *
325 * @param[in] oads COMPTEL Orbit Aspect Data container.
326 *
327 * Append COMPTEL Orbit Aspect Data container to the container.
328 ***************************************************************************/
329void GCOMOads::extend(const GCOMOads& oads)
330{
331 // Do nothing if COMPTEL Orbit Aspect Data container is empty
332 if (!oads.is_empty()) {
333
334 // Get size. Note that we extract the size first to avoid an
335 // endless loop that arises when a container is appended to
336 // itself.
337 int num = oads.size();
338
339 // Reserve enough space
340 reserve(size() + num);
341
342 // Loop over all elements and append them to container
343 for (int i = 0; i < num; ++i) {
344 m_oads.push_back(oads[i]);
345 }
346
347 } // endif: COMPTEL Orbit Aspect Data container was not empty
348
349 // Return
350 return;
351}
352
353
354/***********************************************************************//**
355 * @brief Load COMPTEL Orbit Aspect Data FITS file
356 *
357 * @param[in] filename COMPTEL OAD FITS file name.
358 *
359 * Loads an COMPTEL Orbit Aspect Data FITS file in the container.
360 ***************************************************************************/
361void GCOMOads::load(const GFilename& filename)
362{
363 // Open FITS file
364 GFits fits(filename);
365
366 // Get HDU (pointer is always valid)
367 const GFitsTable& hdu = *fits.table(1);
368
369 // Read Orbit Aspect Data FITS table
370 read(hdu);
371
372 // Close FITS file
373 fits.close();
374
375 // Return
376 return;
377}
378
379
380/***********************************************************************//**
381 * @brief Read COMPTEL Orbit Aspect Data FITS table
382 *
383 * @param[in] table COMPTEL OAD FITS table.
384 *
385 * Reads COMPTEL Orbit Aspect Data FITS table into the container.
386 ***************************************************************************/
387void GCOMOads::read(const GFitsTable& table)
388{
389 // Earth radius in km including atmosphere (see EVP routine EVSCDJ Rev.7)
390 const double era = 6451.03;
391
392 // Set Earth radius in km excluding atmosphere
393 const double erd = 6378.5;
394 const double erd_min = erd + 300.0; // Lower limit on orbit
395 const double erd_max = erd + 530.0; // Upper limit on orbit
396
397 // Clear
398 clear();
399
400 // Extract number of records in FITS file
401 int num = table.nrows();
402
403 // If there are records then load them
404 if (num > 0) {
405
406 // Reserve data
407 m_oads.reserve(num);
408
409 // Get column pointers
410 const GFitsTableCol* ptr_tjd = table["TJD"]; // days
411 const GFitsTableCol* ptr_tics = table["TICS"]; // ticks
412 const GFitsTableCol* ptr_gcaz = table["GCAZ"]; // rad
413 const GFitsTableCol* ptr_gcel = table["GCEL"]; // rad
414 const GFitsTableCol* ptr_posx = table["POSX"]; // km
415 const GFitsTableCol* ptr_posy = table["POSY"]; // km
416 const GFitsTableCol* ptr_posz = table["POSZ"]; // km
417 const GFitsTableCol* ptr_zrasc = table["ZRASC"]; // rad
418 const GFitsTableCol* ptr_zdecl = table["ZDECL"]; // rad
419 const GFitsTableCol* ptr_xrasc = table["XRASC"]; // rad
420 const GFitsTableCol* ptr_xdecl = table["XDECL"]; // rad
421
422 // Initialise Earth radius angle
423 double georad = 73.5;
424
425 // Copy data from columns into records
426 for (int i = 0; i < num; ++i) {
427
428 // Allocate OAD record
429 GCOMOad oad;
430
431 // Get time of record
432 int tjd = ptr_tjd->integer(i);
433 int tics = ptr_tics->integer(i);
434
435 // Store time information. The stop time is defined as the start
436 // time plus 131071 tics, since the length of one superpacket is
437 // 16.384 secs, i.e. 16.384 * 8000 = 131072 ticks
438 oad.tjd(tjd);
439 oad.tics(tics);
440 oad.tstart(gammalib::com_time(tjd, tics));
441 oad.tstop(gammalib::com_time(tjd, tics + 131071));
442
443 // Set geocentre azimuth and zenith angle in deg
444 oad.gcaz(ptr_gcaz->real(i) * gammalib::rad2deg);
445 oad.gcel(ptr_gcel->real(i) * gammalib::rad2deg);
446
447 // Set telescope Z- and X-axes
448 GSkyDir zaxis;
449 GSkyDir xaxis;
450 zaxis.radec(ptr_zrasc->real(i), ptr_zdecl->real(i));
451 xaxis.radec(ptr_xrasc->real(i), ptr_xdecl->real(i));
452 oad.zaxis(zaxis);
453 oad.xaxis(xaxis);
454
455 // Set telescope position vector
456 oad.pos(GVector(ptr_posx->real(i), ptr_posy->real(i), ptr_posz->real(i)));
457
458 // Compute apparent radius of Earth
459 double radius = std::sqrt(ptr_posx->real(i) * ptr_posx->real(i) +
460 ptr_posy->real(i) * ptr_posy->real(i) +
461 ptr_posz->real(i) * ptr_posz->real(i));
462 if ((radius > erd_min) && (radius < erd_max)) {
463 georad = std::asin(era/radius) * gammalib::rad2deg;
464 }
465 #if defined(G_GEORAD_WARNING)
466 else {
467 std::string msg = "Error in CGRO position. Distance from "
468 "geocentre is "+gammalib::str(radius)+ " km "
469 "while it should be in the interval ["+
470 gammalib::str(erd_min)+","+
471 gammalib::str(erd_max)+"] km. Use previous "
472 "spacecraft altitude.";
474 }
475 #endif
476 oad.georad(georad);
477
478 // Append record
479 m_oads.push_back(oad);
480
481 } // endfor: looped over OAD records
482
483 } // endif: there were records to load
484
485 // Return
486 return;
487}
488
489
490/***********************************************************************//**
491 * @brief Print COMPTEL Orbit Aspect Data container
492 *
493 * @param[in] chatter Chattiness.
494 * @return String containing COMPTEL Orbit Aspect Data container information.
495 ***************************************************************************/
496std::string GCOMOads::print(const GChatter& chatter) const
497{
498 // Initialise result string
499 std::string result;
500
501 // Continue only if chatter is not silent
502 if (chatter != SILENT) {
503
504 // Append header
505 result.append("=== GCOMOads ===");
506
507 // Append container information
508 result.append("\n"+gammalib::parformat("Superpackets"));
509 result.append(gammalib::str(size()));
510 if (size() > 0) {
511
512 // Append time range
513 result.append("\n"+gammalib::parformat("TJD range"));
514 result.append(gammalib::str(m_oads[0].tjd()));
515 result.append(":");
516 result.append(gammalib::str(m_oads[0].tics()));
517 result.append(" - ");
518 result.append(gammalib::str(m_oads[size()-1].tjd()));
519 result.append(":");
520 result.append(gammalib::str(m_oads[size()-1].tics()));
521 result.append("\n"+gammalib::parformat("MJD range"));
522 result.append(gammalib::str(m_oads[0].tstart().mjd()));
523 result.append(" - ");
524 result.append(gammalib::str(m_oads[size()-1].tstop().mjd()));
525 result.append(" days");
526 result.append("\n"+gammalib::parformat("UTC range"));
527 result.append(m_oads[0].tstart().utc());
528 result.append(" - ");
529 result.append(m_oads[size()-1].tstop().utc());
530
531 // Append detailed information
532 GChatter reduced_chatter = gammalib::reduce(chatter);
533 if (reduced_chatter > SILENT) {
534
535 // Append TJDs
536 int tjd = 0;
537 int num = 0;
538 for (int i = 0; i < size(); ++i) {
539 if (m_oads[i].tjd() != tjd) {
540 if (num > 0) {
541 std::string key = "TJD "+gammalib::str(tjd);
542 result.append("\n"+gammalib::parformat(key));
543 result.append(gammalib::str(num)+" superpackets");
544 }
545 tjd = m_oads[i].tjd();
546 num = 1;
547 }
548 else {
549 num++;
550 }
551 }
552 std::string key = "TJD "+gammalib::str(tjd);
553 result.append("\n"+gammalib::parformat(key));
554 result.append(gammalib::str(num)+" superpackets");
555
556 } // endif: detailed information requested
557
558 } // endif: there were records
559
560 } // endif: chatter was not silent
561
562 // Return result
563 return result;
564}
565
566
567/*==========================================================================
568 = =
569 = Private methods =
570 = =
571 ==========================================================================*/
572
573/***********************************************************************//**
574 * @brief Initialise class members
575 ***************************************************************************/
577{
578 // Initialise members
579 m_oads.clear();
580
581 // Return
582 return;
583}
584
585
586/***********************************************************************//**
587 * @brief Copy class members
588 *
589 * @param[in] oads COMPTEL Orbit Aspect Data container.
590 ***************************************************************************/
592{
593 // Copy members
594 m_oads = oads.m_oads;
595
596 // Return
597 return;
598}
599
600
601/***********************************************************************//**
602 * @brief Delete class members
603 ***************************************************************************/
605{
606 // Return
607 return;
608}
#define G_AT
#define G_READ
COMPTEL Orbit Aspect Data container class definition.
Implementation of support function used by COMPTEL classes.
Definition of COMPTEL tools.
Exception handler interface definition.
#define G_INSERT
#define G_REMOVE
FITS table abstract base class interface definition.
FITS file class interface definition.
Mathematical function definitions.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
COMPTEL Orbit Aspect Data class.
Definition GCOMOad.hpp:49
const int & tjd(void) const
Return Truncated Julian Days of Orbit Aspect Record.
Definition GCOMOad.hpp:193
const GSkyDir & zaxis(void) const
Return telescope Z-axis.
Definition GCOMOad.hpp:338
const int & tics(void) const
Return tics of Orbit Aspect Record.
Definition GCOMOad.hpp:222
const float & gcaz(void) const
Return Geocentre azimuth angle.
Definition GCOMOad.hpp:251
const GTime & tstart(void) const
Return start time of superpacket.
Definition GCOMOad.hpp:133
const float & gcel(void) const
Return Geocentre zenith angle.
Definition GCOMOad.hpp:280
const float & georad(void) const
Return apparent radius of Earth.
Definition GCOMOad.hpp:309
const GTime & tstop(void) const
Return stop time of superpacket.
Definition GCOMOad.hpp:164
const GVector & pos(void) const
Return telescope position vector (km)
Definition GCOMOad.hpp:398
const GSkyDir & xaxis(void) const
Return telescope X-axis.
Definition GCOMOad.hpp:368
COMPTEL Orbit Aspect Data container class.
Definition GCOMOads.hpp:51
void remove(const int &index)
Remove Orbit Aspect Data from container.
Definition GCOMOads.cpp:304
GCOMOad & at(const int &index)
Return reference to Orbit Aspect Data.
Definition GCOMOads.cpp:201
GCOMOads & operator=(const GCOMOads &oads)
Assignment operator.
Definition GCOMOads.cpp:137
void extend(const GCOMOads &oads)
Append Orbit Aspect Data container.
Definition GCOMOads.cpp:329
std::string print(const GChatter &chatter=NORMAL) const
Print COMPTEL Orbit Aspect Data container.
Definition GCOMOads.cpp:496
virtual ~GCOMOads(void)
Destructor.
Definition GCOMOads.cpp:115
void reserve(const int &num)
Reserves space for Orbit Aspect Data in container.
Definition GCOMOads.hpp:170
GCOMOads * clone(void) const
Clone COMPTEL Orbit Aspect Data container.
Definition GCOMOads.cpp:185
void clear(void)
Clear COMPTEL Orbit Aspect Data container.
Definition GCOMOads.cpp:167
int size(void) const
Return number of Orbit Aspect Data in container.
Definition GCOMOads.hpp:141
void read(const GFitsTable &table)
Read COMPTEL Orbit Aspect Data FITS table.
Definition GCOMOads.cpp:387
bool is_empty(void) const
Signals if there are no Orbit Aspect Data in container.
Definition GCOMOads.hpp:156
GCOMOads(void)
Void constructor.
Definition GCOMOads.cpp:64
GCOMOad & insert(const int &index, const GCOMOad &oad)
Insert Orbit Aspect Data into container.
Definition GCOMOads.cpp:268
void load(const GFilename &filename)
Load COMPTEL Orbit Aspect Data FITS file.
Definition GCOMOads.cpp:361
void init_members(void)
Initialise class members.
Definition GCOMOads.cpp:576
GCOMOad & append(const GCOMOad &oad)
Append Orbit Aspect Data to container.
Definition GCOMOads.cpp:246
void free_members(void)
Delete class members.
Definition GCOMOads.cpp:604
std::vector< GCOMOad > m_oads
Orbit Aspect Data records.
Definition GCOMOads.hpp:89
void copy_members(const GCOMOads &oads)
Copy class members.
Definition GCOMOads.cpp:591
Filename class.
Definition GFilename.hpp:62
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.
const int & nrows(void) const
Return number of rows in table.
FITS file class.
Definition GFits.hpp:63
void close(void)
Close FITS file.
Definition GFits.cpp:1342
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition GFits.cpp:482
Sky direction class.
Definition GSkyDir.hpp:62
void radec(const double &ra, const double &dec)
Set equatorial sky direction (radians)
Definition GSkyDir.cpp:197
Vector class.
Definition GVector.hpp:46
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
GChatter reduce(const GChatter &chatter)
Reduce chattiness by one level.
Definition GTypemaps.hpp:65
void warning(const std::string &origin, const std::string &message)
Emits warning.
Definition GTools.cpp:1386
const double rad2deg
Definition GMath.hpp:44
GTime com_time(const int &tjd, const int &tics)
Convert TJD and COMPTEL tics in GTime object.
Definition GCOMTools.cpp:55