Commit e059bed749781f3849a5ff3e0a283f00f8e4e359

Authored by knodlseder
1 parent fe605e26

implement effective area access

include/GLATResponse.hpp
... ... @@ -58,6 +58,9 @@ public:
58 58 const GSkyDir& srcDir, const double& srcEng,
59 59 const GSkyDir& instPntDir, const double& instPosAng,
60 60 const double& time);
  61 + double aeff(const double& logE, const double& ctheta);
  62 + void aeff_ctheta_min(const double& ctheta);
  63 + double aeff_ctheta_min(void) const;
61 64  
62 65 // PSF Methods
63 66 double psf(const GSkyDir& obsDir, const double& obsEng,
... ... @@ -112,7 +115,9 @@ private:
112 115 GVector get_fits_vector(const GFitsHDU* hdu, const std::string& colname, int row = 0);
113 116  
114 117 // Private Aeff data
115   - GLATResponseTable m_aeff_bins; //!< Aeff energy and cos theta binning
  118 + GLATResponseTable m_aeff_bins; //!< Aeff energy and cos theta binning
  119 + double* m_aeff; //!< Aeff array
  120 + double m_aeff_ctheta_min; //!< Minimum valid cos(theta)
116 121  
117 122 // Private PSF data
118 123 GLATResponseTable m_psf_bins; //!< PSF energy and cos theta binning
... ...
include/GLATResponseTable.hpp
... ... @@ -56,6 +56,10 @@ public:
56 56 double energy(const int& ie) const;
57 57 int num_energy(void) const { return m_energy_num; }
58 58 int num_ctheta(void) const { return m_ctheta_num; }
  59 + double energy_lo(const int& inx) const { return m_energy_lo[inx]; }
  60 + double energy_hi(const int& inx) const { return m_energy_hi[inx]; }
  61 + double ctheta_lo(const int& inx) const { return m_ctheta_lo[inx]; }
  62 + double ctheta_hi(const int& inx) const { return m_ctheta_hi[inx]; }
59 63  
60 64 private:
61 65 // Methods
... ...
pyext/GLATResponse.i
... ... @@ -34,26 +34,36 @@ public:
34 34 GLATResponse(const GLATResponse& rsp);
35 35 ~GLATResponse();
36 36  
37   - // Methods
  37 + // IRF Methods
38 38 double irf(const GSkyDir& obsDir, const double& obsEng,
39 39 const GSkyDir& srcDir, const double& srcEng,
40 40 const GSkyDir& instPntDir, const double& instPosAng,
41 41 const double& time);
42   - double psf(const GSkyDir& obsDir, const double& obsEng,
  42 + // Aeff Methods
  43 + double aeff(const GSkyDir& obsDir, const double& obsEng,
43 44 const GSkyDir& srcDir, const double& srcEng,
44 45 const GSkyDir& instPntDir, const double& instPosAng,
45 46 const double& time);
46   - double psf(const double& delta, const double& logE, const double& ctheta);
47   - GVector psf(const GVector& delta, const double& logE, const double& ctheta);
48   - double aeff(const GSkyDir& obsDir, const double& obsEng,
  47 + double aeff(const double& logE, const double& ctheta);
  48 + void aeff_ctheta_min(const double& ctheta);
  49 + double aeff_ctheta_min(void) const;
  50 +
  51 + // PSF Methods
  52 + double psf(const GSkyDir& obsDir, const double& obsEng,
49 53 const GSkyDir& srcDir, const double& srcEng,
50 54 const GSkyDir& instPntDir, const double& instPosAng,
51 55 const double& time);
  56 + double psf(const double& delta, const double& logE, const double& ctheta);
  57 + GVector psf(const GVector& delta, const double& logE, const double& ctheta);
  58 +
  59 + // Edisp Methods
52 60 double edisp(const GSkyDir& obsDir, const double& obsEng,
53 61 const GSkyDir& srcDir, const double& srcEng,
54 62 const GSkyDir& instPntDir, const double& instPosAng,
55 63 const double& time);
56   - void set_caldb(const std::string& caldb);
57   - void load(const std::string& rspname, const std::string& rsptype);
58   - void save(const std::string& rspname) const;
  64 +
  65 + // Other Methods
  66 + void set_caldb(const std::string& caldb);
  67 + void load(const std::string& rspname, const std::string& rsptype);
  68 + void save(const std::string& rspname) const;
59 69 };
... ...
src/rsp/GLATAeff.cpp
... ... @@ -66,6 +66,50 @@ double GLATResponse::aeff(const GSkyDir&amp; obsDir, const double&amp; obsEng,
66 66 }
67 67  
68 68  
  69 +/***********************************************************************//**
  70 + * @brief Return effective area in units of cm2
  71 + *
  72 + * @param[in] logE Logarithm of the true photon energy (MeV).
  73 + * @param[in] ctheta Cosine of the zenith angle with respect to the pointing
  74 + * axis.
  75 + ***************************************************************************/
  76 +double GLATResponse::aeff(const double& logE, const double& ctheta)
  77 +{
  78 + // Get effective area value
  79 + double aeff = (ctheta >= m_aeff_ctheta_min)
  80 + ? m_aeff_bins.interpolate(logE, ctheta, m_aeff) : 0.0;
  81 +
  82 + // Return effective area value
  83 + return aeff;
  84 +}
  85 +
  86 +
  87 +/***********************************************************************//**
  88 + * @brief Set minimum cos(theta) angle for effective area access
  89 + *
  90 + * @param[in] ctheta Cosine of the maximum zenith angle for which effective
  91 + * areas will be returned (0 is returned for larger values)
  92 + ***************************************************************************/
  93 +void GLATResponse::aeff_ctheta_min(const double& ctheta)
  94 +{
  95 + // Set minimum cos(theta) value
  96 + m_aeff_ctheta_min = ctheta;
  97 +
  98 + // Return
  99 + return;
  100 +}
  101 +
  102 +
  103 +/***********************************************************************//**
  104 + * @brief Get minimum cos(theta) angle for effective area access
  105 + ***************************************************************************/
  106 +double GLATResponse::aeff_ctheta_min(void) const
  107 +{
  108 + // Return minimum cos(theta) value
  109 + return m_aeff_ctheta_min;
  110 +}
  111 +
  112 +
69 113 /*==========================================================================
70 114 = =
71 115 = Private methods =
... ... @@ -74,6 +118,8 @@ double GLATResponse::aeff(const GSkyDir&amp; obsDir, const double&amp; obsEng,
74 118  
75 119 /***********************************************************************//**
76 120 * @brief Initialise effective area
  121 + *
  122 + * The effective area is converted into units of cm2.
77 123 ***************************************************************************/
78 124 void GLATResponse::aeff_init(void)
79 125 {
... ... @@ -92,8 +138,23 @@ void GLATResponse::aeff_init(void)
92 138 // Get the energy and cos(theta) bins
93 139 m_aeff_bins.load(hdu);
94 140  
95   - // Get the data
96   - GVector effarea = get_fits_vector(hdu, "EFFAREA");
  141 + // Allocate memory for effective area
  142 + int size = m_aeff_bins.num_energy() * m_aeff_bins.num_ctheta();
  143 + if (size > 0)
  144 + m_aeff = new double[size];
  145 +
  146 + // Get pointer to effective area column
  147 + GFitsTableCol* ptr = hdu->column("EFFAREA");
  148 + if (ptr == NULL)
  149 + throw GException::fits_column_not_found(G_INIT_AEFF, "EFFAREA");
  150 +
  151 + // Copy data and convert from m2 into cm2
  152 + int num = ptr->number();
  153 + for (int i = 0; i < num; ++i)
  154 + m_aeff[i] = ptr->real(0,i) * 1.0e4;
  155 +
  156 + // Set minimum cos(theta)
  157 + m_aeff_ctheta_min = m_aeff_bins.ctheta_lo(0);
97 158  
98 159 // Return
99 160 return;
... ... @@ -116,8 +177,20 @@ void GLATResponse::aeff_append(GFits&amp; file) const
116 177 m_aeff_bins.save(&hdu_bounds);
117 178 hdu_bounds.extname("ABOUNDS");
118 179  
  180 + // Build effective area image
  181 + int naxes[] = {m_aeff_bins.num_energy(), m_aeff_bins.num_ctheta()};
  182 + GFitsDblImage image_aeff(2, naxes, m_aeff);
  183 +
  184 + // Construct effective area HDU
  185 + GFitsHDU hdu_aeff(image_aeff);
  186 + hdu_aeff.extname("AEFF");
  187 + hdu_aeff.header()->update(GFitsHeaderCard("CTYPE1", "Energy", "Energy binning"));
  188 + hdu_aeff.header()->update(GFitsHeaderCard("CTYPE2", "cos(theta)", "cos(theta) binning"));
  189 + hdu_aeff.header()->update(GFitsHeaderCard("BUNIT", "cm2", "Pixel unit"));
  190 +
119 191 // Append HDUs to FITS file
120 192 file.append_hdu(hdu_bounds);
  193 + file.append_hdu(hdu_aeff);
121 194  
122 195 // Return
123 196 return;
... ... @@ -130,7 +203,9 @@ void GLATResponse::aeff_append(GFits&amp; file) const
130 203 void GLATResponse::aeff_init_members(void)
131 204 {
132 205 // Initialise Aeff members
133   -
  206 + m_aeff_ctheta_min = 0.0;
  207 + m_aeff = NULL;
  208 +
134 209 // Return
135 210 return;
136 211 }
... ... @@ -141,6 +216,19 @@ void GLATResponse::aeff_init_members(void)
141 216 ***************************************************************************/
142 217 void GLATResponse::aeff_copy_members(const GLATResponse& rsp)
143 218 {
  219 + // Copy attributes
  220 + m_aeff_bins = rsp.m_aeff_bins;
  221 + m_aeff_ctheta_min = rsp.m_aeff_ctheta_min;
  222 +
  223 + // Copy effective area array
  224 + if (rsp.m_aeff != NULL) {
  225 + int size = m_aeff_bins.num_energy() * m_aeff_bins.num_ctheta();
  226 + if (size > 0) {
  227 + m_aeff = new double[size];
  228 + memcpy(m_aeff, rsp.m_aeff, size*sizeof(double));
  229 + }
  230 + }
  231 +
144 232 // Return
145 233 return;
146 234 }
... ... @@ -151,6 +239,12 @@ void GLATResponse::aeff_copy_members(const GLATResponse&amp; rsp)
151 239 ***************************************************************************/
152 240 void GLATResponse::aeff_free_members(void)
153 241 {
  242 + // Free effective area memory
  243 + if (m_aeff != NULL) delete [] m_aeff;
  244 +
  245 + // Signal that effective area memory is free
  246 + m_aeff = NULL;
  247 +
154 248 // Return
155 249 return;
156 250 }
... ...