GammaLib  2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GSPITools.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GSPITools.cpp - INTEGRAL/SPI tools *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2020 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 GSPITools.cpp
23  * @brief Implementation of INTEGRAL/SPI tools
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "GSPITools.hpp"
32 #include "GFits.hpp"
33 #include "GFitsTable.hpp"
34 
35 /* __ Method name definitions ____________________________________________ */
36 
37 /* __ Coding definitions _________________________________________________ */
38 
39 /* __ Debug definitions __________________________________________________ */
40 
41 
42 /***********************************************************************//**
43  * @brief Return FITS table
44  *
45  * @param[in] fits FITS file.
46  * @param[in] extname Extension name.
47  * @param[in] extver Extension version.
48  * @return Pointer to FITS table.
49  *
50  * Returns the HDU with a specific extension name and version from the FITS
51  * file. The method searched in the FITS file as well as grouping tables and
52  * nested grouping tables.
53  *
54  * The method allocates a copy of the HDU, hence the client needs to
55  * deallocate the HDU after usage.
56  ***************************************************************************/
57 const GFitsTable* gammalib::spi_hdu(const GFits& fits,
58  const std::string& extname,
59  const int& extver)
60 {
61  // Initialise HDU with NULL pointer
62  const GFitsTable* hdu = NULL;
63 
64  // Loop over all extensions
65  for (int extno = 0; extno < fits.size(); ++extno) {
66 
67  // Get FITS table extension
68  const GFitsTable* ext = dynamic_cast<const GFitsTable*>(fits[extno]);
69 
70  // If extension is no table then skip extension
71  if (ext == NULL) {
72  continue;
73  }
74 
75  // If HDU has the requested extension name and the requested extension
76  // version then clone the HDU and break. If no extension version is
77  // present in the file then only check on extension name.
78  if (ext->extname() == extname) {
79  if (ext->has_card("EXTVER")) {
80  if (ext->integer("EXTVER") == extver) {
81  hdu = ext->clone();
82  break;
83  }
84  }
85  else {
86  hdu = ext->clone();
87  break;
88  }
89  }
90 
91  // If HDU is a grouping table then search the requested extension
92  // in the grouping table or any grouping tables that are found in
93  // the grouping table
94  else if (ext->extname() == "GROUPING") {
95 
96  // If the extension has a GRPNAME then check if the requested
97  // extension name if that grouping name
98  if (ext->has_card("GRPNAME")) {
99  if (ext->string("GRPNAME") == extname) {
100  hdu = ext->clone();
101  break;
102  }
103  }
104 
105  // Loop over grouping table and search for a member with the
106  // requested extension name and version. In case of success
107  // get the URL, open the FITS file and search for the extension
108  // with the requested name and version.
109  for (int i = 0; i < ext->nrows(); ++i) {
110  if (((*ext)["MEMBER_NAME"]->string(i) == extname) &&
111  ((*ext)["MEMBER_VERSION"]->integer(i) == extver)) {
112  std::string filename = (*ext)["MEMBER_LOCATION"]->string(i);
113  if (!filename.empty()) {
114  std::string filepath = fits.filename().path();
115  GFits fits_next(filepath+filename);
116  hdu = spi_hdu(fits_next, extname, extver);
117  if (hdu != NULL) {
118  break;
119  }
120  }
121  }
122  } // endfor: looped over grouping table
123 
124  // If we have still no HDU then search all grouping tables
125  // that are found in the grouping table
126  if (hdu == NULL) {
127  for (int i = 0; i < ext->nrows(); ++i) {
128  if ((*ext)["MEMBER_NAME"]->string(i) == "GROUPING") {
129  std::string filename = (*ext)["MEMBER_LOCATION"]->string(i);
130  if (!filename.empty()) {
131  std::string filepath = fits.filename().path();
132  GFits fits_next(filepath+filename);
133  hdu = spi_hdu(fits_next, extname, extver);
134  if (hdu != NULL) {
135  break;
136  }
137  }
138  }
139  }
140  } // endif: we had no HDU
141 
142  // If we have an HDU then break
143  if (hdu != NULL) {
144  break;
145  }
146 
147  } // endelse: HDU was a grouping table
148 
149  } // endfor: looped over all extensions
150 
151  // Return pointer to FITS table
152  return hdu;
153 }
154 
155 
156 /***********************************************************************//**
157  * @brief Return number of HDU versions.
158  *
159  * @param[in] fits FITS file.
160  * @param[in] extname Extension name.
161  * @return Number of HDU versions.
162  *
163  * Returns the number of HDU versions with a specific extension name in the
164  * FITS file and associated or nested grouping tables.
165  ***************************************************************************/
166 int gammalib::spi_num_hdus(const GFits& fits, const std::string& extname)
167 {
168  // Initialise number of versions
169  int extvers = 0;
170 
171  // Loop over all extensions
172  for (int extno = 0; extno < fits.size(); ++extno) {
173 
174  // Get HDU
175  const GFitsHDU* ext = fits[extno];
176 
177  // If HDU has the requested extension name then increase version
178  // counter
179  if (ext->extname() == extname) {
180  extvers++;
181  }
182 
183  // If HDU is a grouping table then count the number of versions in
184  // the grouping table
185  else if (ext->extname() == "GROUPING") {
186 
187  // Cast extension to FITS table
188  const GFitsTable* table = static_cast<const GFitsTable*>(ext);
189 
190  // Loop over grouping table and search for a member with the
191  // requested extension name and version. In case of success
192  // get the URL, open the FITS file and search for the extension
193  // with the requested name and version.
194  for (int i = 0; i < table->nrows(); ++i) {
195  if ((*table)["MEMBER_NAME"]->string(i) == extname) {
196  extvers++;
197  }
198  else if ((*table)["MEMBER_NAME"]->string(i) == "GROUPING") {
199  std::string filename = (*table)["MEMBER_LOCATION"]->string(i);
200  if (!filename.empty()) {
201  std::string filepath = fits.filename().path();
202  GFits fits_next(filepath+filename);
203  extvers += spi_num_hdus(fits_next, extname);
204  }
205  }
206  } // endfor: looped over grouping table
207 
208  } // endelse: HDU was a grouping table
209 
210  } // endfor: looped over all extensions
211 
212  // Return number of versions
213  return extvers;
214 }
215 
216 
217 /***********************************************************************//**
218  * @brief Convert IJD to GTime
219  *
220  * @param[in] ijd INTEGRAL Julian Days (days).
221  * @return time.
222  *
223  * Converts time given in INTEGRAL Julian Days into a GTime object.
224  ***************************************************************************/
225 GTime gammalib::spi_ijd2time(const double& ijd)
226 {
227  // Convert IJD to MJD
228  double mjd = ijd + 51544.0;
229 
230  // Set GTime
231  GTime time;
232  time.mjd(mjd);
233 
234  // Return time
235  return time;
236 }
237 
238 
239 /***********************************************************************//**
240  * @brief Return start time of annealing operations
241  *
242  * @return Start time of annealing operations.
243  *
244  * Returns the start time of the SPI annealing operations.
245  *
246  * Source: https://www.cosmos.esa.int/web/integral/long-term-plan
247  ***************************************************************************/
249 {
250  // Allocates times
251  GTimes times;
252 
253  // Set annealing start times
254  times.append(GTime("2003-02-06T09:00:00")); // 1.
255  times.append(GTime("2003-07-15T12:00:00")); // 2.
256  times.append(GTime("2003-11-11T12:00:00")); // 3.
257  times.append(GTime("2004-06-17T09:00:00")); // 4.
258  times.append(GTime("2005-01-19T09:00:00")); // 5.
259  times.append(GTime("2005-06-14T00:00:00")); // 6.
260  times.append(GTime("2006-01-09T00:00:00")); // 7.
261  times.append(GTime("2006-06-08T00:00:00")); // 8.
262  times.append(GTime("2006-12-04T10:00:00")); // 9.
263  times.append(GTime("2007-05-29T12:00:00")); // 10.
264  times.append(GTime("2008-01-12T04:00:00")); // 11.
265  times.append(GTime("2008-08-17T04:00:00")); // 12.
266  times.append(GTime("2009-04-20T08:49:33")); // 13. Rev. 796- 802
267  times.append(GTime("2009-10-19T19:38:18")); // 14. Rev. 857- 862
268  times.append(GTime("2010-03-30T09:52:05")); // 15. Rev. 911- 916
269  times.append(GTime("2010-10-10T19:44:20")); // 16. Rev. 976- 981
270  times.append(GTime("2011-04-26T06:35:08")); // 17. Rev. 1042-1047
271  times.append(GTime("2011-11-21T15:36:48")); // 18. Rev. 1112-1118
272  times.append(GTime("2012-06-06T01:30:06")); // 19. Rev. 1178-1183
273  times.append(GTime("2013-01-04T10:32:36")); // 20. Rev. 1249-1253
274  times.append(GTime("2013-08-01T21:00:00")); // 21. Rev. 1319-1324
275  times.append(GTime("2014-01-07T08:32:20")); // 22. Rev. 1372-1377
276  times.append(GTime("2014-08-28T16:05:05")); // 23. Rev. 1450-1453
277  times.append(GTime("2015-02-15T12:54:04")); // 24. Rev. 1508-1512
278  times.append(GTime("2015-09-08T09:17:16")); // 25. Rev. 1585-1590
279  times.append(GTime("2016-03-04T11:23:26")); // 26. Rev. 1652-1656
280  times.append(GTime("2016-07-23T11:19:51")); // 27. Rev. 1705-1710
281  times.append(GTime("2017-01-14T23:26:20")); // 28. Rev. 1771-1776
282  times.append(GTime("2017-07-25T09:56:01")); // 29. Rev. 1843-1848
283  times.append(GTime("2018-01-27T14:29:29")); // 30. Rev. 1913-1918
284  times.append(GTime("2018-07-22T00:28:13")); // 31. Rev. 1979-1984
285  times.append(GTime("2019-01-21T13:31:40")); // 32. Rev. 2048-2053
286  times.append(GTime("2019-09-23T01:41:56")); // 33. Rev. 2140-2145
287  times.append(GTime("2020-03-05T21:56:30")); // 34. Rev. 2202-2207
288 
289  // Return times
290  return times;
291 }
292 
293 
294 /***********************************************************************//**
295  * @brief Return times of detector failures
296  *
297  * @return Times of detector failures.
298  *
299  * Returns the times of detector failures.
300  ***************************************************************************/
302 {
303  // Allocates times
304  GTimes times;
305 
306  // Set detector failure times
307  times.append(GTime("2003-12-06T09:58:30")); // Detector #2
308  times.append(GTime("2004-07-17T11:00:00")); // Detector #17
309  times.append(GTime("2009-02-19T12:00:00")); // Detector #5
310  times.append(GTime("2010-05-27T16:00:00")); // Detector #1
311 
312  // Return times
313  return times;
314 }
GTimes spi_gedfail_times(void)
Return times of detector failures.
Definition: GSPITools.cpp:301
bool has_card(const int &cardno) const
Check existence of header card.
Definition: GFitsHDU.hpp:233
Abstract FITS extension base class.
Definition: GFitsHDU.hpp:51
const GFilename & filename(void) const
Return FITS filename.
Definition: GFits.hpp:313
Time class.
Definition: GTime.hpp:55
FITS file class.
Definition: GFits.hpp:63
int spi_num_hdus(const GFits &fits, const std::string &extname)
Return number of HDU versions.
Definition: GSPITools.cpp:166
FITS file class interface definition.
GTimes spi_annealing_start_times(void)
Return start time of annealing operations.
Definition: GSPITools.cpp:248
Time container class.
Definition: GTimes.hpp:45
GTime spi_ijd2time(const double &ijd)
Convert IJD to GTime.
Definition: GSPITools.cpp:225
std::string path(void) const
Return access path.
Definition: GFilename.hpp:217
const GFitsTable * spi_hdu(const GFits &fits, const std::string &extname, const int &extver=1)
Return FITS table.
Definition: GSPITools.cpp:57
Abstract interface for FITS table.
Definition: GFitsTable.hpp:44
int integer(const std::string &keyname) const
Return card value as integer.
Definition: GFitsHDU.hpp:436
const std::string & extname(void) const
Return extension name.
Definition: GFitsHDU.hpp:162
const int & nrows(void) const
Return number of rows in table.
Definition: GFitsTable.hpp:119
int size(void) const
Return number of HDUs in FITS file.
Definition: GFits.hpp:237
std::string string(const std::string &keyname) const
Return card value as string.
Definition: GFitsHDU.hpp:410
virtual GFitsTable * clone(void) const =0
Clones object.
double mjd(void) const
Return time in Modified Julian Days (TT)
Definition: GTime.cpp:320
std::string filepath(const std::string &pathname, const std::string &filename)
Build file path from path name and file name.
Definition: GTools.cpp:393
Definition of INTEGRAL/SPI tools.
void append(const GTime &time)
Append time to container.
Definition: GTimes.cpp:216
FITS table abstract base class interface definition.