GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
67  init_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  ***************************************************************************/
81 GCOMOads::GCOMOads(const GFilename& filename)
82 {
83  // Initialise class members
84  init_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  ***************************************************************************/
167 void GCOMOads::clear(void)
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  ***************************************************************************/
201 GCOMOad& 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  ***************************************************************************/
224 const 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  ***************************************************************************/
268 GCOMOad& 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  ***************************************************************************/
304 void 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  ***************************************************************************/
329 void 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  ***************************************************************************/
361 void 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  ***************************************************************************/
387 void 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  ***************************************************************************/
500 std::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 }
GCOMOads * clone(void) const
Clone COMPTEL Orbit Aspect Data container.
Definition: GCOMOads.cpp:185
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition: GFits.cpp:482
std::vector< GCOMOad > m_oads
Orbit Aspect Data records.
Definition: GCOMOads.hpp:89
void warning(const std::string &origin, const std::string &message)
Emits warning.
Definition: GTools.cpp:1386
Definition of COMPTEL tools.
GCOMOad & insert(const int &index, const GCOMOad &oad)
Insert Orbit Aspect Data into container.
Definition: GCOMOads.cpp:268
#define G_REMOVE
Definition: GCOMOads.cpp:42
const float & gcel(void) const
Return Geocentre zenith angle.
Definition: GCOMOad.hpp:283
bool is_empty(void) const
Signals if there are no Orbit Aspect Data in container.
Definition: GCOMOads.hpp:156
const GSkyDir & xaxis(void) const
Return telescope X-axis.
Definition: GCOMOad.hpp:400
std::string print(const GChatter &chatter=NORMAL) const
Print COMPTEL Orbit Aspect Data container.
Definition: GCOMOads.cpp:500
const GTime & tstop(void) const
Return stop time of superpacket.
Definition: GCOMOad.hpp:167
int size(void) const
Return number of Orbit Aspect Data in container.
Definition: GCOMOads.hpp:141
FITS file class.
Definition: GFits.hpp:63
void clear(void)
Clear COMPTEL Orbit Aspect Data container.
Definition: GCOMOads.cpp:167
FITS file class interface definition.
GCOMOad & at(const int &index)
Return reference to Orbit Aspect Data.
Definition: GCOMOads.cpp:201
#define G_INSERT
Definition: GCOMOads.cpp:41
GTime com_time(const int &tjd, const int &tics)
Convert TJD and COMPTEL tics in GTime object.
Definition: GCOMTools.cpp:55
const float & georad(void) const
Return apparent radius of Earth.
Definition: GCOMOad.hpp:312
COMPTEL Orbit Aspect Data class.
Definition: GCOMOad.hpp:49
Implementation of support function used by COMPTEL classes.
const GTime & tstart(void) const
Return start time of superpacket.
Definition: GCOMOad.hpp:136
void read(const GFitsTable &table)
Read COMPTEL Orbit Aspect Data FITS table.
Definition: GCOMOads.cpp:387
void radec(const double &ra, const double &dec)
Set equatorial sky direction (radians)
Definition: GSkyDir.cpp:197
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
Definition: GVector.cpp:1358
void load(const GFilename &filename)
Load COMPTEL Orbit Aspect Data FITS file.
Definition: GCOMOads.cpp:361
const GVector & pos(void) const
Return telescope position vector (km)
Definition: GCOMOad.hpp:430
#define G_AT
Definition: GCOMOads.cpp:40
const GSkyDir & zaxis(void) const
Return telescope Z-axis.
Definition: GCOMOad.hpp:370
Filename class.
Definition: GFilename.hpp:62
Abstract interface for FITS table column.
virtual ~GCOMOads(void)
Destructor.
Definition: GCOMOads.cpp:115
Abstract interface for FITS table.
Definition: GFitsTable.hpp:44
GChatter
Definition: GTypemaps.hpp:33
GCOMOad & append(const GCOMOad &oad)
Append Orbit Aspect Data to container.
Definition: GCOMOads.cpp:246
const float & ehora(void) const
Return Earth Horizon Angle of telescope pointing axis.
Definition: GCOMOad.hpp:341
void extend(const GCOMOads &oads)
Append Orbit Aspect Data container.
Definition: GCOMOads.cpp:329
GVector asin(const GVector &vector)
Computes arcsin of vector elements.
Definition: GVector.cpp:1106
const int & nrows(void) const
Return number of rows in table.
Definition: GFitsTable.hpp:119
void init_members(void)
Initialise class members.
Definition: GCOMOads.cpp:580
void free_members(void)
Delete class members.
Definition: GCOMOads.cpp:608
#define G_READ
Definition: GCOMOads.cpp:43
virtual int integer(const int &row, const int &inx=0) const =0
virtual double real(const int &row, const int &inx=0) const =0
const int & tjd(void) const
Return Truncated Julian Days of Orbit Aspect Record.
Definition: GCOMOad.hpp:196
GCOMOads & operator=(const GCOMOads &oads)
Assignment operator.
Definition: GCOMOads.cpp:137
void reserve(const int &num)
Reserves space for Orbit Aspect Data in container.
Definition: GCOMOads.hpp:170
GChatter reduce(const GChatter &chatter)
Reduce chattiness by one level.
Definition: GTypemaps.hpp:65
Exception handler interface definition.
COMPTEL Orbit Aspect Data container class.
Definition: GCOMOads.hpp:51
GCOMOads(void)
Void constructor.
Definition: GCOMOads.cpp:64
void remove(const int &index)
Remove Orbit Aspect Data from container.
Definition: GCOMOads.cpp:304
Vector class.
Definition: GVector.hpp:46
const double rad2deg
Definition: GMath.hpp:44
const int & tics(void) const
Return tics of Orbit Aspect Record.
Definition: GCOMOad.hpp:225
void copy_members(const GCOMOads &oads)
Copy class members.
Definition: GCOMOads.cpp:595
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
Sky direction class.
Definition: GSkyDir.hpp:62
void close(void)
Close FITS file.
Definition: GFits.cpp:1342
COMPTEL Orbit Aspect Data container class definition.
Mathematical function definitions.
const float & gcaz(void) const
Return Geocentre azimuth angle.
Definition: GCOMOad.hpp:254
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489
FITS table abstract base class interface definition.