GammaLib 2.1.0.dev
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-2023 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 const GFitsTableCol* ptr_ehora = table["EHORA"]; // rad
422
423 // Initialise Earth radius angle
424 double georad = 73.5;
425
426 // Copy data from columns into records
427 for (int i = 0; i < num; ++i) {
428
429 // Allocate OAD record
430 GCOMOad oad;
431
432 // Get time of record
433 int tjd = ptr_tjd->integer(i);
434 int tics = ptr_tics->integer(i);
435
436 // Store time information. The stop time is defined as the start
437 // time plus 131071 tics, since the length of one superpacket is
438 // 16.384 secs, i.e. 16.384 * 8000 = 131072 ticks
439 oad.tjd(tjd);
440 oad.tics(tics);
441 oad.tstart(gammalib::com_time(tjd, tics));
442 oad.tstop(gammalib::com_time(tjd, tics + 131071));
443
444 // Set geocentre azimuth and zenith angle in deg
445 oad.gcaz(ptr_gcaz->real(i) * gammalib::rad2deg);
446 oad.gcel(ptr_gcel->real(i) * gammalib::rad2deg);
447
448 // Set telescope Z- and X-axes
449 GSkyDir zaxis;
450 GSkyDir xaxis;
451 zaxis.radec(ptr_zrasc->real(i), ptr_zdecl->real(i));
452 xaxis.radec(ptr_xrasc->real(i), ptr_xdecl->real(i));
453 oad.zaxis(zaxis);
454 oad.xaxis(xaxis);
455
456 // Set telescope position vector
457 oad.pos(GVector(ptr_posx->real(i), ptr_posy->real(i), ptr_posz->real(i)));
458
459 // Compute apparent radius of Earth
460 double radius = std::sqrt(ptr_posx->real(i) * ptr_posx->real(i) +
461 ptr_posy->real(i) * ptr_posy->real(i) +
462 ptr_posz->real(i) * ptr_posz->real(i));
463 if ((radius > erd_min) && (radius < erd_max)) {
464 georad = std::asin(era/radius) * gammalib::rad2deg;
465 }
466 #if defined(G_GEORAD_WARNING)
467 else {
468 std::string msg = "Error in CGRO position. Distance from "
469 "geocentre is "+gammalib::str(radius)+ " km "
470 "while it should be in the interval ["+
471 gammalib::str(erd_min)+","+
472 gammalib::str(erd_max)+"] km. Use previous "
473 "spacecraft altitude.";
475 }
476 #endif
477 oad.georad(georad);
478
479 // Set Earth Horizon Angle in deg
480 oad.ehora(ptr_ehora->real(i) * gammalib::rad2deg);
481
482 // Append record
483 m_oads.push_back(oad);
484
485 } // endfor: looped over OAD records
486
487 } // endif: there were records to load
488
489 // Return
490 return;
491}
492
493
494/***********************************************************************//**
495 * @brief Print COMPTEL Orbit Aspect Data container
496 *
497 * @param[in] chatter Chattiness.
498 * @return String containing COMPTEL Orbit Aspect Data container information.
499 ***************************************************************************/
500std::string GCOMOads::print(const GChatter& chatter) const
501{
502 // Initialise result string
503 std::string result;
504
505 // Continue only if chatter is not silent
506 if (chatter != SILENT) {
507
508 // Append header
509 result.append("=== GCOMOads ===");
510
511 // Append container information
512 result.append("\n"+gammalib::parformat("Superpackets"));
513 result.append(gammalib::str(size()));
514 if (size() > 0) {
515
516 // Append time range
517 result.append("\n"+gammalib::parformat("TJD range"));
518 result.append(gammalib::str(m_oads[0].tjd()));
519 result.append(":");
520 result.append(gammalib::str(m_oads[0].tics()));
521 result.append(" - ");
522 result.append(gammalib::str(m_oads[size()-1].tjd()));
523 result.append(":");
524 result.append(gammalib::str(m_oads[size()-1].tics()));
525 result.append("\n"+gammalib::parformat("MJD range"));
526 result.append(gammalib::str(m_oads[0].tstart().mjd()));
527 result.append(" - ");
528 result.append(gammalib::str(m_oads[size()-1].tstop().mjd()));
529 result.append(" days");
530 result.append("\n"+gammalib::parformat("UTC range"));
531 result.append(m_oads[0].tstart().utc());
532 result.append(" - ");
533 result.append(m_oads[size()-1].tstop().utc());
534
535 // Append detailed information
536 GChatter reduced_chatter = gammalib::reduce(chatter);
537 if (reduced_chatter > SILENT) {
538
539 // Append TJDs
540 int tjd = 0;
541 int num = 0;
542 for (int i = 0; i < size(); ++i) {
543 if (m_oads[i].tjd() != tjd) {
544 if (num > 0) {
545 std::string key = "TJD "+gammalib::str(tjd);
546 result.append("\n"+gammalib::parformat(key));
547 result.append(gammalib::str(num)+" superpackets");
548 }
549 tjd = m_oads[i].tjd();
550 num = 1;
551 }
552 else {
553 num++;
554 }
555 }
556 std::string key = "TJD "+gammalib::str(tjd);
557 result.append("\n"+gammalib::parformat(key));
558 result.append(gammalib::str(num)+" superpackets");
559
560 } // endif: detailed information requested
561
562 } // endif: there were records
563
564 } // endif: chatter was not silent
565
566 // Return result
567 return result;
568}
569
570
571/*==========================================================================
572 = =
573 = Private methods =
574 = =
575 ==========================================================================*/
576
577/***********************************************************************//**
578 * @brief Initialise class members
579 ***************************************************************************/
581{
582 // Initialise members
583 m_oads.clear();
584
585 // Return
586 return;
587}
588
589
590/***********************************************************************//**
591 * @brief Copy class members
592 *
593 * @param[in] oads COMPTEL Orbit Aspect Data container.
594 ***************************************************************************/
596{
597 // Copy members
598 m_oads = oads.m_oads;
599
600 // Return
601 return;
602}
603
604
605/***********************************************************************//**
606 * @brief Delete class members
607 ***************************************************************************/
609{
610 // Return
611 return;
612}
#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:196
const GSkyDir & zaxis(void) const
Return telescope Z-axis.
Definition GCOMOad.hpp:370
const int & tics(void) const
Return tics of Orbit Aspect Record.
Definition GCOMOad.hpp:225
const float & ehora(void) const
Return Earth Horizon Angle of telescope pointing axis.
Definition GCOMOad.hpp:341
const float & gcaz(void) const
Return Geocentre azimuth angle.
Definition GCOMOad.hpp:254
const GTime & tstart(void) const
Return start time of superpacket.
Definition GCOMOad.hpp:136
const float & gcel(void) const
Return Geocentre zenith angle.
Definition GCOMOad.hpp:283
const float & georad(void) const
Return apparent radius of Earth.
Definition GCOMOad.hpp:312
const GTime & tstop(void) const
Return stop time of superpacket.
Definition GCOMOad.hpp:167
const GVector & pos(void) const
Return telescope position vector (km)
Definition GCOMOad.hpp:430
const GSkyDir & xaxis(void) const
Return telescope X-axis.
Definition GCOMOad.hpp:400
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:500
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:580
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:608
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:595
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:218
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:1162
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508
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:1405
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