Commit 233655feb51273e5495f63ab6f862c125474e95c
1 parent
19469fd7
Make use of effective area classes in response.
The CTA response class makes now use of the GCTAAeff classes to handle the effective area response. The GCTAResponse::load_aeff() method automatically detects the response type, allocates the appropriate GCTAAeff derived class, and loads the response information. The GCTAObservation::read() and GCTAObservation::write() method also handle now transparently all 3 effective area response formats. Only the effective area correction for ARF response files is not yet implemented. This will be done once the response factorization has also be applied for the point spread function.
Showing
15 changed files
with
400 additions
and
359 deletions
inst/cta/include/GCTAAeff.hpp
| @@ -52,6 +52,8 @@ public: | @@ -52,6 +52,8 @@ public: | ||
| 52 | virtual double operator()(const double& logE, | 52 | virtual double operator()(const double& logE, |
| 53 | const double& theta = 0.0, | 53 | const double& theta = 0.0, |
| 54 | const double& phi = 0.0, | 54 | const double& phi = 0.0, |
| 55 | + const double& zenith = 0.0, | ||
| 56 | + const double& azimuth = 0.0, | ||
| 55 | const bool& etrue = true) const = 0; | 57 | const bool& etrue = true) const = 0; |
| 56 | 58 | ||
| 57 | // Operators | 59 | // Operators |
| @@ -61,6 +63,7 @@ public: | @@ -61,6 +63,7 @@ public: | ||
| 61 | virtual void clear(void) = 0; | 63 | virtual void clear(void) = 0; |
| 62 | virtual GCTAAeff* clone(void) const = 0; | 64 | virtual GCTAAeff* clone(void) const = 0; |
| 63 | virtual void load(const std::string& filename) = 0; | 65 | virtual void load(const std::string& filename) = 0; |
| 66 | + virtual std::string filename(void) const = 0; | ||
| 64 | virtual std::string print(void) const = 0; | 67 | virtual std::string print(void) const = 0; |
| 65 | 68 | ||
| 66 | protected: | 69 | protected: |
inst/cta/include/GCTAAeff2D.hpp
| @@ -56,12 +56,15 @@ public: | @@ -56,12 +56,15 @@ public: | ||
| 56 | double operator()(const double& logE, | 56 | double operator()(const double& logE, |
| 57 | const double& theta = 0.0, | 57 | const double& theta = 0.0, |
| 58 | const double& phi = 0.0, | 58 | const double& phi = 0.0, |
| 59 | + const double& zenith = 0.0, | ||
| 60 | + const double& azimuth = 0.0, | ||
| 59 | const bool& etrue = true) const; | 61 | const bool& etrue = true) const; |
| 60 | 62 | ||
| 61 | // Implemented pure virtual methods | 63 | // Implemented pure virtual methods |
| 62 | void clear(void); | 64 | void clear(void); |
| 63 | GCTAAeff2D* clone(void) const; | 65 | GCTAAeff2D* clone(void) const; |
| 64 | void load(const std::string& filename); | 66 | void load(const std::string& filename); |
| 67 | + std::string filename(void) const; | ||
| 65 | std::string print(void) const; | 68 | std::string print(void) const; |
| 66 | 69 | ||
| 67 | // Methods | 70 | // Methods |
| @@ -74,7 +77,8 @@ private: | @@ -74,7 +77,8 @@ private: | ||
| 74 | void free_members(void); | 77 | void free_members(void); |
| 75 | 78 | ||
| 76 | // Members | 79 | // Members |
| 77 | - GCTAResponseTable m_aeff; //!< Aeff response table | 80 | + std::string m_filename; //!< Name of Aeff response file |
| 81 | + GCTAResponseTable m_aeff; //!< Aeff response table | ||
| 78 | }; | 82 | }; |
| 79 | 83 | ||
| 80 | #endif /* GCTAAEFF2D_HPP */ | 84 | #endif /* GCTAAEFF2D_HPP */ |
inst/cta/include/GCTAAeffArf.hpp
| @@ -58,18 +58,21 @@ public: | @@ -58,18 +58,21 @@ public: | ||
| 58 | double operator()(const double& logE, | 58 | double operator()(const double& logE, |
| 59 | const double& theta = 0.0, | 59 | const double& theta = 0.0, |
| 60 | const double& phi = 0.0, | 60 | const double& phi = 0.0, |
| 61 | + const double& zenith = 0.0, | ||
| 62 | + const double& azimuth = 0.0, | ||
| 61 | const bool& etrue = true) const; | 63 | const bool& etrue = true) const; |
| 62 | 64 | ||
| 63 | // Implemented pure virtual methods | 65 | // Implemented pure virtual methods |
| 64 | void clear(void); | 66 | void clear(void); |
| 65 | GCTAAeffArf* clone(void) const; | 67 | GCTAAeffArf* clone(void) const; |
| 66 | void load(const std::string& filename); | 68 | void load(const std::string& filename); |
| 69 | + std::string filename(void) const; | ||
| 67 | std::string print(void) const; | 70 | std::string print(void) const; |
| 68 | 71 | ||
| 69 | // Methods | 72 | // Methods |
| 70 | int size(void) const { return m_logE.size(); } | 73 | int size(void) const { return m_logE.size(); } |
| 71 | - void offset_sigma(const double& sigma) { m_offset_sigma=sigma; } | ||
| 72 | - const double& offset_sigma(void) const { return m_offset_sigma; } | 74 | + void sigma(const double& sigma) { m_sigma=sigma; } |
| 75 | + const double& sigma(void) const { return m_sigma; } | ||
| 73 | void thetacut(const double& thetacut) { m_thetacut=thetacut; } | 76 | void thetacut(const double& thetacut) { m_thetacut=thetacut; } |
| 74 | const double& thetacut(void) const { return m_thetacut; } | 77 | const double& thetacut(void) const { return m_thetacut; } |
| 75 | void scale(const double& scale) { m_scale=scale; } | 78 | void scale(const double& scale) { m_scale=scale; } |
| @@ -83,11 +86,12 @@ private: | @@ -83,11 +86,12 @@ private: | ||
| 83 | void free_members(void); | 86 | void free_members(void); |
| 84 | 87 | ||
| 85 | // Members | 88 | // Members |
| 86 | - GNodeArray m_logE; //!< log(E) nodes for Aeff interpolation | ||
| 87 | - std::vector<double> m_aeff; //!< Effective area in cm2 | ||
| 88 | - double m_offset_sigma; //!< Sigma for offset angle computation (0=none) | ||
| 89 | - double m_thetacut; //!< Theta cut for ARF | ||
| 90 | - double m_scale; //!< Scale for ARF | 89 | + std::string m_filename; //!< Name of Aeff response file |
| 90 | + GNodeArray m_logE; //!< log(E) nodes for Aeff interpolation | ||
| 91 | + std::vector<double> m_aeff; //!< Effective area in cm2 | ||
| 92 | + double m_sigma; //!< Sigma for offset angle computation (0=none) | ||
| 93 | + double m_thetacut; //!< Theta cut for ARF | ||
| 94 | + double m_scale; //!< Scale for ARF | ||
| 91 | }; | 95 | }; |
| 92 | 96 | ||
| 93 | #endif /* GCTAAEFFARF_HPP */ | 97 | #endif /* GCTAAEFFARF_HPP */ |
inst/cta/include/GCTAAeffPerfTable.hpp
| @@ -58,18 +58,21 @@ public: | @@ -58,18 +58,21 @@ public: | ||
| 58 | double operator()(const double& logE, | 58 | double operator()(const double& logE, |
| 59 | const double& theta = 0.0, | 59 | const double& theta = 0.0, |
| 60 | const double& phi = 0.0, | 60 | const double& phi = 0.0, |
| 61 | + const double& zenith = 0.0, | ||
| 62 | + const double& azimuth = 0.0, | ||
| 61 | const bool& etrue = true) const; | 63 | const bool& etrue = true) const; |
| 62 | 64 | ||
| 63 | // Implemented pure virtual methods | 65 | // Implemented pure virtual methods |
| 64 | void clear(void); | 66 | void clear(void); |
| 65 | GCTAAeffPerfTable* clone(void) const; | 67 | GCTAAeffPerfTable* clone(void) const; |
| 66 | void load(const std::string& filename); | 68 | void load(const std::string& filename); |
| 69 | + std::string filename(void) const; | ||
| 67 | std::string print(void) const; | 70 | std::string print(void) const; |
| 68 | 71 | ||
| 69 | // Methods | 72 | // Methods |
| 70 | - int size(void) const { return m_logE.size(); } | ||
| 71 | - void offset_sigma(const double& sigma) { m_offset_sigma=sigma; } | ||
| 72 | - const double& offset_sigma(void) const { return m_offset_sigma; } | 73 | + int size(void) const { return m_logE.size(); } |
| 74 | + void sigma(const double& sigma) { m_sigma=sigma; } | ||
| 75 | + const double& sigma(void) const { return m_sigma; } | ||
| 73 | 76 | ||
| 74 | private: | 77 | private: |
| 75 | // Methods | 78 | // Methods |
| @@ -78,9 +81,10 @@ private: | @@ -78,9 +81,10 @@ private: | ||
| 78 | void free_members(void); | 81 | void free_members(void); |
| 79 | 82 | ||
| 80 | // Members | 83 | // Members |
| 81 | - GNodeArray m_logE; //!< log(E) nodes for Aeff interpolation | ||
| 82 | - std::vector<double> m_aeff; //!< Effective area in cm2 | ||
| 83 | - double m_offset_sigma; //!< Sigma for offset angle computation (0=none) | 84 | + std::string m_filename; //!< Name of Aeff response file |
| 85 | + GNodeArray m_logE; //!< log(E) nodes for Aeff interpolation | ||
| 86 | + std::vector<double> m_aeff; //!< Effective area in cm2 | ||
| 87 | + double m_sigma; //!< Sigma for offset angle computation (0=none) | ||
| 84 | }; | 88 | }; |
| 85 | 89 | ||
| 86 | #endif /* GCTAAEFFPERFTABLE_HPP */ | 90 | #endif /* GCTAAEFFPERFTABLE_HPP */ |
inst/cta/include/GCTAResponse.hpp
| @@ -55,6 +55,7 @@ | @@ -55,6 +55,7 @@ | ||
| 55 | #include "GCTAEventAtom.hpp" | 55 | #include "GCTAEventAtom.hpp" |
| 56 | #include "GCTADir.hpp" | 56 | #include "GCTADir.hpp" |
| 57 | #include "GCTAResponseTable.hpp" | 57 | #include "GCTAResponseTable.hpp" |
| 58 | +#include "GCTAAeff.hpp" | ||
| 58 | 59 | ||
| 59 | /* __ Type definitions ___________________________________________________ */ | 60 | /* __ Type definitions ___________________________________________________ */ |
| 60 | typedef std::vector<double> GCTAPsfPars; | 61 | typedef std::vector<double> GCTAPsfPars; |
| @@ -136,26 +137,25 @@ public: | @@ -136,26 +137,25 @@ public: | ||
| 136 | const GObservation& obs) const; | 137 | const GObservation& obs) const; |
| 137 | 138 | ||
| 138 | // Other Methods | 139 | // Other Methods |
| 139 | - GCTAEventAtom* mc(const double& area, const GPhoton& photon, | ||
| 140 | - const GObservation& obs, GRan& ran) const; | ||
| 141 | - void caldb(const std::string& caldb); | ||
| 142 | - std::string caldb(void) const { return m_caldb; } | ||
| 143 | - void load(const std::string& rspname); | ||
| 144 | - void eps(const double& eps) { m_eps=eps; } | ||
| 145 | - const double& eps(void) const { return m_eps; } | ||
| 146 | - void offset_sigma(const double& sigma) { m_offset_sigma=sigma; } | ||
| 147 | - const double& offset_sigma(void) const { return m_offset_sigma; } | ||
| 148 | - std::string arffile(void) const { return m_arffile; } | ||
| 149 | - std::string rmffile(void) const { return m_rmffile; } | ||
| 150 | - std::string psffile(void) const { return m_psffile; } | ||
| 151 | - double arf_thetacut(void) const { return m_arf_thetacut; } | ||
| 152 | - double arf_scale(void) const { return m_arf_scale; } | ||
| 153 | - void arf_thetacut(const double& value) { m_arf_thetacut=value; } | ||
| 154 | - void arf_scale(const double& value) { m_arf_scale=value; } | ||
| 155 | - void load_arf(const std::string& filename); | ||
| 156 | - void load_psf(const std::string& filename); | ||
| 157 | - void read_arf(const GFitsTable* hdu); | ||
| 158 | - void read_psf(const GFitsTable* hdu); | 140 | + GCTAEventAtom* mc(const double& area, const GPhoton& photon, |
| 141 | + const GObservation& obs, GRan& ran) const; | ||
| 142 | + void caldb(const std::string& caldb); | ||
| 143 | + std::string caldb(void) const { return m_caldb; } | ||
| 144 | + void load(const std::string& rspname); | ||
| 145 | + void eps(const double& eps) { m_eps=eps; } | ||
| 146 | + const double& eps(void) const { return m_eps; } | ||
| 147 | + void offset_sigma(const double& sigma) { m_offset_sigma=sigma; } | ||
| 148 | + const double& offset_sigma(void) const { return m_offset_sigma; } | ||
| 149 | + std::string rmffile(void) const { return m_rmffile; } | ||
| 150 | + std::string psffile(void) const { return m_psffile; } | ||
| 151 | + void read_psf(const GFitsTable* hdu); | ||
| 152 | + | ||
| 153 | + // New factorisation | ||
| 154 | + void load_aeff(const std::string& filename); | ||
| 155 | + void load_psf(const std::string& filename); | ||
| 156 | + void load_edisp(const std::string& filename) {} | ||
| 157 | + const GCTAAeff* aeff(void) const { return m_aeff; } | ||
| 158 | + void aeff(GCTAAeff* aeff) { m_aeff=aeff; } | ||
| 159 | 159 | ||
| 160 | // Low-level response methods | 160 | // Low-level response methods |
| 161 | double aeff(const double& theta, | 161 | double aeff(const double& theta, |
| @@ -208,15 +208,10 @@ private: | @@ -208,15 +208,10 @@ private: | ||
| 208 | // Private data members | 208 | // Private data members |
| 209 | std::string m_caldb; //!< Name of or path to the calibration database | 209 | std::string m_caldb; //!< Name of or path to the calibration database |
| 210 | std::string m_rspname; //!< Name of the instrument response | 210 | std::string m_rspname; //!< Name of the instrument response |
| 211 | - std::string m_arffile; //!< Name of ARF file | ||
| 212 | std::string m_rmffile; //!< Name of RMF file | 211 | std::string m_rmffile; //!< Name of RMF file |
| 213 | std::string m_psffile; //!< Name of PSF file | 212 | std::string m_psffile; //!< Name of PSF file |
| 214 | - double m_arf_thetacut; //!< Theta cut for ARF | ||
| 215 | - double m_arf_scale; //!< Scale for ARF | ||
| 216 | GNodeArray m_psf_logE; //!< log(E) nodes for PSF interpolation | 213 | GNodeArray m_psf_logE; //!< log(E) nodes for PSF interpolation |
| 217 | - GNodeArray m_aeff_logE; //!< log(E) nodes for Aeff interpolation | ||
| 218 | std::vector<double> m_logE; //!< log(E) = log10(E/TeV) - bin centre | 214 | std::vector<double> m_logE; //!< log(E) = log10(E/TeV) - bin centre |
| 219 | - std::vector<double> m_aeff; //!< Effective area in cm2 after all cuts | ||
| 220 | std::vector<double> m_r68; //!< 68% containment radius of PSF post cuts in degrees | 215 | std::vector<double> m_r68; //!< 68% containment radius of PSF post cuts in degrees |
| 221 | std::vector<double> m_r80; //!< 80% containment radius of PSF post cuts in degrees | 216 | std::vector<double> m_r80; //!< 80% containment radius of PSF post cuts in degrees |
| 222 | double m_eps; //!< Integration precision | 217 | double m_eps; //!< Integration precision |
| @@ -225,6 +220,9 @@ private: | @@ -225,6 +220,9 @@ private: | ||
| 225 | // New PSF handling | 220 | // New PSF handling |
| 226 | int m_psf_version; //!< PSF version | 221 | int m_psf_version; //!< PSF version |
| 227 | GCTAResponseTable m_psf_table; //!< PSF response table | 222 | GCTAResponseTable m_psf_table; //!< PSF response table |
| 223 | + | ||
| 224 | + // New PSF factorisation | ||
| 225 | + GCTAAeff* m_aeff; //!< Effective area component | ||
| 228 | }; | 226 | }; |
| 229 | 227 | ||
| 230 | #endif /* GCTARESPONSE_HPP */ | 228 | #endif /* GCTARESPONSE_HPP */ |
inst/cta/pyext/GCTAAeff.i
| @@ -47,12 +47,15 @@ public: | @@ -47,12 +47,15 @@ public: | ||
| 47 | virtual double operator()(const double& logE, | 47 | virtual double operator()(const double& logE, |
| 48 | const double& theta = 0.0, | 48 | const double& theta = 0.0, |
| 49 | const double& phi = 0.0, | 49 | const double& phi = 0.0, |
| 50 | + const double& zenith = 0.0, | ||
| 51 | + const double& azimuth = 0.0, | ||
| 50 | const bool& etrue = true) const = 0; | 52 | const bool& etrue = true) const = 0; |
| 51 | 53 | ||
| 52 | // Pure virtual methods | 54 | // Pure virtual methods |
| 53 | - virtual void clear(void) = 0; | ||
| 54 | - virtual GCTAAeff* clone(void) const = 0; | ||
| 55 | - virtual void load(const std::string& filename) = 0; | 55 | + virtual void clear(void) = 0; |
| 56 | + virtual GCTAAeff* clone(void) const = 0; | ||
| 57 | + virtual void load(const std::string& filename) = 0; | ||
| 58 | + virtual std::string filename(void) const = 0; | ||
| 56 | }; | 59 | }; |
| 57 | 60 | ||
| 58 | 61 |
inst/cta/pyext/GCTAAeff2D.i
| @@ -49,12 +49,15 @@ public: | @@ -49,12 +49,15 @@ public: | ||
| 49 | double operator()(const double& logE, | 49 | double operator()(const double& logE, |
| 50 | const double& theta = 0.0, | 50 | const double& theta = 0.0, |
| 51 | const double& phi = 0.0, | 51 | const double& phi = 0.0, |
| 52 | + const double& zenith = 0.0, | ||
| 53 | + const double& azimuth = 0.0, | ||
| 52 | const bool& etrue = true) const; | 54 | const bool& etrue = true) const; |
| 53 | 55 | ||
| 54 | // Implemented pure virtual methods | 56 | // Implemented pure virtual methods |
| 55 | void clear(void); | 57 | void clear(void); |
| 56 | GCTAAeff2D* clone(void) const; | 58 | GCTAAeff2D* clone(void) const; |
| 57 | void load(const std::string& filename); | 59 | void load(const std::string& filename); |
| 60 | + std::string filename(void) const; | ||
| 58 | 61 | ||
| 59 | // Methods | 62 | // Methods |
| 60 | void read(const GFits* file); | 63 | void read(const GFits* file); |
inst/cta/pyext/GCTAAeffArf.i
| @@ -49,17 +49,20 @@ public: | @@ -49,17 +49,20 @@ public: | ||
| 49 | double operator()(const double& logE, | 49 | double operator()(const double& logE, |
| 50 | const double& theta = 0.0, | 50 | const double& theta = 0.0, |
| 51 | const double& phi = 0.0, | 51 | const double& phi = 0.0, |
| 52 | + const double& zenith = 0.0, | ||
| 53 | + const double& azimuth = 0.0, | ||
| 52 | const bool& etrue = true) const; | 54 | const bool& etrue = true) const; |
| 53 | 55 | ||
| 54 | // Implemented pure virtual methods | 56 | // Implemented pure virtual methods |
| 55 | void clear(void); | 57 | void clear(void); |
| 56 | GCTAAeffArf* clone(void) const; | 58 | GCTAAeffArf* clone(void) const; |
| 57 | void load(const std::string& filename); | 59 | void load(const std::string& filename); |
| 60 | + std::string filename(void) const; | ||
| 58 | 61 | ||
| 59 | // Methods | 62 | // Methods |
| 60 | int size(void) const; | 63 | int size(void) const; |
| 61 | - void offset_sigma(const double& sigma); | ||
| 62 | - const double& offset_sigma(void) const; | 64 | + void sigma(const double& sigma); |
| 65 | + const double& sigma(void) const; | ||
| 63 | void thetacut(const double& thetacut); | 66 | void thetacut(const double& thetacut); |
| 64 | const double& thetacut(void) const; | 67 | const double& thetacut(void) const; |
| 65 | void scale(const double& scale); | 68 | void scale(const double& scale); |
inst/cta/pyext/GCTAAeffPerfTable.i
| @@ -49,17 +49,20 @@ public: | @@ -49,17 +49,20 @@ public: | ||
| 49 | double operator()(const double& logE, | 49 | double operator()(const double& logE, |
| 50 | const double& theta = 0.0, | 50 | const double& theta = 0.0, |
| 51 | const double& phi = 0.0, | 51 | const double& phi = 0.0, |
| 52 | + const double& zenith = 0.0, | ||
| 53 | + const double& azimuth = 0.0, | ||
| 52 | const bool& etrue = true) const; | 54 | const bool& etrue = true) const; |
| 53 | 55 | ||
| 54 | // Implemented pure virtual methods | 56 | // Implemented pure virtual methods |
| 55 | void clear(void); | 57 | void clear(void); |
| 56 | GCTAAeffPerfTable* clone(void) const; | 58 | GCTAAeffPerfTable* clone(void) const; |
| 57 | void load(const std::string& filename); | 59 | void load(const std::string& filename); |
| 60 | + std::string filename(void) const; | ||
| 58 | 61 | ||
| 59 | // Methods | 62 | // Methods |
| 60 | int size(void) const; | 63 | int size(void) const; |
| 61 | - void offset_sigma(const double& sigma); | ||
| 62 | - const double& offset_sigma(void) const; | 64 | + void sigma(const double& sigma); |
| 65 | + const double& sigma(void) const; | ||
| 63 | }; | 66 | }; |
| 64 | 67 | ||
| 65 | 68 |
inst/cta/pyext/GCTAResponse.i
| @@ -85,26 +85,20 @@ public: | @@ -85,26 +85,20 @@ public: | ||
| 85 | const GObservation& obs) const; | 85 | const GObservation& obs) const; |
| 86 | 86 | ||
| 87 | // Other Methods | 87 | // Other Methods |
| 88 | - GCTAEventAtom* mc(const double& area, const GPhoton& photon, | ||
| 89 | - const GObservation& obs, GRan& ran) const; | ||
| 90 | - void caldb(const std::string& caldb); | ||
| 91 | - std::string caldb(void) const; | ||
| 92 | - void load(const std::string& rspname); | ||
| 93 | - void eps(const double& eps); | ||
| 94 | - const double& eps(void) const; | ||
| 95 | - void offset_sigma(const double& sigma); | ||
| 96 | - const double& offset_sigma(void) const; | ||
| 97 | - std::string arffile(void) const; | ||
| 98 | - std::string rmffile(void) const; | ||
| 99 | - std::string psffile(void) const; | ||
| 100 | - double arf_thetacut(void) const; | ||
| 101 | - double arf_scale(void) const; | ||
| 102 | - void arf_thetacut(const double& value); | ||
| 103 | - void arf_scale(const double& value); | ||
| 104 | - void load_arf(const std::string& filename); | ||
| 105 | - void load_psf(const std::string& filename); | ||
| 106 | - void read_arf(const GFitsTable* hdu); | ||
| 107 | - void read_psf(const GFitsTable* hdu); | 88 | + GCTAEventAtom* mc(const double& area, const GPhoton& photon, |
| 89 | + const GObservation& obs, GRan& ran) const; | ||
| 90 | + void caldb(const std::string& caldb); | ||
| 91 | + std::string caldb(void) const; | ||
| 92 | + void load(const std::string& rspname); | ||
| 93 | + void eps(const double& eps); | ||
| 94 | + const double& eps(void) const; | ||
| 95 | + void offset_sigma(const double& sigma); | ||
| 96 | + const double& offset_sigma(void) const; | ||
| 97 | + void load_aeff(const std::string& filename); | ||
| 98 | + void load_psf(const std::string& filename); | ||
| 99 | + void load_edisp(const std::string& filename); | ||
| 100 | + const GCTAAeff* aeff(void) const; | ||
| 101 | + void aeff(GCTAAeff* aeff); | ||
| 108 | 102 | ||
| 109 | // Low-level response methods | 103 | // Low-level response methods |
| 110 | double aeff(const double& theta, | 104 | double aeff(const double& theta, |
inst/cta/src/GCTAAeff2D.cpp
| @@ -28,7 +28,6 @@ | @@ -28,7 +28,6 @@ | ||
| 28 | #ifdef HAVE_CONFIG_H | 28 | #ifdef HAVE_CONFIG_H |
| 29 | #include <config.h> | 29 | #include <config.h> |
| 30 | #endif | 30 | #endif |
| 31 | -//#include <cmath> | ||
| 32 | #include "GTools.hpp" | 31 | #include "GTools.hpp" |
| 33 | #include "GFitsTable.hpp" | 32 | #include "GFitsTable.hpp" |
| 34 | #include "GCTAAeff2D.hpp" | 33 | #include "GCTAAeff2D.hpp" |
| @@ -155,8 +154,10 @@ GCTAAeff2D& GCTAAeff2D::operator= (const GCTAAeff2D& aeff) | @@ -155,8 +154,10 @@ GCTAAeff2D& GCTAAeff2D::operator= (const GCTAAeff2D& aeff) | ||
| 155 | * @brief Return effective area in units of cm2 | 154 | * @brief Return effective area in units of cm2 |
| 156 | * | 155 | * |
| 157 | * @param[in] logE Log10 of the true photon energy (TeV). | 156 | * @param[in] logE Log10 of the true photon energy (TeV). |
| 158 | - * @param[in] theta Offset angle (rad). Defaults to 0.0. | ||
| 159 | - * @param[in] phi Azimuth angle (rad). Not used in this method. | 157 | + * @param[in] theta Offset angle in camera system (rad). Defaults to 0.0. |
| 158 | + * @param[in] phi Azimuth angle in camera system (rad). Not used in this method. | ||
| 159 | + * @param[in] zenith Zenith angle in Earth system (rad). Not used in this method. | ||
| 160 | + * @param[in] azimuth Azimuth angle in Earth system (rad). Not used in this method. | ||
| 160 | * @param[in] etrue Use true energy (true/false). Defaults to true. | 161 | * @param[in] etrue Use true energy (true/false). Defaults to true. |
| 161 | * | 162 | * |
| 162 | * Returns the effective area in units of cm2 for a given energy and | 163 | * Returns the effective area in units of cm2 for a given energy and |
| @@ -172,6 +173,8 @@ GCTAAeff2D& GCTAAeff2D::operator= (const GCTAAeff2D& aeff) | @@ -172,6 +173,8 @@ GCTAAeff2D& GCTAAeff2D::operator= (const GCTAAeff2D& aeff) | ||
| 172 | double GCTAAeff2D::operator()(const double& logE, | 173 | double GCTAAeff2D::operator()(const double& logE, |
| 173 | const double& theta, | 174 | const double& theta, |
| 174 | const double& phi, | 175 | const double& phi, |
| 176 | + const double& zenith, | ||
| 177 | + const double& azimuth, | ||
| 175 | const bool& etrue) const | 178 | const bool& etrue) const |
| 176 | { | 179 | { |
| 177 | // Set parameter index | 180 | // Set parameter index |
| @@ -242,12 +245,30 @@ void GCTAAeff2D::load(const std::string& filename) | @@ -242,12 +245,30 @@ void GCTAAeff2D::load(const std::string& filename) | ||
| 242 | // Read effective area from file | 245 | // Read effective area from file |
| 243 | read(&fits); | 246 | read(&fits); |
| 244 | 247 | ||
| 248 | + // Close FITS file | ||
| 249 | + fits.close(); | ||
| 250 | + | ||
| 251 | + // Store filename | ||
| 252 | + m_filename = filename; | ||
| 253 | + | ||
| 245 | // Return | 254 | // Return |
| 246 | return; | 255 | return; |
| 247 | } | 256 | } |
| 248 | 257 | ||
| 249 | 258 | ||
| 250 | /***********************************************************************//** | 259 | /***********************************************************************//** |
| 260 | + * @brief Return filename | ||
| 261 | + * | ||
| 262 | + * @return Returns filename from which effective area was loaded | ||
| 263 | + ***************************************************************************/ | ||
| 264 | +std::string GCTAAeff2D::filename(void) const | ||
| 265 | +{ | ||
| 266 | + // Return filename | ||
| 267 | + return m_filename; | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | + | ||
| 271 | +/***********************************************************************//** | ||
| 251 | * @brief Read effective area from FITS file | 272 | * @brief Read effective area from FITS file |
| 252 | * | 273 | * |
| 253 | * @param[in] fits FITS file pointer. | 274 | * @param[in] fits FITS file pointer. |
| @@ -258,8 +279,8 @@ void GCTAAeff2D::load(const std::string& filename) | @@ -258,8 +279,8 @@ void GCTAAeff2D::load(const std::string& filename) | ||
| 258 | ***************************************************************************/ | 279 | ***************************************************************************/ |
| 259 | void GCTAAeff2D::read(const GFits* fits) | 280 | void GCTAAeff2D::read(const GFits* fits) |
| 260 | { | 281 | { |
| 261 | - // Clear instance | ||
| 262 | - clear(); | 282 | + // Clear response table |
| 283 | + m_aeff.clear(); | ||
| 263 | 284 | ||
| 264 | // Get pointer to effective area HDU | 285 | // Get pointer to effective area HDU |
| 265 | GFitsTable* hdu = fits->table("EFFECTIVE AREA"); | 286 | GFitsTable* hdu = fits->table("EFFECTIVE AREA"); |
| @@ -302,6 +323,7 @@ std::string GCTAAeff2D::print(void) const | @@ -302,6 +323,7 @@ std::string GCTAAeff2D::print(void) const | ||
| 302 | 323 | ||
| 303 | // Append header | 324 | // Append header |
| 304 | result.append("=== GCTAAeff2D ==="); | 325 | result.append("=== GCTAAeff2D ==="); |
| 326 | + result.append("\n"+parformat("Filename")+m_filename); | ||
| 305 | result.append("\n"+parformat("Number of energy bins")+str(m_aeff.axis(0))); | 327 | result.append("\n"+parformat("Number of energy bins")+str(m_aeff.axis(0))); |
| 306 | result.append("\n"+parformat("Number of offset bins")+str(m_aeff.axis(1))); | 328 | result.append("\n"+parformat("Number of offset bins")+str(m_aeff.axis(1))); |
| 307 | result.append("\n"+parformat("Log10(Energy) range")); | 329 | result.append("\n"+parformat("Log10(Energy) range")); |
| @@ -326,6 +348,7 @@ std::string GCTAAeff2D::print(void) const | @@ -326,6 +348,7 @@ std::string GCTAAeff2D::print(void) const | ||
| 326 | void GCTAAeff2D::init_members(void) | 348 | void GCTAAeff2D::init_members(void) |
| 327 | { | 349 | { |
| 328 | // Initialise members | 350 | // Initialise members |
| 351 | + m_filename.clear(); | ||
| 329 | m_aeff.clear(); | 352 | m_aeff.clear(); |
| 330 | 353 | ||
| 331 | // Return | 354 | // Return |
| @@ -341,7 +364,8 @@ void GCTAAeff2D::init_members(void) | @@ -341,7 +364,8 @@ void GCTAAeff2D::init_members(void) | ||
| 341 | void GCTAAeff2D::copy_members(const GCTAAeff2D& aeff) | 364 | void GCTAAeff2D::copy_members(const GCTAAeff2D& aeff) |
| 342 | { | 365 | { |
| 343 | // Copy members | 366 | // Copy members |
| 344 | - m_aeff = aeff.m_aeff; | 367 | + m_filename = aeff.m_filename; |
| 368 | + m_aeff = aeff.m_aeff; | ||
| 345 | 369 | ||
| 346 | // Return | 370 | // Return |
| 347 | return; | 371 | return; |
inst/cta/src/GCTAAeffArf.cpp
| @@ -157,8 +157,10 @@ GCTAAeffArf& GCTAAeffArf::operator= (const GCTAAeffArf& aeff) | @@ -157,8 +157,10 @@ GCTAAeffArf& GCTAAeffArf::operator= (const GCTAAeffArf& aeff) | ||
| 157 | * @brief Return effective area in units of cm2 | 157 | * @brief Return effective area in units of cm2 |
| 158 | * | 158 | * |
| 159 | * @param[in] logE Log10 of the true photon energy (TeV). | 159 | * @param[in] logE Log10 of the true photon energy (TeV). |
| 160 | - * @param[in] theta Offset angle (rad). Defaults to 0.0. | ||
| 161 | - * @param[in] phi Azimuth angle (rad). Not used. | 160 | + * @param[in] theta Offset angle in camera system (rad). Defaults to 0.0. |
| 161 | + * @param[in] phi Azimuth angle in camera system (rad). Not used in this method. | ||
| 162 | + * @param[in] zenith Zenith angle in Earth system (rad). Not used in this method. | ||
| 163 | + * @param[in] azimuth Azimuth angle in Earth system (rad). Not used in this method. | ||
| 162 | * @param[in] etrue Use true energy (true/false). Not used. | 164 | * @param[in] etrue Use true energy (true/false). Not used. |
| 163 | * | 165 | * |
| 164 | * Returns the effective area in units of cm2 for a given energy and | 166 | * Returns the effective area in units of cm2 for a given energy and |
| @@ -167,9 +169,11 @@ GCTAAeffArf& GCTAAeffArf::operator= (const GCTAAeffArf& aeff) | @@ -167,9 +169,11 @@ GCTAAeffArf& GCTAAeffArf::operator= (const GCTAAeffArf& aeff) | ||
| 167 | * becomes negative. | 169 | * becomes negative. |
| 168 | ***************************************************************************/ | 170 | ***************************************************************************/ |
| 169 | double GCTAAeffArf::operator()(const double& logE, | 171 | double GCTAAeffArf::operator()(const double& logE, |
| 170 | - const double& theta, | ||
| 171 | - const double& phi, | ||
| 172 | - const bool& etrue) const | 172 | + const double& theta, |
| 173 | + const double& phi, | ||
| 174 | + const double& zenith, | ||
| 175 | + const double& azimuth, | ||
| 176 | + const bool& etrue) const | ||
| 173 | { | 177 | { |
| 174 | // Get effective area value in cm2 | 178 | // Get effective area value in cm2 |
| 175 | double aeff = m_logE.interpolate(logE, m_aeff); | 179 | double aeff = m_logE.interpolate(logE, m_aeff); |
| @@ -180,9 +184,9 @@ double GCTAAeffArf::operator()(const double& logE, | @@ -180,9 +184,9 @@ double GCTAAeffArf::operator()(const double& logE, | ||
| 180 | } | 184 | } |
| 181 | 185 | ||
| 182 | // Optionally add in Gaussian offset angle dependence | 186 | // Optionally add in Gaussian offset angle dependence |
| 183 | - if (m_offset_sigma != 0.0) { | 187 | + if (m_sigma != 0.0) { |
| 184 | double offset = theta * rad2deg; | 188 | double offset = theta * rad2deg; |
| 185 | - double arg = offset * offset / m_offset_sigma; | 189 | + double arg = offset * offset / m_sigma; |
| 186 | double scale = exp(-0.5 * arg * arg); | 190 | double scale = exp(-0.5 * arg * arg); |
| 187 | aeff *= scale; | 191 | aeff *= scale; |
| 188 | } | 192 | } |
| @@ -242,10 +246,6 @@ GCTAAeffArf* GCTAAeffArf::clone(void) const | @@ -242,10 +246,6 @@ GCTAAeffArf* GCTAAeffArf::clone(void) const | ||
| 242 | ***************************************************************************/ | 246 | ***************************************************************************/ |
| 243 | void GCTAAeffArf::load(const std::string& filename) | 247 | void GCTAAeffArf::load(const std::string& filename) |
| 244 | { | 248 | { |
| 245 | - // Clear arrays | ||
| 246 | - m_logE.clear(); | ||
| 247 | - m_aeff.clear(); | ||
| 248 | - | ||
| 249 | // Open ARF FITS file | 249 | // Open ARF FITS file |
| 250 | GFits file(filename); | 250 | GFits file(filename); |
| 251 | 251 | ||
| @@ -258,12 +258,27 @@ void GCTAAeffArf::load(const std::string& filename) | @@ -258,12 +258,27 @@ void GCTAAeffArf::load(const std::string& filename) | ||
| 258 | // Close ARF FITS file | 258 | // Close ARF FITS file |
| 259 | file.close(); | 259 | file.close(); |
| 260 | 260 | ||
| 261 | + // Store filename | ||
| 262 | + m_filename = filename; | ||
| 263 | + | ||
| 261 | // Return | 264 | // Return |
| 262 | return; | 265 | return; |
| 263 | } | 266 | } |
| 264 | 267 | ||
| 265 | 268 | ||
| 266 | /***********************************************************************//** | 269 | /***********************************************************************//** |
| 270 | + * @brief Return filename | ||
| 271 | + * | ||
| 272 | + * @return Returns filename from which effective area was loaded | ||
| 273 | + ***************************************************************************/ | ||
| 274 | +std::string GCTAAeffArf::filename(void) const | ||
| 275 | +{ | ||
| 276 | + // Return filename | ||
| 277 | + return m_filename; | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | + | ||
| 281 | +/***********************************************************************//** | ||
| 267 | * @brief Read CTA ARF vector | 282 | * @brief Read CTA ARF vector |
| 268 | * | 283 | * |
| 269 | * @param[in] hdu FITS table pointer. | 284 | * @param[in] hdu FITS table pointer. |
| @@ -388,7 +403,7 @@ void GCTAAeffArf::read_arf(const GFitsTable* hdu) | @@ -388,7 +403,7 @@ void GCTAAeffArf::read_arf(const GFitsTable* hdu) | ||
| 388 | } // endfor: looped over nodes | 403 | } // endfor: looped over nodes |
| 389 | 404 | ||
| 390 | // Disable offset angle dependence | 405 | // Disable offset angle dependence |
| 391 | - m_offset_sigma = 0.0; | 406 | + m_sigma = 0.0; |
| 392 | 407 | ||
| 393 | // Return | 408 | // Return |
| 394 | return; | 409 | return; |
| @@ -411,16 +426,17 @@ std::string GCTAAeffArf::print(void) const | @@ -411,16 +426,17 @@ std::string GCTAAeffArf::print(void) const | ||
| 411 | 426 | ||
| 412 | // Append information | 427 | // Append information |
| 413 | result.append("=== GCTAAeffArf ==="); | 428 | result.append("=== GCTAAeffArf ==="); |
| 429 | + result.append("\n"+parformat("Filename")+m_filename); | ||
| 414 | result.append("\n"+parformat("Number of energy bins")+str(size())); | 430 | result.append("\n"+parformat("Number of energy bins")+str(size())); |
| 415 | result.append("\n"+parformat("Log10(Energy) range")); | 431 | result.append("\n"+parformat("Log10(Energy) range")); |
| 416 | result.append(str(emin)+" - "+str(emax)+" TeV"); | 432 | result.append(str(emin)+" - "+str(emax)+" TeV"); |
| 417 | 433 | ||
| 418 | // Append offset angle dependence | 434 | // Append offset angle dependence |
| 419 | - if (m_offset_sigma == 0) { | 435 | + if (m_sigma == 0) { |
| 420 | result.append("\n"+parformat("Offset angle dependence")+"none"); | 436 | result.append("\n"+parformat("Offset angle dependence")+"none"); |
| 421 | } | 437 | } |
| 422 | else { | 438 | else { |
| 423 | - std::string txt = "Fixed sigma="+str(m_offset_sigma); | 439 | + std::string txt = "Fixed sigma="+str(m_sigma); |
| 424 | result.append("\n"+parformat("Offset angle dependence")+txt); | 440 | result.append("\n"+parformat("Offset angle dependence")+txt); |
| 425 | } | 441 | } |
| 426 | 442 | ||
| @@ -441,11 +457,12 @@ std::string GCTAAeffArf::print(void) const | @@ -441,11 +457,12 @@ std::string GCTAAeffArf::print(void) const | ||
| 441 | void GCTAAeffArf::init_members(void) | 457 | void GCTAAeffArf::init_members(void) |
| 442 | { | 458 | { |
| 443 | // Initialise members | 459 | // Initialise members |
| 460 | + m_filename.clear(); | ||
| 444 | m_logE.clear(); | 461 | m_logE.clear(); |
| 445 | m_aeff.clear(); | 462 | m_aeff.clear(); |
| 446 | - m_offset_sigma = 3.0; | ||
| 447 | - m_thetacut = 0.0; | ||
| 448 | - m_scale = 1.0; | 463 | + m_sigma = 0.0; |
| 464 | + m_thetacut = 0.0; | ||
| 465 | + m_scale = 1.0; | ||
| 449 | 466 | ||
| 450 | // Return | 467 | // Return |
| 451 | return; | 468 | return; |
| @@ -460,11 +477,12 @@ void GCTAAeffArf::init_members(void) | @@ -460,11 +477,12 @@ void GCTAAeffArf::init_members(void) | ||
| 460 | void GCTAAeffArf::copy_members(const GCTAAeffArf& aeff) | 477 | void GCTAAeffArf::copy_members(const GCTAAeffArf& aeff) |
| 461 | { | 478 | { |
| 462 | // Copy members | 479 | // Copy members |
| 463 | - m_logE = aeff.m_logE; | ||
| 464 | - m_aeff = aeff.m_aeff; | ||
| 465 | - m_offset_sigma = aeff.m_offset_sigma; | ||
| 466 | - m_thetacut = aeff.m_thetacut; | ||
| 467 | - m_scale = aeff.m_scale; | 480 | + m_filename = aeff.m_filename; |
| 481 | + m_logE = aeff.m_logE; | ||
| 482 | + m_aeff = aeff.m_aeff; | ||
| 483 | + m_sigma = aeff.m_sigma; | ||
| 484 | + m_thetacut = aeff.m_thetacut; | ||
| 485 | + m_scale = aeff.m_scale; | ||
| 468 | 486 | ||
| 469 | // Return | 487 | // Return |
| 470 | return; | 488 | return; |
inst/cta/src/GCTAAeffPerfTable.cpp
| @@ -157,8 +157,10 @@ GCTAAeffPerfTable& GCTAAeffPerfTable::operator= (const GCTAAeffPerfTable& aeff) | @@ -157,8 +157,10 @@ GCTAAeffPerfTable& GCTAAeffPerfTable::operator= (const GCTAAeffPerfTable& aeff) | ||
| 157 | * @brief Return effective area in units of cm2 | 157 | * @brief Return effective area in units of cm2 |
| 158 | * | 158 | * |
| 159 | * @param[in] logE Log10 of the true photon energy (TeV). | 159 | * @param[in] logE Log10 of the true photon energy (TeV). |
| 160 | - * @param[in] theta Offset angle (rad). Defaults to 0.0. | ||
| 161 | - * @param[in] phi Azimuth angle (rad). Not used. | 160 | + * @param[in] theta Offset angle in camera system (rad). Defaults to 0.0. |
| 161 | + * @param[in] phi Azimuth angle in camera system (rad). Not used in this method. | ||
| 162 | + * @param[in] zenith Zenith angle in Earth system (rad). Not used in this method. | ||
| 163 | + * @param[in] azimuth Azimuth angle in Earth system (rad). Not used in this method. | ||
| 162 | * @param[in] etrue Use true energy (true/false). Not used. | 164 | * @param[in] etrue Use true energy (true/false). Not used. |
| 163 | * | 165 | * |
| 164 | * Returns the effective area in units of cm2 for a given energy and | 166 | * Returns the effective area in units of cm2 for a given energy and |
| @@ -169,6 +171,8 @@ GCTAAeffPerfTable& GCTAAeffPerfTable::operator= (const GCTAAeffPerfTable& aeff) | @@ -169,6 +171,8 @@ GCTAAeffPerfTable& GCTAAeffPerfTable::operator= (const GCTAAeffPerfTable& aeff) | ||
| 169 | double GCTAAeffPerfTable::operator()(const double& logE, | 171 | double GCTAAeffPerfTable::operator()(const double& logE, |
| 170 | const double& theta, | 172 | const double& theta, |
| 171 | const double& phi, | 173 | const double& phi, |
| 174 | + const double& zenith, | ||
| 175 | + const double& azimuth, | ||
| 172 | const bool& etrue) const | 176 | const bool& etrue) const |
| 173 | { | 177 | { |
| 174 | // Get effective area value in cm2 | 178 | // Get effective area value in cm2 |
| @@ -180,9 +184,9 @@ double GCTAAeffPerfTable::operator()(const double& logE, | @@ -180,9 +184,9 @@ double GCTAAeffPerfTable::operator()(const double& logE, | ||
| 180 | } | 184 | } |
| 181 | 185 | ||
| 182 | // Optionally add in Gaussian offset angle dependence | 186 | // Optionally add in Gaussian offset angle dependence |
| 183 | - if (m_offset_sigma != 0.0) { | 187 | + if (m_sigma != 0.0) { |
| 184 | double offset = theta * rad2deg; | 188 | double offset = theta * rad2deg; |
| 185 | - double arg = offset * offset / m_offset_sigma; | 189 | + double arg = offset * offset / m_sigma; |
| 186 | double scale = exp(-0.5 * arg * arg); | 190 | double scale = exp(-0.5 * arg * arg); |
| 187 | aeff *= scale; | 191 | aeff *= scale; |
| 188 | } | 192 | } |
| @@ -283,12 +287,27 @@ void GCTAAeffPerfTable::load(const std::string& filename) | @@ -283,12 +287,27 @@ void GCTAAeffPerfTable::load(const std::string& filename) | ||
| 283 | 287 | ||
| 284 | } // endwhile: looped over lines | 288 | } // endwhile: looped over lines |
| 285 | 289 | ||
| 290 | + // Store filename | ||
| 291 | + m_filename = filename; | ||
| 292 | + | ||
| 286 | // Return | 293 | // Return |
| 287 | return; | 294 | return; |
| 288 | } | 295 | } |
| 289 | 296 | ||
| 290 | 297 | ||
| 291 | /***********************************************************************//** | 298 | /***********************************************************************//** |
| 299 | + * @brief Return filename | ||
| 300 | + * | ||
| 301 | + * @return Returns filename from which effective area was loaded | ||
| 302 | + ***************************************************************************/ | ||
| 303 | +std::string GCTAAeffPerfTable::filename(void) const | ||
| 304 | +{ | ||
| 305 | + // Return filename | ||
| 306 | + return m_filename; | ||
| 307 | +} | ||
| 308 | + | ||
| 309 | + | ||
| 310 | +/***********************************************************************//** | ||
| 292 | * @brief Print effective area information | 311 | * @brief Print effective area information |
| 293 | * | 312 | * |
| 294 | * @return Content of effective area instance. | 313 | * @return Content of effective area instance. |
| @@ -304,16 +323,17 @@ std::string GCTAAeffPerfTable::print(void) const | @@ -304,16 +323,17 @@ std::string GCTAAeffPerfTable::print(void) const | ||
| 304 | 323 | ||
| 305 | // Append information | 324 | // Append information |
| 306 | result.append("=== GCTAAeffPerfTable ==="); | 325 | result.append("=== GCTAAeffPerfTable ==="); |
| 326 | + result.append("\n"+parformat("Filename")+m_filename); | ||
| 307 | result.append("\n"+parformat("Number of energy bins")+str(size())); | 327 | result.append("\n"+parformat("Number of energy bins")+str(size())); |
| 308 | result.append("\n"+parformat("Log10(Energy) range")); | 328 | result.append("\n"+parformat("Log10(Energy) range")); |
| 309 | result.append(str(emin)+" - "+str(emax)+" TeV"); | 329 | result.append(str(emin)+" - "+str(emax)+" TeV"); |
| 310 | 330 | ||
| 311 | // Append offset angle dependence | 331 | // Append offset angle dependence |
| 312 | - if (m_offset_sigma == 0) { | 332 | + if (m_sigma == 0) { |
| 313 | result.append("\n"+parformat("Offset angle dependence")+"none"); | 333 | result.append("\n"+parformat("Offset angle dependence")+"none"); |
| 314 | } | 334 | } |
| 315 | else { | 335 | else { |
| 316 | - std::string txt = "Fixed sigma="+str(m_offset_sigma); | 336 | + std::string txt = "Fixed sigma="+str(m_sigma); |
| 317 | result.append("\n"+parformat("Offset angle dependence")+txt); | 337 | result.append("\n"+parformat("Offset angle dependence")+txt); |
| 318 | } | 338 | } |
| 319 | 339 | ||
| @@ -334,9 +354,10 @@ std::string GCTAAeffPerfTable::print(void) const | @@ -334,9 +354,10 @@ std::string GCTAAeffPerfTable::print(void) const | ||
| 334 | void GCTAAeffPerfTable::init_members(void) | 354 | void GCTAAeffPerfTable::init_members(void) |
| 335 | { | 355 | { |
| 336 | // Initialise members | 356 | // Initialise members |
| 357 | + m_filename.clear(); | ||
| 337 | m_logE.clear(); | 358 | m_logE.clear(); |
| 338 | m_aeff.clear(); | 359 | m_aeff.clear(); |
| 339 | - m_offset_sigma = 3.0; | 360 | + m_sigma = 3.0; |
| 340 | 361 | ||
| 341 | // Return | 362 | // Return |
| 342 | return; | 363 | return; |
| @@ -351,9 +372,10 @@ void GCTAAeffPerfTable::init_members(void) | @@ -351,9 +372,10 @@ void GCTAAeffPerfTable::init_members(void) | ||
| 351 | void GCTAAeffPerfTable::copy_members(const GCTAAeffPerfTable& aeff) | 372 | void GCTAAeffPerfTable::copy_members(const GCTAAeffPerfTable& aeff) |
| 352 | { | 373 | { |
| 353 | // Copy members | 374 | // Copy members |
| 354 | - m_logE = aeff.m_logE; | ||
| 355 | - m_aeff = aeff.m_aeff; | ||
| 356 | - m_offset_sigma = aeff.m_offset_sigma; | 375 | + m_filename = aeff.m_filename; |
| 376 | + m_logE = aeff.m_logE; | ||
| 377 | + m_aeff = aeff.m_aeff; | ||
| 378 | + m_sigma = aeff.m_sigma; | ||
| 357 | 379 | ||
| 358 | // Return | 380 | // Return |
| 359 | return; | 381 | return; |
inst/cta/src/GCTAObservation.cpp
| @@ -29,17 +29,21 @@ | @@ -29,17 +29,21 @@ | ||
| 29 | #include <config.h> | 29 | #include <config.h> |
| 30 | #endif | 30 | #endif |
| 31 | #include "GObservationRegistry.hpp" | 31 | #include "GObservationRegistry.hpp" |
| 32 | -#include "GCTAException.hpp" | ||
| 33 | -#include "GCTAObservation.hpp" | ||
| 34 | -#include "GCTAEventList.hpp" | ||
| 35 | -#include "GCTAEventCube.hpp" | ||
| 36 | -#include "GCTARoi.hpp" | ||
| 37 | #include "GException.hpp" | 32 | #include "GException.hpp" |
| 38 | #include "GFits.hpp" | 33 | #include "GFits.hpp" |
| 39 | #include "GTools.hpp" | 34 | #include "GTools.hpp" |
| 40 | #include "GModelSpatialPtsrc.hpp" | 35 | #include "GModelSpatialPtsrc.hpp" |
| 41 | #include "GIntegral.hpp" | 36 | #include "GIntegral.hpp" |
| 42 | #include "GIntegrand.hpp" | 37 | #include "GIntegrand.hpp" |
| 38 | +#include "GCTAException.hpp" | ||
| 39 | +#include "GCTAObservation.hpp" | ||
| 40 | +#include "GCTAEventList.hpp" | ||
| 41 | +#include "GCTAEventCube.hpp" | ||
| 42 | +#include "GCTARoi.hpp" | ||
| 43 | +#include "GCTAAeff.hpp" | ||
| 44 | +#include "GCTAAeff2D.hpp" | ||
| 45 | +#include "GCTAAeffArf.hpp" | ||
| 46 | +#include "GCTAAeffPerfTable.hpp" | ||
| 43 | 47 | ||
| 44 | /* __ Globals ____________________________________________________________ */ | 48 | /* __ Globals ____________________________________________________________ */ |
| 45 | const GCTAObservation g_obs_cta_seed("CTA"); | 49 | const GCTAObservation g_obs_cta_seed("CTA"); |
| @@ -339,18 +343,18 @@ void GCTAObservation::pointing(const GCTAPointing& pointing) | @@ -339,18 +343,18 @@ void GCTAObservation::pointing(const GCTAPointing& pointing) | ||
| 339 | * for a binned observation. | 343 | * for a binned observation. |
| 340 | * | 344 | * |
| 341 | * @todo Still supports old ARF, PSF and RMF parameter names. | 345 | * @todo Still supports old ARF, PSF and RMF parameter names. |
| 346 | + * @todo PSF correction for ARF not yet implemented. | ||
| 342 | ***************************************************************************/ | 347 | ***************************************************************************/ |
| 343 | void GCTAObservation::read(const GXmlElement& xml) | 348 | void GCTAObservation::read(const GXmlElement& xml) |
| 344 | { | 349 | { |
| 345 | // Clear observation | 350 | // Clear observation |
| 346 | clear(); | 351 | clear(); |
| 347 | 352 | ||
| 348 | - // Initialise response parameters | ||
| 349 | - std::string aeff; | ||
| 350 | - std::string psf; | ||
| 351 | - std::string rmf; | ||
| 352 | - double thetacut = 0.0; | ||
| 353 | - double scale = 1.0; | 353 | + // Delete old response function |
| 354 | + if (m_response != NULL) delete m_response; | ||
| 355 | + | ||
| 356 | + // Allocate new CTA response function | ||
| 357 | + m_response = new GCTAResponse; | ||
| 354 | 358 | ||
| 355 | // Extract instrument name | 359 | // Extract instrument name |
| 356 | m_instrument = xml.attribute("instrument"); | 360 | m_instrument = xml.attribute("instrument"); |
| @@ -401,20 +405,53 @@ void GCTAObservation::read(const GXmlElement& xml) | @@ -401,20 +405,53 @@ void GCTAObservation::read(const GXmlElement& xml) | ||
| 401 | else if ((par->attribute("name") == "EffectiveArea") || | 405 | else if ((par->attribute("name") == "EffectiveArea") || |
| 402 | (par->attribute("name") == "ARF")) { | 406 | (par->attribute("name") == "ARF")) { |
| 403 | 407 | ||
| 404 | - // Store filename | ||
| 405 | - aeff = par->attribute("file"); | 408 | + // Get filename |
| 409 | + std::string filename = par->attribute("file"); | ||
| 406 | 410 | ||
| 407 | - // Optionally extract thetacut (0.0 if no thetacut) | ||
| 408 | - std::string s_thetacut = par->attribute("thetacut"); | ||
| 409 | - if (s_thetacut.length() > 0) { | ||
| 410 | - thetacut = todouble(s_thetacut); | ||
| 411 | - } | ||
| 412 | - | ||
| 413 | - // Optionally extract scale factor (1.0 if no scale) | ||
| 414 | - std::string s_scale = par->attribute("scale"); | ||
| 415 | - if (s_scale.length() > 0) { | ||
| 416 | - scale = todouble(s_scale); | ||
| 417 | - } | 411 | + // If filename is not empty then load effective area |
| 412 | + if (strip_whitespace(filename).length() > 0) { | ||
| 413 | + | ||
| 414 | + // Load effective area | ||
| 415 | + m_response->load_aeff(filename); | ||
| 416 | + | ||
| 417 | + // Optional attributes | ||
| 418 | + double thetacut = 0.0; | ||
| 419 | + double scale = 1.0; | ||
| 420 | + double sigma = 0.0; | ||
| 421 | + | ||
| 422 | + // Optionally extract thetacut (0.0 if no thetacut) | ||
| 423 | + std::string s_thetacut = par->attribute("thetacut"); | ||
| 424 | + if (s_thetacut.length() > 0) { | ||
| 425 | + thetacut = todouble(s_thetacut); | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + // Optionally extract scale factor (1.0 if no scale) | ||
| 429 | + std::string s_scale = par->attribute("scale"); | ||
| 430 | + if (s_scale.length() > 0) { | ||
| 431 | + scale = todouble(s_scale); | ||
| 432 | + } | ||
| 433 | + | ||
| 434 | + // Optionally extract sigma (0.0 if no sigma) | ||
| 435 | + std::string s_sigma = par->attribute("sigma"); | ||
| 436 | + if (s_sigma.length() > 0) { | ||
| 437 | + sigma = todouble(s_sigma); | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + // If we have an ARF then set attributes | ||
| 441 | + GCTAAeffArf* arf = const_cast<GCTAAeffArf*>(dynamic_cast<const GCTAAeffArf*>(m_response->aeff())); | ||
| 442 | + if (arf != NULL) { | ||
| 443 | + arf->thetacut(thetacut); | ||
| 444 | + arf->scale(scale); | ||
| 445 | + arf->sigma(sigma); | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + // If we have a performance table then set attributes | ||
| 449 | + GCTAAeffPerfTable* perf = const_cast<GCTAAeffPerfTable*>(dynamic_cast<const GCTAAeffPerfTable*>(m_response->aeff())); | ||
| 450 | + if (perf != NULL) { | ||
| 451 | + perf->sigma(sigma); | ||
| 452 | + } | ||
| 453 | + | ||
| 454 | + } // endif: effective area filename was valid | ||
| 418 | 455 | ||
| 419 | // Increase number of parameters | 456 | // Increase number of parameters |
| 420 | npar[1]++; | 457 | npar[1]++; |
| @@ -423,7 +460,16 @@ void GCTAObservation::read(const GXmlElement& xml) | @@ -423,7 +460,16 @@ void GCTAObservation::read(const GXmlElement& xml) | ||
| 423 | // Handle PSF | 460 | // Handle PSF |
| 424 | else if ((par->attribute("name") == "PointSpreadFunction") || | 461 | else if ((par->attribute("name") == "PointSpreadFunction") || |
| 425 | (par->attribute("name") == "PSF")) { | 462 | (par->attribute("name") == "PSF")) { |
| 426 | - psf = par->attribute("file"); | 463 | + |
| 464 | + // Get filename | ||
| 465 | + std::string filename = par->attribute("file"); | ||
| 466 | + | ||
| 467 | + // If filename is not empty then load point spread function | ||
| 468 | + if (strip_whitespace(filename).length() > 0) { | ||
| 469 | + m_response->load_psf(filename); | ||
| 470 | + } | ||
| 471 | + | ||
| 472 | + // Increase number of parameters | ||
| 427 | npar[2]++; | 473 | npar[2]++; |
| 428 | } | 474 | } |
| 429 | 475 | ||
| @@ -431,7 +477,16 @@ void GCTAObservation::read(const GXmlElement& xml) | @@ -431,7 +477,16 @@ void GCTAObservation::read(const GXmlElement& xml) | ||
| 431 | // Handle RMF | 477 | // Handle RMF |
| 432 | else if ((par->attribute("name") == "EnergyDispersion") || | 478 | else if ((par->attribute("name") == "EnergyDispersion") || |
| 433 | (par->attribute("name") == "RMF")) { | 479 | (par->attribute("name") == "RMF")) { |
| 434 | - rmf = par->attribute("file"); | 480 | + |
| 481 | + // Get filename | ||
| 482 | + std::string filename = par->attribute("file"); | ||
| 483 | + | ||
| 484 | + // If filename is not empty then load energy dispersion | ||
| 485 | + if (strip_whitespace(filename).length() > 0) { | ||
| 486 | + m_response->load_edisp(filename); | ||
| 487 | + } | ||
| 488 | + | ||
| 489 | + // Increase number of parameters | ||
| 435 | npar[3]++; | 490 | npar[3]++; |
| 436 | } | 491 | } |
| 437 | 492 | ||
| @@ -444,22 +499,14 @@ void GCTAObservation::read(const GXmlElement& xml) | @@ -444,22 +499,14 @@ void GCTAObservation::read(const GXmlElement& xml) | ||
| 444 | ", \"PointSpreadFunction\" and \"EnergyDispersion\" parameters."); | 499 | ", \"PointSpreadFunction\" and \"EnergyDispersion\" parameters."); |
| 445 | } | 500 | } |
| 446 | 501 | ||
| 447 | - // Delete old response function | ||
| 448 | - if (m_response != NULL) delete m_response; | ||
| 449 | - | ||
| 450 | - // Allocate new CTA response function | ||
| 451 | - m_response = new GCTAResponse; | ||
| 452 | - | ||
| 453 | - // Load PSF (need this before Aeff to handle thetacut) | ||
| 454 | - if (strip_whitespace(psf).length() > 0) { | ||
| 455 | - m_response->load_psf(psf); | ||
| 456 | - } | ||
| 457 | - | ||
| 458 | - // Load effective area | ||
| 459 | - if (strip_whitespace(aeff).length() > 0) { | ||
| 460 | - m_response->arf_thetacut(thetacut); | ||
| 461 | - m_response->arf_scale(scale); | ||
| 462 | - m_response->load_arf(aeff); | 502 | + // If we have an ARF then apply effective area correction if necessary |
| 503 | + GCTAAeffArf* arf = const_cast<GCTAAeffArf*>(dynamic_cast<const GCTAAeffArf*>(m_response->aeff())); | ||
| 504 | + if (arf != NULL) { | ||
| 505 | + if (arf->thetacut() > 0.0) { | ||
| 506 | + // TODO | ||
| 507 | + // Loop over all energies in ARF vector, determine PSF integral, | ||
| 508 | + // and perform correction | ||
| 509 | + } | ||
| 463 | } | 510 | } |
| 464 | 511 | ||
| 465 | // Return | 512 | // Return |
| @@ -554,23 +601,52 @@ void GCTAObservation::write(GXmlElement& xml) const | @@ -554,23 +601,52 @@ void GCTAObservation::write(GXmlElement& xml) const | ||
| 554 | npar[0]++; | 601 | npar[0]++; |
| 555 | } | 602 | } |
| 556 | 603 | ||
| 557 | - // Handle ARF | 604 | + // Handle effective area |
| 558 | else if (par->attribute("name") == "EffectiveArea") { | 605 | else if (par->attribute("name") == "EffectiveArea") { |
| 559 | - std::string aeff = ""; | 606 | + |
| 607 | + // Initialise attributes | ||
| 608 | + std::string filename = ""; | ||
| 560 | double thetacut = 0.0; | 609 | double thetacut = 0.0; |
| 561 | double scale = 1.0; | 610 | double scale = 1.0; |
| 611 | + double sigma = 0.0; | ||
| 612 | + | ||
| 613 | + // Continue only if response and effective area are valid | ||
| 562 | if (m_response != NULL) { | 614 | if (m_response != NULL) { |
| 563 | - aeff = m_response->arffile(); | ||
| 564 | - thetacut = m_response->arf_thetacut(); | ||
| 565 | - scale = m_response->arf_scale(); | ||
| 566 | - } | ||
| 567 | - par->attribute("file", aeff); | 615 | + if (m_response->aeff() != NULL) { |
| 616 | + | ||
| 617 | + // Get filename | ||
| 618 | + filename = m_response->aeff()->filename(); | ||
| 619 | + | ||
| 620 | + // Get optional ARF attributes | ||
| 621 | + const GCTAAeffArf* arf = | ||
| 622 | + dynamic_cast<const GCTAAeffArf*>(m_response->aeff()); | ||
| 623 | + if (arf != NULL) { | ||
| 624 | + thetacut = arf->thetacut(); | ||
| 625 | + scale = arf->scale(); | ||
| 626 | + sigma = arf->sigma(); | ||
| 627 | + } | ||
| 628 | + | ||
| 629 | + // Get optional performance table attributes | ||
| 630 | + const GCTAAeffPerfTable* perf = | ||
| 631 | + dynamic_cast<const GCTAAeffPerfTable*>(m_response->aeff()); | ||
| 632 | + if (perf != NULL) { | ||
| 633 | + sigma = arf->sigma(); | ||
| 634 | + } | ||
| 635 | + | ||
| 636 | + } // endif: effective area was valid | ||
| 637 | + } // endif: response was valid | ||
| 638 | + | ||
| 639 | + // Set attributes | ||
| 640 | + par->attribute("file", filename); | ||
| 568 | if (thetacut > 0.0) { | 641 | if (thetacut > 0.0) { |
| 569 | par->attribute("thetacut", str(thetacut)); | 642 | par->attribute("thetacut", str(thetacut)); |
| 570 | } | 643 | } |
| 571 | if (scale != 1.0) { | 644 | if (scale != 1.0) { |
| 572 | par->attribute("scale", str(scale)); | 645 | par->attribute("scale", str(scale)); |
| 573 | } | 646 | } |
| 647 | + if (sigma > 0.0) { | ||
| 648 | + par->attribute("sigma", str(sigma)); | ||
| 649 | + } | ||
| 574 | npar[1]++; | 650 | npar[1]++; |
| 575 | } | 651 | } |
| 576 | 652 |
inst/cta/src/GCTAResponse.cpp
| @@ -47,6 +47,9 @@ | @@ -47,6 +47,9 @@ | ||
| 47 | #include "GCTAException.hpp" | 47 | #include "GCTAException.hpp" |
| 48 | #include "GCTASupport.hpp" | 48 | #include "GCTASupport.hpp" |
| 49 | #include "GCTADir.hpp" | 49 | #include "GCTADir.hpp" |
| 50 | +#include "GCTAAeff2D.hpp" | ||
| 51 | +#include "GCTAAeffArf.hpp" | ||
| 52 | +#include "GCTAAeffPerfTable.hpp" | ||
| 50 | 53 | ||
| 51 | /* __ Method name definitions ____________________________________________ */ | 54 | /* __ Method name definitions ____________________________________________ */ |
| 52 | #define G_CALDB "GCTAResponse::caldb(std::string&)" | 55 | #define G_CALDB "GCTAResponse::caldb(std::string&)" |
| @@ -587,6 +590,9 @@ void GCTAResponse::load(const std::string& irfname) | @@ -587,6 +590,9 @@ void GCTAResponse::load(const std::string& irfname) | ||
| 587 | // Read performance table | 590 | // Read performance table |
| 588 | read_performance_table(filename); | 591 | read_performance_table(filename); |
| 589 | 592 | ||
| 593 | + // Read effective area | ||
| 594 | + m_aeff = new GCTAAeffPerfTable(filename); | ||
| 595 | + | ||
| 590 | // Store response name | 596 | // Store response name |
| 591 | m_rspname = irfname; | 597 | m_rspname = irfname; |
| 592 | 598 | ||
| @@ -599,29 +605,68 @@ void GCTAResponse::load(const std::string& irfname) | @@ -599,29 +605,68 @@ void GCTAResponse::load(const std::string& irfname) | ||
| 599 | 605 | ||
| 600 | 606 | ||
| 601 | /***********************************************************************//** | 607 | /***********************************************************************//** |
| 602 | - * @brief Load CTA ARF vector | 608 | + * @brief Load effective area |
| 603 | * | 609 | * |
| 604 | - * @param[in] filename FITS file name. | 610 | + * @param[in] filename Effective area filename. |
| 611 | + * | ||
| 612 | + * This method allocates an effective area instance and load the effective | ||
| 613 | + * area information from a response file. The following response file formats | ||
| 614 | + * are supported: | ||
| 615 | + * | ||
| 616 | + * (1) A CTA performance table. This is an ASCII file which specifies the | ||
| 617 | + * on-axis effective area as function of energy. | ||
| 618 | + * | ||
| 619 | + * (2) A ARF FITS file. This is a FITS file which stores the effective area | ||
| 620 | + * in a vector. | ||
| 621 | + * | ||
| 622 | + * (3) A CTA response table. This is a FITS file which specifies the | ||
| 623 | + * effective area as function of energy and offset angle. | ||
| 624 | + * | ||
| 625 | + * This method examines the file, and depending on the detected format, | ||
| 626 | + * allocates the appropriate effective area class and loads the data. | ||
| 605 | * | 627 | * |
| 606 | - * This method loads a CTA ARF vector from a FITS file. See the | ||
| 607 | - * GCTAResponse::read_arf method for more information on ARF vector reading. | 628 | + * First, the method checks whether the file is a FITS file or not. If the |
| 629 | + * file is not a FITS file, it is assumed that the file is an ASCII | ||
| 630 | + * performance table. If the file is a FITS file, the number of rows found | ||
| 631 | + * in the table is used to distinguish between an ARF (multiple rows) and | ||
| 632 | + * a CTA response table (single row). | ||
| 633 | + * | ||
| 634 | + * @todo Implement a method that checks if a file is a FITS file instead | ||
| 635 | + * of using try-catch. | ||
| 608 | ***************************************************************************/ | 636 | ***************************************************************************/ |
| 609 | -void GCTAResponse::load_arf(const std::string& filename) | 637 | +void GCTAResponse::load_aeff(const std::string& filename) |
| 610 | { | 638 | { |
| 611 | - // Open ARF FITS file | ||
| 612 | - GFits file(filename); | ||
| 613 | - | ||
| 614 | - // Get ARF table | ||
| 615 | - GFitsTable* table = file.table("SPECRESP"); | 639 | + // Free any existing effective area instance |
| 640 | + if (m_aeff != NULL) delete m_aeff; | ||
| 641 | + m_aeff = NULL; | ||
| 642 | + | ||
| 643 | + // Try opening the file as a FITS file | ||
| 644 | + try { | ||
| 645 | + | ||
| 646 | + // Open FITS file | ||
| 647 | + GFits file(filename); | ||
| 648 | + | ||
| 649 | + // If file contains an "EFFECTIVE AREA" extension then load it | ||
| 650 | + // as CTA response table | ||
| 651 | + if (file.hashdu("EFFECTIVE AREA")) { | ||
| 652 | + file.close(); | ||
| 653 | + m_aeff = new GCTAAeff2D(filename); | ||
| 654 | + } | ||
| 616 | 655 | ||
| 617 | - // Read ARF | ||
| 618 | - read_arf(table); | 656 | + // ... else if file contains a "SPECRESP" extension then load it |
| 657 | + // as ARF | ||
| 658 | + else if (file.hashdu("SPECRESP")) { | ||
| 659 | + file.close(); | ||
| 660 | + m_aeff = new GCTAAeffArf(filename); | ||
| 661 | + } | ||
| 619 | 662 | ||
| 620 | - // Close ARF FITS file | ||
| 621 | - file.close(); | 663 | + } |
| 622 | 664 | ||
| 623 | - // Store filename | ||
| 624 | - m_arffile = filename; | 665 | + // If FITS file opening failed then assume that we have a performance |
| 666 | + // table | ||
| 667 | + catch (GException::fits_open_error &e) { | ||
| 668 | + m_aeff = new GCTAAeffPerfTable(filename); | ||
| 669 | + } | ||
| 625 | 670 | ||
| 626 | // Return | 671 | // Return |
| 627 | return; | 672 | return; |
| @@ -697,137 +742,6 @@ void GCTAResponse::load_psf(const std::string& filename) | @@ -697,137 +742,6 @@ void GCTAResponse::load_psf(const std::string& filename) | ||
| 697 | 742 | ||
| 698 | 743 | ||
| 699 | /***********************************************************************//** | 744 | /***********************************************************************//** |
| 700 | - * @brief Read CTA ARF vector | ||
| 701 | - * | ||
| 702 | - * @param[in] hdu FITS table pointer. | ||
| 703 | - * | ||
| 704 | - * This method reads a CTA ARF vector from the FITS HDU. Note that the | ||
| 705 | - * energies are converted to TeV and the effective area is converted to cm2. | ||
| 706 | - * Conversion is done based on the units provided for the energy and | ||
| 707 | - * effective area columns. Units that are recognized are 'keV', 'MeV', 'GeV', | ||
| 708 | - * 'TeV', 'm^2', 'm2', 'cm^2' and 'cm^2' (case independent). | ||
| 709 | - * | ||
| 710 | - * @todo Assign appropriate theta angle for PSF. So far we use onaxis. | ||
| 711 | - * For appropriate theta angle assignment, we would need this | ||
| 712 | - * information in the response header. | ||
| 713 | - ***************************************************************************/ | ||
| 714 | -void GCTAResponse::read_arf(const GFitsTable* hdu) | ||
| 715 | -{ | ||
| 716 | - // Clear arrays | ||
| 717 | - m_aeff_logE.clear(); | ||
| 718 | - m_aeff.clear(); | ||
| 719 | - | ||
| 720 | - // Get pointers to table columns | ||
| 721 | - const GFitsTableCol* energy_lo = &(*hdu)["ENERG_LO"]; | ||
| 722 | - const GFitsTableCol* energy_hi = &(*hdu)["ENERG_HI"]; | ||
| 723 | - const GFitsTableCol* specresp = &(*hdu)["SPECRESP"]; | ||
| 724 | - | ||
| 725 | - // Determine unit conversion factors (default: TeV and cm^2) | ||
| 726 | - std::string u_energy_lo = tolower(strip_whitespace(energy_lo->unit())); | ||
| 727 | - std::string u_energy_hi = tolower(strip_whitespace(energy_hi->unit())); | ||
| 728 | - std::string u_specresp = tolower(strip_whitespace(specresp->unit())); | ||
| 729 | - double c_energy_lo = 1.0; | ||
| 730 | - double c_energy_hi = 1.0; | ||
| 731 | - double c_specresp = 1.0; | ||
| 732 | - if (u_energy_lo == "kev") { | ||
| 733 | - c_energy_lo = 1.0e-9; | ||
| 734 | - } | ||
| 735 | - else if (u_energy_lo == "mev") { | ||
| 736 | - c_energy_lo = 1.0e-6; | ||
| 737 | - } | ||
| 738 | - else if (u_energy_lo == "gev") { | ||
| 739 | - c_energy_lo = 1.0e-3; | ||
| 740 | - } | ||
| 741 | - if (u_energy_hi == "kev") { | ||
| 742 | - c_energy_hi = 1.0e-9; | ||
| 743 | - } | ||
| 744 | - else if (u_energy_hi == "mev") { | ||
| 745 | - c_energy_hi = 1.0e-6; | ||
| 746 | - } | ||
| 747 | - else if (u_energy_hi == "gev") { | ||
| 748 | - c_energy_hi = 1.0e-3; | ||
| 749 | - } | ||
| 750 | - if (u_specresp == "m^2" || u_specresp == "m2") { | ||
| 751 | - c_specresp = 10000.0; | ||
| 752 | - } | ||
| 753 | - | ||
| 754 | - // Extract number of energy bins | ||
| 755 | - int num = energy_lo->length(); | ||
| 756 | - | ||
| 757 | - // Set nodes | ||
| 758 | - for (int i = 0; i < num; ++i) { | ||
| 759 | - | ||
| 760 | - // Compute log10 mean energy in TeV | ||
| 761 | - double e_min = energy_lo->real(i) * c_energy_lo; | ||
| 762 | - double e_max = energy_hi->real(i) * c_energy_hi; | ||
| 763 | - double logE = 0.5 * (log10(e_min) + log10(e_max)); | ||
| 764 | - | ||
| 765 | - // Initialise scale factor | ||
| 766 | - double scale = m_arf_scale; | ||
| 767 | - | ||
| 768 | - // Optionally compute scaling factor from thetacut. This is done | ||
| 769 | - // by computing the containment fraction for the specified thetacut. | ||
| 770 | - if (m_arf_thetacut > 0.0) { | ||
| 771 | - | ||
| 772 | - // Get PSF parameters for node energy and theta angle | ||
| 773 | - //TODO: Implement theta angle computation | ||
| 774 | - GCTAPsfPars pars = psf_dummy_sigma(logE, 0.0); | ||
| 775 | - | ||
| 776 | - // Get maximum integration radius | ||
| 777 | - double rmax = m_arf_thetacut * deg2rad; | ||
| 778 | - | ||
| 779 | - // Setup integration kernel | ||
| 780 | - cta_npsf_kern_rad_azsym integrand(this, | ||
| 781 | - rmax, | ||
| 782 | - 0.0, | ||
| 783 | - pars); | ||
| 784 | - | ||
| 785 | - // Setup integration | ||
| 786 | - GIntegral integral(&integrand); | ||
| 787 | - integral.eps(m_eps); | ||
| 788 | - | ||
| 789 | - // Perform integration | ||
| 790 | - double fraction = integral.romb(0.0, rmax); | ||
| 791 | - | ||
| 792 | - // Update scale factor | ||
| 793 | - if (fraction > 0.0) { | ||
| 794 | - scale /= fraction; | ||
| 795 | - #if defined(G_DEBUG_READ_ARF) | ||
| 796 | - std::cout << "GCTAResponse::read_arf:"; | ||
| 797 | - std::cout << " e_min=" << e_min; | ||
| 798 | - std::cout << " e_max=" << e_max; | ||
| 799 | - std::cout << " logE=" << logE; | ||
| 800 | - std::cout << " scale=" << scale; | ||
| 801 | - std::cout << " fraction=" << fraction; | ||
| 802 | - std::cout << std::endl; | ||
| 803 | - #endif | ||
| 804 | - } | ||
| 805 | - else { | ||
| 806 | - std::cout << "WARNING: GCTAResponse::read_arf:"; | ||
| 807 | - std::cout << " Non-positive integral occured in"; | ||
| 808 | - std::cout << " PSF integration in GCTAResponse::read_arf."; | ||
| 809 | - std::cout << std::endl; | ||
| 810 | - } | ||
| 811 | - } | ||
| 812 | - | ||
| 813 | - // Compute effective area in cm2 | ||
| 814 | - double aeff = specresp->real(i) * c_specresp * scale; | ||
| 815 | - | ||
| 816 | - // Store log10 mean energy and effective area value | ||
| 817 | - m_aeff_logE.append(logE); | ||
| 818 | - m_aeff.push_back(aeff); | ||
| 819 | - | ||
| 820 | - } // endfor: looped over nodes | ||
| 821 | - | ||
| 822 | - // Disable offset angle dependence | ||
| 823 | - m_offset_sigma = 0.0; | ||
| 824 | - | ||
| 825 | - // Return | ||
| 826 | - return; | ||
| 827 | -} | ||
| 828 | - | ||
| 829 | - | ||
| 830 | -/***********************************************************************//** | ||
| 831 | * @brief Read CTA PSF vector | 745 | * @brief Read CTA PSF vector |
| 832 | * | 746 | * |
| 833 | * @param[in] hdu FITS table pointer. | 747 | * @param[in] hdu FITS table pointer. |
| @@ -925,25 +839,13 @@ std::string GCTAResponse::print(void) const | @@ -925,25 +839,13 @@ std::string GCTAResponse::print(void) const | ||
| 925 | result.append("=== GCTAResponse ==="); | 839 | result.append("=== GCTAResponse ==="); |
| 926 | result.append("\n"+parformat("Calibration database")+m_caldb); | 840 | result.append("\n"+parformat("Calibration database")+m_caldb); |
| 927 | result.append("\n"+parformat("Response name")+m_rspname); | 841 | result.append("\n"+parformat("Response name")+m_rspname); |
| 928 | - result.append("\n"+parformat("ARF file name")+m_arffile); | ||
| 929 | result.append("\n"+parformat("RMF file name")+m_rmffile); | 842 | result.append("\n"+parformat("RMF file name")+m_rmffile); |
| 930 | result.append("\n"+parformat("PSF file name")+m_psffile); | 843 | result.append("\n"+parformat("PSF file name")+m_psffile); |
| 931 | - result.append("\n"+parformat("ARF theta angle cut")); | ||
| 932 | - if (m_arf_thetacut > 0) { | ||
| 933 | - result.append(str(m_arf_thetacut)); | ||
| 934 | - } | ||
| 935 | - else { | ||
| 936 | - result.append("none"); | ||
| 937 | - } | ||
| 938 | - result.append("\n"+parformat("ARF scaling")+str(m_arf_scale)); | ||
| 939 | - if (m_offset_sigma == 0) { | ||
| 940 | - result.append("\n"+parformat("Offset angle dependence")+"none"); | ||
| 941 | - } | ||
| 942 | - else { | ||
| 943 | - std::string txt = "Fixed sigma="+str(m_offset_sigma); | ||
| 944 | - result.append("\n"+parformat("Offset angle dependence")+txt); | 844 | + |
| 845 | + // Append effective area information | ||
| 846 | + if (m_aeff != NULL) { | ||
| 847 | + result.append("\n"+m_aeff->print()); | ||
| 945 | } | 848 | } |
| 946 | - result.append("\n"+parformat("Effective area nodes")+str(m_aeff_logE.size())); | ||
| 947 | 849 | ||
| 948 | // Append PSF information | 850 | // Append PSF information |
| 949 | result.append("\n"+parformat("PSF version")); | 851 | result.append("\n"+parformat("PSF version")); |
| @@ -967,15 +869,6 @@ std::string GCTAResponse::print(void) const | @@ -967,15 +869,6 @@ std::string GCTAResponse::print(void) const | ||
| 967 | result.append("\n"+parformat("PSF nodes")+str(m_psf_logE.size())); | 869 | result.append("\n"+parformat("PSF nodes")+str(m_psf_logE.size())); |
| 968 | } | 870 | } |
| 969 | 871 | ||
| 970 | - // Debug option: Plot Aeff | ||
| 971 | - #if defined(G_DEBUG_PRINT_AEFF) | ||
| 972 | - result.append("\n"+parformat("Effective area")); | ||
| 973 | - for (int i = 0; i < m_aeff_logE.size(); ++i) { | ||
| 974 | - result.append("\n"+parformat("logE="+str(m_aeff_logE[i]))); | ||
| 975 | - result.append("Aeff="+str(m_aeff.at(i))+" m2"); | ||
| 976 | - } | ||
| 977 | - #endif | ||
| 978 | - | ||
| 979 | // Debug option: Plot PSF | 872 | // Debug option: Plot PSF |
| 980 | #if defined(G_DEBUG_PRINT_PSF) | 873 | #if defined(G_DEBUG_PRINT_PSF) |
| 981 | result.append("\n"+parformat("Point spread function")); | 874 | result.append("\n"+parformat("Point spread function")); |
| @@ -1547,14 +1440,10 @@ double GCTAResponse::npred_diffuse(const GModelDiffuseSource& model, | @@ -1547,14 +1440,10 @@ double GCTAResponse::npred_diffuse(const GModelDiffuseSource& model, | ||
| 1547 | * @param[in] zenith Zenith angle of telescope pointing (radians). | 1440 | * @param[in] zenith Zenith angle of telescope pointing (radians). |
| 1548 | * @param[in] azimuth Azimuth angle of telescope pointing (radians). | 1441 | * @param[in] azimuth Azimuth angle of telescope pointing (radians). |
| 1549 | * @param[in] srcLogEng Log10 of true photon energy (E/TeV). | 1442 | * @param[in] srcLogEng Log10 of true photon energy (E/TeV). |
| 1443 | + * @return Effective area in units fo cm2. | ||
| 1550 | * | 1444 | * |
| 1551 | - * A simple offset angle dependence has been implemented using a Gaussian | ||
| 1552 | - * if theta^2 (similar to the radial acceptance model implemented for the | ||
| 1553 | - * background). The width of the Gaussian is assumed independent of energy | ||
| 1554 | - * and given by the fixed parameter m_offset_sigma. | ||
| 1555 | - * | ||
| 1556 | - * @todo Implement offset angle dependence from response file. | ||
| 1557 | - * @todo So far the parameters phi, zenith, and azimuth are not used. | 1445 | + * Returns the effective area as function of position in the camera system |
| 1446 | + * and in the earth system. | ||
| 1558 | ***************************************************************************/ | 1447 | ***************************************************************************/ |
| 1559 | double GCTAResponse::aeff(const double& theta, | 1448 | double GCTAResponse::aeff(const double& theta, |
| 1560 | const double& phi, | 1449 | const double& phi, |
| @@ -1562,19 +1451,10 @@ double GCTAResponse::aeff(const double& theta, | @@ -1562,19 +1451,10 @@ double GCTAResponse::aeff(const double& theta, | ||
| 1562 | const double& azimuth, | 1451 | const double& azimuth, |
| 1563 | const double& srcLogEng) const | 1452 | const double& srcLogEng) const |
| 1564 | { | 1453 | { |
| 1565 | - // Interpolate effective area using node array | ||
| 1566 | - double aeff = m_aeff_logE.interpolate(srcLogEng, m_aeff); | ||
| 1567 | - if (aeff < 0) { | ||
| 1568 | - aeff = 0.0; | ||
| 1569 | - } | ||
| 1570 | - | ||
| 1571 | - // Optionally add in offset angle dependence | ||
| 1572 | - if (m_offset_sigma != 0.0) { | ||
| 1573 | - double offset = theta * rad2deg; | ||
| 1574 | - double arg = offset * offset / m_offset_sigma; | ||
| 1575 | - double scale = exp(-0.5 * arg * arg); | ||
| 1576 | - aeff *= scale; | ||
| 1577 | - } | 1454 | + // Get effective area |
| 1455 | + double aeff = (m_aeff != NULL) | ||
| 1456 | + ? (*m_aeff)(srcLogEng, theta, phi, zenith, azimuth) | ||
| 1457 | + : 0.0; | ||
| 1578 | 1458 | ||
| 1579 | // Return effective area | 1459 | // Return effective area |
| 1580 | return aeff; | 1460 | return aeff; |
| @@ -2043,23 +1923,21 @@ void GCTAResponse::init_members(void) | @@ -2043,23 +1923,21 @@ void GCTAResponse::init_members(void) | ||
| 2043 | // Initialise members | 1923 | // Initialise members |
| 2044 | m_caldb.clear(); | 1924 | m_caldb.clear(); |
| 2045 | m_rspname.clear(); | 1925 | m_rspname.clear(); |
| 2046 | - m_arffile.clear(); | ||
| 2047 | m_rmffile.clear(); | 1926 | m_rmffile.clear(); |
| 2048 | m_psffile.clear(); | 1927 | m_psffile.clear(); |
| 2049 | m_psf_logE.clear(); | 1928 | m_psf_logE.clear(); |
| 2050 | - m_aeff_logE.clear(); | ||
| 2051 | m_logE.clear(); | 1929 | m_logE.clear(); |
| 2052 | - m_aeff.clear(); | ||
| 2053 | m_r68.clear(); | 1930 | m_r68.clear(); |
| 2054 | m_r80.clear(); | 1931 | m_r80.clear(); |
| 2055 | m_eps = 1.0e-5; // Precision for Romberg integration | 1932 | m_eps = 1.0e-5; // Precision for Romberg integration |
| 2056 | m_offset_sigma = 3.0; // Default value for now ... | 1933 | m_offset_sigma = 3.0; // Default value for now ... |
| 2057 | - m_arf_thetacut = 0.0; // Default: no thetacut | ||
| 2058 | - m_arf_scale = 1.0; // Default: ARF is unscaled | ||
| 2059 | 1934 | ||
| 2060 | // Initialise PSF information | 1935 | // Initialise PSF information |
| 2061 | m_psf_version = -99; // Unknown PSF version | 1936 | m_psf_version = -99; // Unknown PSF version |
| 2062 | m_psf_table.clear(); | 1937 | m_psf_table.clear(); |
| 1938 | + | ||
| 1939 | + // New factorisation | ||
| 1940 | + m_aeff = NULL; | ||
| 2063 | 1941 | ||
| 2064 | // Return | 1942 | // Return |
| 2065 | return; | 1943 | return; |
| @@ -2076,24 +1954,22 @@ void GCTAResponse::copy_members(const GCTAResponse& rsp) | @@ -2076,24 +1954,22 @@ void GCTAResponse::copy_members(const GCTAResponse& rsp) | ||
| 2076 | // Copy attributes | 1954 | // Copy attributes |
| 2077 | m_caldb = rsp.m_caldb; | 1955 | m_caldb = rsp.m_caldb; |
| 2078 | m_rspname = rsp.m_rspname; | 1956 | m_rspname = rsp.m_rspname; |
| 2079 | - m_arffile = rsp.m_arffile; | ||
| 2080 | m_rmffile = rsp.m_rmffile; | 1957 | m_rmffile = rsp.m_rmffile; |
| 2081 | m_psffile = rsp.m_psffile; | 1958 | m_psffile = rsp.m_psffile; |
| 2082 | m_psf_logE = rsp.m_psf_logE; | 1959 | m_psf_logE = rsp.m_psf_logE; |
| 2083 | - m_aeff_logE = rsp.m_aeff_logE; | ||
| 2084 | m_logE = rsp.m_logE; | 1960 | m_logE = rsp.m_logE; |
| 2085 | - m_aeff = rsp.m_aeff; | ||
| 2086 | m_r68 = rsp.m_r68; | 1961 | m_r68 = rsp.m_r68; |
| 2087 | m_r80 = rsp.m_r80; | 1962 | m_r80 = rsp.m_r80; |
| 2088 | m_eps = rsp.m_eps; | 1963 | m_eps = rsp.m_eps; |
| 2089 | m_offset_sigma = rsp.m_offset_sigma; | 1964 | m_offset_sigma = rsp.m_offset_sigma; |
| 2090 | - m_arf_thetacut = rsp.m_arf_thetacut; | ||
| 2091 | - m_arf_scale = rsp.m_arf_scale; | ||
| 2092 | 1965 | ||
| 2093 | // Copy PSF information | 1966 | // Copy PSF information |
| 2094 | m_psf_version = rsp.m_psf_version; | 1967 | m_psf_version = rsp.m_psf_version; |
| 2095 | m_psf_table = rsp.m_psf_table; | 1968 | m_psf_table = rsp.m_psf_table; |
| 2096 | 1969 | ||
| 1970 | + // New factorisation | ||
| 1971 | + m_aeff = (rsp.m_aeff != NULL) ? rsp.m_aeff->clone() : NULL; | ||
| 1972 | + | ||
| 2097 | // Return | 1973 | // Return |
| 2098 | return; | 1974 | return; |
| 2099 | } | 1975 | } |
| @@ -2104,6 +1980,12 @@ void GCTAResponse::copy_members(const GCTAResponse& rsp) | @@ -2104,6 +1980,12 @@ void GCTAResponse::copy_members(const GCTAResponse& rsp) | ||
| 2104 | ***************************************************************************/ | 1980 | ***************************************************************************/ |
| 2105 | void GCTAResponse::free_members(void) | 1981 | void GCTAResponse::free_members(void) |
| 2106 | { | 1982 | { |
| 1983 | + // Free memory | ||
| 1984 | + if (m_aeff != NULL) delete m_aeff; | ||
| 1985 | + | ||
| 1986 | + // Initialise pointers | ||
| 1987 | + m_aeff = NULL; | ||
| 1988 | + | ||
| 2107 | // Return | 1989 | // Return |
| 2108 | return; | 1990 | return; |
| 2109 | } | 1991 | } |
| @@ -2125,9 +2007,9 @@ void GCTAResponse::read_performance_table(const std::string& filename) | @@ -2125,9 +2007,9 @@ void GCTAResponse::read_performance_table(const std::string& filename) | ||
| 2125 | { | 2007 | { |
| 2126 | // Clear arrays | 2008 | // Clear arrays |
| 2127 | m_psf_logE.clear(); | 2009 | m_psf_logE.clear(); |
| 2128 | - m_aeff_logE.clear(); | 2010 | + //m_aeff_logE.clear(); |
| 2129 | m_logE.clear(); | 2011 | m_logE.clear(); |
| 2130 | - m_aeff.clear(); | 2012 | + //m_aeff.clear(); |
| 2131 | m_r68.clear(); | 2013 | m_r68.clear(); |
| 2132 | m_r80.clear(); | 2014 | m_r80.clear(); |
| 2133 | 2015 | ||
| @@ -2164,7 +2046,7 @@ void GCTAResponse::read_performance_table(const std::string& filename) | @@ -2164,7 +2046,7 @@ void GCTAResponse::read_performance_table(const std::string& filename) | ||
| 2164 | 2046 | ||
| 2165 | // Push elements in vectors | 2047 | // Push elements in vectors |
| 2166 | m_logE.push_back(todouble(elements[0])); | 2048 | m_logE.push_back(todouble(elements[0])); |
| 2167 | - m_aeff.push_back(todouble(elements[1])*10000.0); | 2049 | + //m_aeff.push_back(todouble(elements[1])*10000.0); |
| 2168 | m_r68.push_back(todouble(elements[2])); | 2050 | m_r68.push_back(todouble(elements[2])); |
| 2169 | m_r80.push_back(todouble(elements[3])); | 2051 | m_r80.push_back(todouble(elements[3])); |
| 2170 | 2052 | ||
| @@ -2175,7 +2057,7 @@ void GCTAResponse::read_performance_table(const std::string& filename) | @@ -2175,7 +2057,7 @@ void GCTAResponse::read_performance_table(const std::string& filename) | ||
| 2175 | if (num > 0) { | 2057 | if (num > 0) { |
| 2176 | for (int i = 0; i < num; ++i) { | 2058 | for (int i = 0; i < num; ++i) { |
| 2177 | m_psf_logE.append(m_logE.at(i)); | 2059 | m_psf_logE.append(m_logE.at(i)); |
| 2178 | - m_aeff_logE.append(m_logE.at(i)); | 2060 | + //m_aeff_logE.append(m_logE.at(i)); |
| 2179 | } | 2061 | } |
| 2180 | } | 2062 | } |
| 2181 | 2063 |