Commit 5ce529679a40ebdd5590abd4a9dc6423d31c869a

Authored by Jürgen Knödlseder
1 parent 9c5e29a4

Optimise computation of COMPTEL response for extended sources

inst/com/src/com_helpers_response_vector.cpp
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 #include <cmath> 31 #include <cmath>
32 #include "com_helpers_response_vector.hpp" 32 #include "com_helpers_response_vector.hpp"
33 #include "GCOMResponse.hpp" 33 #include "GCOMResponse.hpp"
  34 +#include "GIntegral.hpp"
34 #include "GIntegrals.hpp" 35 #include "GIntegrals.hpp"
35 36
36 /* __ Method name definitions ____________________________________________ */ 37 /* __ Method name definitions ____________________________________________ */
@@ -58,6 +59,9 @@ @@ -58,6 +59,9 @@
58 ***************************************************************************/ 59 ***************************************************************************/
59 GVector com_extended_kerns_phigeo::eval(const double& phigeo) 60 GVector com_extended_kerns_phigeo::eval(const double& phigeo)
60 { 61 {
  62 + // Initialise kernel values
  63 + m_irfs = 0.0;
  64 +
61 // Continue only if phigeo is positive 65 // Continue only if phigeo is positive
62 if (phigeo > 0.0) { 66 if (phigeo > 0.0) {
63 67
@@ -90,56 +94,54 @@ GVector com_extended_kerns_phigeo::eval(const double&amp; phigeo) @@ -90,56 +94,54 @@ GVector com_extended_kerns_phigeo::eval(const double&amp; phigeo)
90 // Continue only if Phigeo index is valid 94 // Continue only if Phigeo index is valid
91 if (iphigeo < m_phigeo_bins) { 95 if (iphigeo < m_phigeo_bins) {
92 96
93 - // Initialise IAQ vector to hold precomputation results  
94 - GVector iaq(m_phibar_bins); 97 + // Setup kernel for azimuthal integration
  98 + com_extended_kerns_phi integrand(m_model,
  99 + m_srcEng,
  100 + m_srcTime,
  101 + m_rot,
  102 + m_drx,
  103 + sin_phigeo,
  104 + cos_phigeo);
  105 +
  106 + // Setup integrator
  107 + GIntegral integral(&integrand);
  108 + integral.fixed_iter(m_iter);
  109 +
  110 + // Integrate over azimuth angle
  111 + double irf = integral.romberg(phi_min, phi_max, m_iter) * sin_phigeo;
95 112
96 - // Loop over Phibar 113 + // Multiply result with IAQ for all Phibar layers
97 for (int iphibar = 0; iphibar < m_phibar_bins; ++iphibar) { 114 for (int iphibar = 0; iphibar < m_phibar_bins; ++iphibar) {
98 115
  116 + // Initialise IAQ
  117 + double iaq;
  118 +
99 // Get IAQ index 119 // Get IAQ index
100 int i = iphibar * m_phigeo_bins + iphigeo; 120 int i = iphibar * m_phigeo_bins + iphigeo;
101 121
102 // Get interpolated IAQ value 122 // Get interpolated IAQ value
103 if (eps < 0.0) { // interpolate towards left 123 if (eps < 0.0) { // interpolate towards left
104 if (iphigeo > 0) { 124 if (iphigeo > 0) {
105 - iaq[iphibar] = (1.0 + eps) * m_iaq[i] - eps * m_iaq[i-1]; 125 + iaq = (1.0 + eps) * m_iaq[i] - eps * m_iaq[i-1];
106 } 126 }
107 else { 127 else {
108 - iaq[iphibar] = (1.0 - eps) * m_iaq[i] + eps * m_iaq[i+1]; 128 + iaq = (1.0 - eps) * m_iaq[i] + eps * m_iaq[i+1];
109 } 129 }
110 } 130 }
111 else { // interpolate towards right 131 else { // interpolate towards right
112 if (iphigeo < m_phigeo_bins-1) { 132 if (iphigeo < m_phigeo_bins-1) {
113 - iaq[iphibar] = (1.0 - eps) * m_iaq[i] + eps * m_iaq[i+1]; 133 + iaq = (1.0 - eps) * m_iaq[i] + eps * m_iaq[i+1];
114 } 134 }
115 else { 135 else {
116 - iaq[iphibar] = (1.0 + eps) * m_iaq[i] - eps * m_iaq[i-1]; 136 + iaq = (1.0 + eps) * m_iaq[i] - eps * m_iaq[i-1];
117 } 137 }
118 } 138 }
119 139
120 - // Normalise IAQ value  
121 - iaq[iphibar] *= m_iaq_norm; 140 + // Compute IRF
  141 + m_irfs[iphibar] = irf * iaq * m_iaq_norm;
122 142
123 } // endfor: looped over Phibar 143 } // endfor: looped over Phibar
124 144
125 - // Setup kernel for azimuthal integration  
126 - com_extended_kerns_phi integrands(m_model,  
127 - m_irfs,  
128 - m_srcEng,  
129 - m_srcTime,  
130 - m_rot,  
131 - m_drx,  
132 - iaq,  
133 - sin_phigeo,  
134 - cos_phigeo);  
135 -  
136 - // Setup integrator  
137 - GIntegrals integral(&integrands);  
138 - integral.fixed_iter(m_iter);  
139 -  
140 - // Integrate over azimuth  
141 - m_irfs = integral.romberg(phi_min, phi_max, m_iter) * sin_phigeo;  
142 -  
143 } // endif: Phigeo bin was valid 145 } // endif: Phigeo bin was valid
144 146
145 } // endif: arc length was positive 147 } // endif: arc length was positive
@@ -157,11 +159,8 @@ GVector com_extended_kerns_phigeo::eval(const double&amp; phigeo) @@ -157,11 +159,8 @@ GVector com_extended_kerns_phigeo::eval(const double&amp; phigeo)
157 * @param[in] phi Azimuth angle (radians). 159 * @param[in] phi Azimuth angle (radians).
158 * @return Vector of azimuthally integrated model. 160 * @return Vector of azimuthally integrated model.
159 ***************************************************************************/ 161 ***************************************************************************/
160 -GVector com_extended_kerns_phi::eval(const double& phi) 162 +double com_extended_kerns_phi::eval(const double& phi)
161 { 163 {
162 - // Initialise kernel values  
163 - m_irfs = 0.0;  
164 -  
165 // Compute sine and cosine of azimuth angle 164 // Compute sine and cosine of azimuth angle
166 double sin_phi = std::sin(phi); 165 double sin_phi = std::sin(phi);
167 double cos_phi = std::cos(phi); 166 double cos_phi = std::cos(phi);
@@ -186,32 +185,8 @@ GVector com_extended_kerns_phi::eval(const double&amp; phi) @@ -186,32 +185,8 @@ GVector com_extended_kerns_phi::eval(const double&amp; phi)
186 intensity *= (*m_drx)(skyDir); 185 intensity *= (*m_drx)(skyDir);
187 } 186 }
188 187
189 - // Continue only if intensity is still positive  
190 - if (intensity > 0.0) {  
191 -  
192 - // Get number of Phibar layers  
193 - int nphibar = m_iaq.size();  
194 -  
195 - // Loop over Phibar  
196 - for (int iphibar = 0; iphibar < nphibar; ++iphibar) {  
197 -  
198 - // Continue only if IAQ value is positive  
199 - if (m_iaq[iphibar] > 0.0) {  
200 -  
201 - // Compute IRF value (unit: cm^2)  
202 - double irf = m_iaq[iphibar] * intensity;  
203 -  
204 - // Set IRF value  
205 - m_irfs[iphibar] = irf;  
206 -  
207 - } // endif: IAQ value was valid  
208 -  
209 - } // endfor: looped over Phibar  
210 -  
211 - } // endif: intensity was valid  
212 -  
213 } // endif: intensity was valid 188 } // endif: intensity was valid
214 189
215 // Return kernel values 190 // Return kernel values
216 - return m_irfs; 191 + return intensity;
217 } 192 }
inst/com/src/com_helpers_response_vector.hpp
@@ -32,6 +32,7 @@ @@ -32,6 +32,7 @@
32 #include "GTime.hpp" 32 #include "GTime.hpp"
33 #include "GVector.hpp" 33 #include "GVector.hpp"
34 #include "GMatrix.hpp" 34 #include "GMatrix.hpp"
  35 +#include "GFunction.hpp"
