Commit e059bed749781f3849a5ff3e0a283f00f8e4e359
1 parent
fe605e26
implement effective area access
Showing
4 changed files
with
125 additions
and
12 deletions
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& obsDir, const double& 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& obsDir, const double& 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& 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& 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& 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 | } | ... | ... |