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 31 #include <cmath>
32 32 #include "com_helpers_response_vector.hpp"
33 33 #include "GCOMResponse.hpp"
  34 +#include "GIntegral.hpp"
34 35 #include "GIntegrals.hpp"
35 36  
36 37 /* __ Method name definitions ____________________________________________ */
... ... @@ -58,6 +59,9 @@
58 59 ***************************************************************************/
59 60 GVector com_extended_kerns_phigeo::eval(const double& phigeo)
60 61 {
  62 + // Initialise kernel values
  63 + m_irfs = 0.0;
  64 +
61 65 // Continue only if phigeo is positive
62 66 if (phigeo > 0.0) {
63 67  
... ... @@ -90,56 +94,54 @@ GVector com_extended_kerns_phigeo::eval(const double&amp; phigeo)
90 94 // Continue only if Phigeo index is valid
91 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 114 for (int iphibar = 0; iphibar < m_phibar_bins; ++iphibar) {
98 115  
  116 + // Initialise IAQ
  117 + double iaq;
  118 +
99 119 // Get IAQ index
100 120 int i = iphibar * m_phigeo_bins + iphigeo;
101 121  
102 122 // Get interpolated IAQ value
103 123 if (eps < 0.0) { // interpolate towards left
104 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 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 131 else { // interpolate towards right
112 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 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 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 145 } // endif: Phigeo bin was valid
144 146  
145 147 } // endif: arc length was positive
... ... @@ -157,11 +159,8 @@ GVector com_extended_kerns_phigeo::eval(const double&amp; phigeo)
157 159 * @param[in] phi Azimuth angle (radians).
158 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 164 // Compute sine and cosine of azimuth angle
166 165 double sin_phi = std::sin(phi);
167 166 double cos_phi = std::cos(phi);
... ... @@ -186,32 +185,8 @@ GVector com_extended_kerns_phi::eval(const double&amp; phi)
186 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 188 } // endif: intensity was valid
214 189  
215 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 32 #include "GTime.hpp"
33 33 #include "GVector.hpp"
34 34 #include "GMatrix.hpp"
  35 +#include "GFunction.hpp"
35 36 #include "GFunctions.hpp"
36 37 #include "GModelSky.hpp"
37 38 #include "GSkyMap.hpp"
... ... @@ -121,36 +122,29 @@ protected:
121 122 * This class provides the kernel for the azimuth angle integration of
122 123 * extended sky models.
123 124 ***************************************************************************/
124   -class com_extended_kerns_phi : public GFunctions {
  125 +class com_extended_kerns_phi : public GFunction {
125 126 public:
126 127 com_extended_kerns_phi(const GModelSky& model,
127   - GVector& irfs,
128 128 const GEnergy& srcEng,
129 129 const GTime& srcTime,
130 130 const GMatrix& rot,
131 131 const GSkyMap* drx,
132   - const GVector& iaq,
133 132 const double& sin_phigeo,
134 133 const double& cos_phigeo) :
135 134 m_model(model),
136   - m_irfs(irfs),
137 135 m_srcEng(srcEng),
138 136 m_srcTime(srcTime),
139 137 m_rot(rot),
140 138 m_drx(drx),
141   - m_iaq(iaq),
142 139 m_sin_phigeo(sin_phigeo),
143 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 142 protected:
147 143 const GModelSky& m_model; //!< Sky model
148   - GVector& m_irfs; //!< IRF vector to update
149 144 const GEnergy& m_srcEng; //!< Source energy
150 145 const GTime& m_srcTime; //!< Source time
151 146 const GMatrix& m_rot; //!< Rotation matrix
152 147 const GSkyMap* m_drx; //!< DRX
153   - const GVector m_iaq; //!< Precomputed IAQ vector
154 148 const double& m_sin_phigeo; //!< Sine of Phigeo
155 149 const double& m_cos_phigeo; //!< Cosine of Phigeo
156 150 };
... ...