35 #include "GFunctions.hpp" 36 #include "GFunctions.hpp"
36 #include "GModelSky.hpp" 37 #include "GModelSky.hpp"
37 #include "GSkyMap.hpp" 38 #include "GSkyMap.hpp"
@@ -121,36 +122,29 @@ protected: @@ -121,36 +122,29 @@ protected:
121 * This class provides the kernel for the azimuth angle integration of 122 * This class provides the kernel for the azimuth angle integration of
122 * extended sky models. 123 * extended sky models.
123 ***************************************************************************/ 124 ***************************************************************************/
124 -class com_extended_kerns_phi : public GFunctions { 125 +class com_extended_kerns_phi : public GFunction {
125 public: 126 public:
126 com_extended_kerns_phi(const GModelSky& model, 127 com_extended_kerns_phi(const GModelSky& model,
127 - GVector& irfs,  
128 const GEnergy& srcEng, 128 const GEnergy& srcEng,
129 const GTime& srcTime, 129 const GTime& srcTime,
130 const GMatrix& rot, 130 const GMatrix& rot,
131 const GSkyMap* drx, 131 const GSkyMap* drx,
132 - const GVector& iaq,  
133 const double& sin_phigeo, 132 const double& sin_phigeo,
134 const double& cos_phigeo) : 133 const double& cos_phigeo) :
135 m_model(model), 134 m_model(model),
136 - m_irfs(irfs),  
137 m_srcEng(srcEng), 135 m_srcEng(srcEng),
138 m_srcTime(srcTime), 136 m_srcTime(srcTime),
139 m_rot(rot), 137 m_rot(rot),
140 m_drx(drx), 138 m_drx(drx),
141 - m_iaq(iaq),  
142 m_sin_phigeo(sin_phigeo), 139 m_sin_phigeo(sin_phigeo),
143 m_cos_phigeo(cos_phigeo) { } 140 m_cos_phigeo(cos_phigeo) { }
144 - int size(void) const { return m_irfs.size(); }  
145 - GVector eval(const double& phi); 141 + double eval(const double& phi);
146 protected: 142 protected:
147 const GModelSky& m_model; //!< Sky model 143 const GModelSky& m_model; //!< Sky model
148 - GVector& m_irfs; //!< IRF vector to update  
149 const GEnergy& m_srcEng; //!< Source energy 144 const GEnergy& m_srcEng; //!< Source energy
150 const GTime& m_srcTime; //!< Source time 145 const GTime& m_srcTime; //!< Source time
151 const GMatrix& m_rot; //!< Rotation matrix 146 const GMatrix& m_rot; //!< Rotation matrix
152 const GSkyMap* m_drx; //!< DRX 147 const GSkyMap* m_drx; //!< DRX
153 - const GVector m_iaq; //!< Precomputed IAQ vector  
154 const double& m_sin_phigeo; //!< Sine of Phigeo 148 const double& m_sin_phigeo; //!< Sine of Phigeo
155 const double& m_cos_phigeo; //!< Cosine of Phigeo 149 const double& m_cos_phigeo; //!< Cosine of Phigeo
156 }; 150 };