GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GLATPsfV3.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GLATPsfV3.cpp - Fermi/LAT point spread function version 3 class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2012-2018 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 GLATPsfV3.cpp
23  * @brief Fermi/LAT point spread function version 3 class implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "GLATPsfV3.hpp"
32 #include "GLATException.hpp"
33 #include "GMath.hpp"
34 #include "GFitsBinTable.hpp"
35 #include "GFitsTableFloatCol.hpp"
36 #include "GIntegral.hpp"
37 
38 /* __ Method name definitions ____________________________________________ */
39 #define G_READ "GLATPsfV3::read(GFitsTable&)"
40 
41 /* __ Macros _____________________________________________________________ */
42 
43 /* __ Coding definitions _________________________________________________ */
44 //#define G_APPROXIMATE_PSF_INTEGRAL //!< Use approximate PSF integral
45 
46 /* __ Debug definitions __________________________________________________ */
47 //#define G_CHECK_PSF_NORM //!< Check PSF normalization
48 
49 /* __ Constants __________________________________________________________ */
50 
51 
52 /*==========================================================================
53  = =
54  = Constructors/destructors =
55  = =
56  ==========================================================================*/
57 
58 /***********************************************************************//**
59  * @brief Void constructor
60  ***************************************************************************/
62 {
63  // Initialise class members
64  init_members();
65 
66  // Return
67  return;
68 }
69 
70 
71 /***********************************************************************//**
72  * @brief Copy constructor
73  *
74  * @param[in] psf Point spread function.
75  ***************************************************************************/
77 {
78  // Initialise class members
79  init_members();
80 
81  // Copy members
82  copy_members(psf);
83 
84  // Return
85  return;
86 }
87 
88 
89 /***********************************************************************//**
90  * @brief Destructor
91  ***************************************************************************/
93 {
94  // Free members
95  free_members();
96 
97  // Return
98  return;
99 }
100 
101 
102 /*==========================================================================
103  = =
104  = Operators =
105  = =
106  ==========================================================================*/
107 
108 /***********************************************************************//**
109  * @brief Assignment operator
110  *
111  * @param[in] psf Point spread function.
112  * @return Point spread function.
113  ***************************************************************************/
115 {
116  // Execute only if object is not identical
117  if (this != &psf) {
118 
119  // Copy base class members
120  this->GLATPsfBase::operator=(psf);
121 
122  // Free members
123  free_members();
124 
125  // Initialise private members
126  init_members();
127 
128  // Copy members
129  copy_members(psf);
130 
131  } // endif: object was not identical
132 
133  // Return this object
134  return *this;
135 }
136 
137 
138 /*==========================================================================
139  = =
140  = Public methods =
141  = =
142  ==========================================================================*/
143 
144 /***********************************************************************//**
145  * @brief Clear point spread function
146  ***************************************************************************/
148 {
149  // Free class members (base and derived classes, derived class first)
150  free_members();
152 
153  // Initialise members
155  init_members();
156 
157  // Return
158  return;
159 }
160 
161 
162 /***********************************************************************//**
163  * @brief Clone point spread function
164  *
165  * @return Pointer to deep copy of point spread function
166  ***************************************************************************/
168 {
169  return new GLATPsfV3(*this);
170 }
171 
172 
173 /***********************************************************************//**
174  * @brief Read point spread function from FITS table
175  *
176  * @param[in] table FITS table.
177  *
178  * @exception GLATException::inconsistent_response
179  * Inconsistent response table encountered
180  *
181  * Reads point spread function information from FITS HDU. In addition to the
182  * energy and costheta binning information, 6 columns are expected:
183  * NCORE, NTAIL, SCORE, STAIL, GCORE, and GTAIL.
184  *
185  * The method assures that NCORE is set properly for each energy and
186  * cos(theta) bin so that the integral over the PSF amount to unity. This
187  * normalization is done by the method normalize_psf.
188  ***************************************************************************/
189 void GLATPsfV3::read(const GFitsTable& table)
190 {
191  // Clear arrays
192  m_ncore.clear();
193  m_ntail.clear();
194  m_score.clear();
195  m_stail.clear();
196  m_gcore.clear();
197  m_gtail.clear();
198 
199  // Get energy and cos theta binning
200  m_rpsf_bins.read(table);
201 
202  // Set minimum cos(theta)
204 
205  // Continue only if there are bins
206  int size = m_rpsf_bins.size();
207  if (size > 0) {
208 
209  // Allocate arrays
210  m_ncore.reserve(size);
211  m_ntail.reserve(size);
212  m_score.reserve(size);
213  m_stail.reserve(size);
214  m_gcore.reserve(size);
215  m_gtail.reserve(size);
216 
217  // Get pointer to columns
218  const GFitsTableCol* ncore = table["NCORE"];
219  const GFitsTableCol* ntail = table["NTAIL"];
220  const GFitsTableCol* score = table["SCORE"];
221  const GFitsTableCol* stail = table["STAIL"];
222  const GFitsTableCol* gcore = table["GCORE"];
223  const GFitsTableCol* gtail = table["GTAIL"];
224 
225  // Check consistency of columns
226  if (ncore->number() != size) {
228  ncore->number(), size);
229  }
230  if (ntail->number() != size) {
232  ntail->number(), size);
233  }
234  if (score->number() != size) {
236  score->number(), size);
237  }
238  if (stail->number() != size) {
240  stail->number(), size);
241  }
242  if (gcore->number() != size) {
244  gcore->number(), size);
245  }
246  if (gtail->number() != size) {
248  gtail->number(), size);
249  }
250 
251  // Copy data
252  for (int i = 0; i < size; ++i) {
253  m_ncore.push_back(ncore->real(0,i));
254  m_ntail.push_back(ntail->real(0,i));
255  m_score.push_back(score->real(0,i));
256  m_stail.push_back(stail->real(0,i));
257  m_gcore.push_back(gcore->real(0,i));
258  m_gtail.push_back(gtail->real(0,i));
259  }
260 
261  // Normalize PSF for all parameters
262  normalize_psf();
263 
264  } // endif: there were bins
265 
266  // Return
267  return;
268 }
269 
270 
271 /***********************************************************************//**
272  * @brief Write point spread function into FITS file
273  *
274  * @param[in] file FITS file.
275  *
276  * Writes the PSF into the extension "RPSF" of a FITS file. This method
277  * does not check if a "RPSF" extension exists so far, it simply adds one
278  * each time it is called.
279  *
280  * Nothing is done if the PSF size is 0.
281  *
282  * @todo Check if a RPSF extension exists already in FITS file
283  ***************************************************************************/
284 void GLATPsfV3::write(GFits& file) const
285 {
286  // Continue only if there are bins
287  int size = m_rpsf_bins.size();
288  if (size > 0) {
289 
290  // Create new binary table
291  GFitsBinTable* hdu_rpsf = new GFitsBinTable;
292 
293  // Set table attributes
294  hdu_rpsf->extname("RPSF");
295 
296  // Write boundaries into table
297  m_rpsf_bins.write(*hdu_rpsf);
298 
299  // Allocate floating point vector columns
300  GFitsTableFloatCol col_ncore = GFitsTableFloatCol("NCORE", 1, size);
301  GFitsTableFloatCol col_ntail = GFitsTableFloatCol("NTAIL", 1, size);
302  GFitsTableFloatCol col_score = GFitsTableFloatCol("SCORE", 1, size);
303  GFitsTableFloatCol col_stail = GFitsTableFloatCol("STAIL", 1, size);
304  GFitsTableFloatCol col_gcore = GFitsTableFloatCol("GCORE", 1, size);
305  GFitsTableFloatCol col_gtail = GFitsTableFloatCol("GTAIL", 1, size);
306 
307  // Fill columns
308  for (int i = 0; i < size; ++i) {
309  col_ncore(0,i) = m_ncore[i];
310  col_ntail(0,i) = m_ntail[i];
311  col_score(0,i) = m_score[i];
312  col_stail(0,i) = m_stail[i];
313  col_gcore(0,i) = m_gcore[i];
314  col_gtail(0,i) = m_gtail[i];
315  }
316 
317  // Append columns to table
318  hdu_rpsf->append(col_ncore);
319  hdu_rpsf->append(col_ntail);
320  hdu_rpsf->append(col_score);
321  hdu_rpsf->append(col_stail);
322  hdu_rpsf->append(col_gcore);
323  hdu_rpsf->append(col_gtail);
324 
325  // Set detector section
326  std::string detnam = (front()) ? "FRONT" : "BACK";
327 
328  // Set header keywords
329  hdu_rpsf->card("PSFVER", 3, "File format version");
330  hdu_rpsf->card("DETNAM", detnam, "Detector section");
331 
332  // Append HDU to FITS file
333  file.append(*hdu_rpsf);
334 
335  // Free binary table
336  delete hdu_rpsf;
337 
338  } // endif: there were data to write
339 
340  // Return
341  return;
342 }
343 
344 
345 /***********************************************************************//**
346  * @brief Return point spread function value
347  *
348  * @param[in] offset Offset angle (deg).
349  * @param[in] logE Log10 of the true photon energy (MeV).
350  * @param[in] ctheta Cosine of zenith angle.
351  *
352  * Evaluates point spread function by doing a bi-linear interpolation of
353  * PSF values obtained at the 4 corners that bound the specified energy and
354  * cos(theta) value.
355  *
356  * This method is inspired by the Fermi/LAT Science Tools method Psf3::value.
357  ***************************************************************************/
358 double GLATPsfV3::psf(const double& offset, const double& logE,
359  const double& ctheta)
360 {
361  // Initialise response
362  double psf = 0.0;
363 
364  // Compute point spread function
365  if (ctheta >= m_min_ctheta) {
366 
367  // Set interpolation indices and weights
368  m_rpsf_bins.set(logE, ctheta);
369 
370  // Recover information for interpolation
371  std::vector<int> index = m_rpsf_bins.indices();
372  std::vector<double> energy = m_rpsf_bins.energies();
373  std::vector<double> weight = m_rpsf_bins.weights();
374 
375  // Compute offset angle in radians
376  double offset_rad = offset * gammalib::deg2rad;
377 
378  // Compute PSF values for the four corners
379  double psf0 = eval_psf(offset_rad, energy[0], index[0]);
380  double psf1 = eval_psf(offset_rad, energy[1], index[1]);
381  double psf2 = eval_psf(offset_rad, energy[2], index[2]);
382  double psf3 = eval_psf(offset_rad, energy[3], index[3]);
383 
384  // Perform bi-linear interpolation
385  psf = weight[0] * psf0 + weight[1] * psf1 +
386  weight[2] * psf2 + weight[3] * psf3;
387 
388  } // endif: cos(theta) was in valid range
389 
390  // Return point spread function
391  return psf;
392 }
393 
394 
395 /***********************************************************************//**
396  * @brief Print point spread function
397  *
398  * @param[in] chatter Chattiness (defaults to NORMAL).
399  * @return String containing point spread function information.
400  ***************************************************************************/
401 std::string GLATPsfV3::print(const GChatter& chatter) const
402 {
403  // Initialise result string
404  std::string result;
405 
406  // Continue only if chatter is not silent
407  if (chatter != SILENT) {
408 
409  // Append header
410  result.append("=== GLATPsfV3 ===");
411 
412  } // endif: chatter was not silent
413 
414  // Return result
415  return result;
416 }
417 
418 
419 /*==========================================================================
420  = =
421  = Private methods =
422  = =
423  ==========================================================================*/
424 
425 /***********************************************************************//**
426  * @brief Initialise class members
427  ***************************************************************************/
429 {
430  // Initialise members
431  m_ncore.clear();
432  m_ntail.clear();
433  m_score.clear();
434  m_stail.clear();
435  m_gcore.clear();
436  m_gtail.clear();
437 
438  // Return
439  return;
440 }
441 
442 
443 /***********************************************************************//**
444  * @brief Copy class members
445  *
446  * @param[in] psf Point spread function.
447  ***************************************************************************/
449 {
450  // Copy members
451  m_ncore = psf.m_ncore;
452  m_ntail = psf.m_ntail;
453  m_score = psf.m_score;
454  m_stail = psf.m_stail;
455  m_gcore = psf.m_gcore;
456  m_gtail = psf.m_gtail;
457 
458  // Return
459  return;
460 }
461 
462 
463 /***********************************************************************//**
464  * @brief Delete class members
465  ***************************************************************************/
467 {
468  // Return
469  return;
470 }
471 
472 
473 /***********************************************************************//**
474  * @brief Return point spread base function value
475  *
476  * @param[in] u Function argument.
477  * @param[in] gamma Index.
478  *
479  * The version 3 PSF base function is given by
480  * \f[\left(1 - \frac{1}{\Gamma} \right)
481  * \left(1 + \frac{u}{\Gamma} \right)^{-\Gamma}\f]
482  ***************************************************************************/
483 double GLATPsfV3::base_fct(const double& u, const double& gamma)
484 {
485  // Get base function value. The special case of gamma==1 is a ugly
486  // kluge because of sloppy programming in handoff response when
487  // setting boundaries of fit parameters for the PSF.
488  double base = (gamma == 1)
489  ? (1.0 - 1.0/1.001) * std::pow(1.0 + u/1.001, -1.001)
490  : (1.0 - 1.0/gamma) * std::pow(1.0 + u/gamma, -gamma);
491 
492  // Return base function
493  return base;
494 }
495 
496 
497 /***********************************************************************//**
498  * @brief Return approximation of point spread base function integral
499  *
500  * @param[in] u Function argument.
501  * @param[in] gamma Index.
502  *
503  * The version 3 PSF base function integral is approximated by
504  * \f[1 - \left(1 + \frac{u}{\Gamma} \right)^{1-\Gamma}\f]
505  * which is valid for small angles \f$u\f$. For larger angles a numerical
506  * integration of the base function has to be performed.
507  *
508  * @todo Verify that 1+u/gamma is not negative
509  ***************************************************************************/
510 double GLATPsfV3::base_int(const double& u, const double& gamma)
511 {
512  // Compute integral of base function
513  double integral = 1.0 - std::pow(1.0 + u/gamma, 1.0 - gamma);
514 
515  // Return integral
516  return integral;
517 }
518 
519 
520 /***********************************************************************//**
521  * @brief Evaluate PSF for a specific set of parameters
522  *
523  * @param[in] offset Offset angle (radians).
524  * @param[in] energy Energy (MeV).
525  * @param[in] index Parameter array index.
526  *
527  * Evaluates PSF as function of offset angle and energy for a specific set
528  * of PSF parameters. The parameter set that is used is specified by the
529  * index parameter. The energy parameter only serves to scale the score and
530  * stail parameters of the PSF.
531  *
532  * This method is inspired from the Fermi/LAT Science Tools method
533  * Psf3::evaluate.
534  ***************************************************************************/
535 double GLATPsfV3::eval_psf(const double& offset, const double& energy,
536  const int& index)
537 {
538  // Get energy scaling
539  double scale = scale_factor(energy);
540 
541  // Get parameters
542  double ncore(m_ncore[index]);
543  double ntail(m_ntail[index]);
544  double score(m_score[index] * scale);
545  double stail(m_stail[index] * scale);
546  double gcore(m_gcore[index]);
547  double gtail(m_gtail[index]);
548 
549  // Compute argument
550  double rc = offset / score;
551  double uc = 0.5 * rc * rc;
552  double rt = offset / stail;
553  double ut = 0.5 * rt * rt;
554 
555  // Evaluate PSF
556  double psf = ncore * (base_fct(uc, gcore) + ntail * base_fct(ut, gtail));
557 
558  // Return PSF
559  return psf;
560 }
561 
562 
563 /***********************************************************************//**
564  * @brief Integrates PSF for a specific set of parameters
565  *
566  * @param[in] energy Energy (MeV).
567  * @param[in] index Parameter array index.
568  *
569  * Integrates PSF for a specific set of parameters.
570  *
571  * Compile option G_APPROXIMATE_PSF_INTEGRAL:
572  * If defined, a numerical PSF integral is only performed for energies
573  * < 120 MeV, while for larger energies the small angle approximation is
574  * used. In not defined, a numerical PSF integral is performed for all
575  * energies.
576  * This option is kept for comparison with the Fermi/LAT ScienceTools who
577  * select the integration method based on the true photon energy. As the
578  * normalization is only performed once upon loading of the PSF, CPU time
579  * is not really an issue here, and we can afford the more precise numerical
580  * integration. Note that the uncertainties of the approximation at energies
581  * near to 120 MeV reaches 0.1%.
582  *
583  * @todo Implement gcore and gtail checking
584  ***************************************************************************/
585 double GLATPsfV3::integrate_psf(const double& energy, const int& index)
586 {
587  // Initialise integral
588  double psf = 0.0;
589 
590  // Get energy scaling
591  double scale = scale_factor(energy);
592 
593  // Get parameters
594  double ncore(m_ncore[index]);
595  double ntail(m_ntail[index]);
596  double score(m_score[index] * scale);
597  double stail(m_stail[index] * scale);
598  double gcore(m_gcore[index]);
599  double gtail(m_gtail[index]);
600 
601  // Make sure that gcore and gtail are not negative
602  //if (gcore < 0 || gtail < 0) {
603  //}
604 
605  // Do we need an exact integral?
606  #if defined(G_APPROXIMATE_PSF_INTEGRAL)
607  if (energy < 120) {
608  #endif
609 
610  // Allocate integrand
611  GLATPsfV3::base_integrand integrand(ncore, ntail, score, stail, gcore, gtail);
612 
613  // Allocate integral
614  GIntegral integral(&integrand);
615 
616  // Integrate radially from 0 to 90 degrees
617  psf = integral.romberg(0.0, gammalib::pihalf) * gammalib::twopi;
618 
619  #if defined(G_APPROXIMATE_PSF_INTEGRAL)
620  } // endif: exact integral was performed
621 
622  // No, so we use the small angle approximation
623  else {
624 
625  // Compute arguments
626  double rc = gammalib::pihalf / score;
627  double uc = 0.5 * rc * rc;
628  double sc = gammalib::twopi * score * score;
629  double rt = gammalib::pihalf / stail;
630  double ut = 0.5 * rt * rt;
631  double st = gammalib::twopi * stail * stail;
632 
633  // Evaluate PSF integral (from 0 to 90 degrees)
634  psf = ncore * (base_int(uc, gcore) * sc +
635  base_int(ut, gtail) * st * ntail);
636 
637  }
638  #endif
639 
640  // Return PSF integral
641  return psf;
642 }
643 
644 
645 /***********************************************************************//**
646  * @brief Normalize PSF for all parameters
647  *
648  * Makes sure that PSF is normalized for all parameters. We assure this by
649  * looping over all parameter nodes, integrating the PSF for each set of
650  * parameters, and dividing the NCORE parameter by the integral.
651  *
652  * Compile option G_CHECK_PSF_NORM:
653  * If defined, checks that the PSF is normalized correctly.
654  ***************************************************************************/
656 {
657  // Loop over all energy bins
658  for (int ie = 0; ie < m_rpsf_bins.nenergies(); ++ie) {
659 
660  // Extract energy value (in MeV)
661  double energy = m_rpsf_bins.energy(ie);
662 
663  // Loop over all cos(theta) bins
664  for (int ic = 0; ic < m_rpsf_bins.ncostheta(); ++ic) {
665 
666  // Get parameter index
667  int index = m_rpsf_bins.index(ie, ic);
668 
669  // Integrate PSF
670  double norm = integrate_psf(energy, index);
671 
672  // Normalize PSF
673  m_ncore[index] /= norm;
674 
675  // Compile option: check PSF normalization
676  #if defined(G_CHECK_PSF_NORM)
677  double scale = scale_factor(energy);
678  double ncore(m_ncore[index]);
679  double ntail(m_ntail[index]);
680  double score(m_score[index] * scale);
681  double stail(m_stail[index] * scale);
682  double gcore(m_gcore[index]);
683  double gtail(m_gtail[index]);
684  GLATPsfV3::base_integrand integrand(ncore, ntail, score, stail, gcore, gtail);
685  GIntegral integral(&integrand);
686  double sum = integral.romberg(0.0, pihalf) * twopi;
687  std::cout << "Energy=" << energy;
688  std::cout << " cos(theta)=" << m_rpsf_bins.costheta_lo(ic);
689  std::cout << " error=" << sum-1.0 << std::endl;
690  #endif
691 
692  } // endfor: looped over cos(theta)
693 
694  } // endfor: looped over energies
695 
696  // Return
697  return;
698 }
std::vector< double > m_ncore
PSF ncore parameter.
Definition: GLATPsfV3.hpp:115
void number(const int &number)
Set number of elements in column.
GLATPsfV3 & operator=(const GLATPsfV3 &psf)
Assignment operator.
Definition: GLATPsfV3.cpp:114
double norm(const GVector &vector)
Computes vector norm.
Definition: GVector.cpp:821
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
Definition: GIntegral.cpp:380
void read(const GFitsTable &hdu)
Read response table from FITS table HDU.
void read(const GFitsTable &table)
Read point spread function from FITS table.
Definition: GLATPsfV3.cpp:189
void write(GFits &file) const
Write point spread function into FITS file.
Definition: GLATPsfV3.cpp:284
void free_members(void)
Delete class members.
Definition: GLATPsfV3.cpp:466
std::vector< double > energies(void) const
Return energies of 4 corners used for interpolation.
double sum(const GVector &vector)
Computes vector sum.
Definition: GVector.cpp:901
GFitsTableCol * append(const GFitsTableCol &column)
Append column to the table.
Definition: GFitsTable.hpp:147
void write(GFitsTable &hdu) const
Write response table into FITS table.
FITS table float column class interface definition.
GIntegral class interface definition.
Definition: GIntegral.hpp:45
FITS file class.
Definition: GFits.hpp:63
GLATPsfV3(void)
Void constructor.
Definition: GLATPsfV3.cpp:61
double scale_factor(const double &energy) const
Return scale factor for energy (in MeV)
double psf(const double &offset, const double &logE, const double &ctheta)
Return point spread function value.
Definition: GLATPsfV3.cpp:358
const double pihalf
Definition: GMath.hpp:38
const double deg2rad
Definition: GMath.hpp:43
std::vector< double > m_gtail
PSF gtail parameter.
Definition: GLATPsfV3.hpp:120
Fermi/LAT point spread function version 3 class definition.
static double base_int(const double &u, const double &gamma)
Return approximation of point spread base function integral.
Definition: GLATPsfV3.cpp:510
double integrate_psf(const double &energy, const int &index)
Integrates PSF for a specific set of parameters.
Definition: GLATPsfV3.cpp:585
void free_members(void)
Delete class members.
Abstract Fermi/LAT point spread function base class.
Definition: GLATPsfBase.hpp:47
const int & nenergies(void) const
Return number of energies in response table.
LAT exception handler interface definition.
Abstract interface for FITS table column.
std::vector< double > m_score
PSF score parameter.
Definition: GLATPsfV3.hpp:117
virtual ~GLATPsfV3(void)
Destructor.
Definition: GLATPsfV3.cpp:92
std::vector< double > m_ntail
PSF ntail parameter.
Definition: GLATPsfV3.hpp:116
const int & ncostheta(void) const
Return number of cosine theta bins in response table.
Abstract interface for FITS table.
Definition: GFitsTable.hpp:44
GChatter
Definition: GTypemaps.hpp:33
double eval_psf(const double &offset, const double &energy, const int &index)
Evaluate PSF for a specific set of parameters.
Definition: GLATPsfV3.cpp:535
void init_members(void)
Initialise class members.
const std::string & extname(void) const
Return extension name.
Definition: GFitsHDU.hpp:162
double m_min_ctheta
Minimum valid cos(theta)
Definition: GLATPsfBase.hpp:97
GLATPsfBase & operator=(const GLATPsfBase &psf)
Assignment operator.
#define G_READ
Definition: GLATPsfV3.cpp:39
GLATResponseTable m_rpsf_bins
PSF energy and cos theta binning.
Definition: GLATPsfBase.hpp:93
void set(const double &logE, const double &ctheta)
Set indices and weighting for bi-linear interpolation of 2D array.
int index(const int &ie, const int &ic) const
Return table index.
virtual double real(const int &row, const int &inx=0) const =0
FITS binary table class.
GVector pow(const GVector &vector, const double &power)
Computes tanh of vector elements.
Definition: GVector.cpp:1332
int size(void) const
Return number of bins in point spread function.
std::vector< double > m_gcore
PSF gcore parameter.
Definition: GLATPsfV3.hpp:119
void init_members(void)
Initialise class members.
Definition: GLATPsfV3.cpp:428
GFitsHDU * append(const GFitsHDU &hdu)
Append HDU to FITS file.
Definition: GFits.cpp:665
void copy_members(const GLATPsfV3 &psf)
Copy class members.
Definition: GLATPsfV3.cpp:448
FITS binary table class definition.
void normalize_psf(void)
Normalize PSF for all parameters.
Definition: GLATPsfV3.cpp:655
double costheta_lo(const int &inx) const
Return lower bin cos theta.
FITS table float column.
std::vector< double > m_stail
PSF stail parameter.
Definition: GLATPsfV3.hpp:118
const double twopi
Definition: GMath.hpp:36
static double base_fct(const double &u, const double &gamma)
Return point spread base function value.
Definition: GLATPsfV3.cpp:483
double energy(const int &ie) const
Return mean energy of bin (units: MeV)
Integration class interface definition.
GFitsHeaderCard & card(const int &cardno)
Return header card.
Definition: GFitsHDU.hpp:259
std::vector< double > weights(void) const
Return weights of 4 corners used for interpolation.
const bool & front(void) const
Signal that point spread function is for front section.
int size(void) const
Return number of bins in response table.
GLATPsfV3 * clone(void) const
Clone point spread function.
Definition: GLATPsfV3.cpp:167
void clear(void)
Clear point spread function.
Definition: GLATPsfV3.cpp:147
std::string print(const GChatter &chatter=NORMAL) const
Print point spread function.
Definition: GLATPsfV3.cpp:401
Mathematical function definitions.
std::vector< int > indices(void) const
Return indices of 4 corners used for interpolation.
Fermi/LAT point spread function version 3 class.
Definition: GLATPsfV3.hpp:51