Commit 1a159a4ccaf6f71deee3e26d5b76c06d9ca9a616
1 parent
1aa24101
implemented model_gamma e wstat value methods
Showing
3 changed files
with
338 additions
and
0 deletions
inst/cta/include/GCTAOnOffObservation.hpp
| ... | ... | @@ -112,6 +112,7 @@ public: |
| 112 | 112 | const GPha& off_spec(void) const; |
| 113 | 113 | const GArf& arf(void) const; |
| 114 | 114 | const GRmf& rmf(void) const; |
| 115 | + GPha model_gamma(const GModels& models) const; | |
| 115 | 116 | |
| 116 | 117 | protected: |
| 117 | 118 | // Protected methods |
| ... | ... | @@ -138,6 +139,14 @@ protected: |
| 138 | 139 | double N_bgd(const GModels& models, const int& ibin, GVector* grad) const; |
| 139 | 140 | |
| 140 | 141 | // Likelihood methods |
| 142 | + double wstat_value(double non, | |
| 143 | + double noff, | |
| 144 | + double alpha, | |
| 145 | + double ngam, | |
| 146 | + double& nonpred, | |
| 147 | + double& nbgd, | |
| 148 | + double& dlogLdsky, | |
| 149 | + double& d2logLdsky2); | |
| 141 | 150 | virtual double likelihood_cstat(const GModels& models, |
| 142 | 151 | GVector* gradient, |
| 143 | 152 | GMatrixSparse* curvature, | ... | ... |
inst/cta/pyext/GCTAOnOffObservation.i
inst/cta/src/GCTAOnOffObservation.cpp
| ... | ... | @@ -1735,6 +1735,37 @@ double GCTAOnOffObservation::N_bgd(const GModels& models, |
| 1735 | 1735 | return value; |
| 1736 | 1736 | } |
| 1737 | 1737 | |
| 1738 | +/*********************************************************************** | |
| 1739 | + * @brief Compute predicted gamma-ray counts Pha for given model | |
| 1740 | + * | |
| 1741 | + * @param[in] models Model container. | |
| 1742 | + * @return model gamma Pha. | |
| 1743 | + * | |
| 1744 | + * Returns spectrum of predicted number of source events in the On regions | |
| 1745 | + * | |
| 1746 | + ***********************************************************************/ | |
| 1747 | +GPha GCTAOnOffObservation::model_gamma(const GModels& models) const | |
| 1748 | +{ | |
| 1749 | + // Get number of model parameters in model container | |
| 1750 | + int npars = models.npars(); | |
| 1751 | + | |
| 1752 | + // Create dummy gradient vectors to provide required argument to N_gamma | |
| 1753 | + GVector dummy_grad(npars); | |
| 1754 | + | |
| 1755 | + // Initialise output Pha | |
| 1756 | + GEbounds ereco = m_arf.ebounds(); | |
| 1757 | + GPha gammas = GPha(ereco); | |
| 1758 | + | |
| 1759 | + // Loop over all energy bins | |
| 1760 | + for (int i = 0; i < m_on_spec.size(); ++i) { | |
| 1761 | + double ngam = N_gamma(models, i, &dummy_grad); | |
| 1762 | + gammas.fill(ereco.emean(i),ngam); | |
| 1763 | + } | |
| 1764 | + | |
| 1765 | + // Return model coun pha | |
| 1766 | + return gammas; | |
| 1767 | +} | |
| 1768 | + | |
| 1738 | 1769 | |
| 1739 | 1770 | /***********************************************************************//** |
| 1740 | 1771 | * @brief Evaluate log-likelihood function for On/Off analysis in the |
| ... | ... | @@ -2062,6 +2093,303 @@ double GCTAOnOffObservation::likelihood_cstat(const GModels& models, |
| 2062 | 2093 | return value; |
| 2063 | 2094 | } |
| 2064 | 2095 | |
| 2096 | +/***********************************************************************//** | |
| 2097 | + * @brief Evaluate log-likelihood value in energy bin for On/Off analysis | |
| 2098 | + * by profiling over the number of background counts | |
| 2099 | + * | |
| 2100 | + * @param[in] non number of On counts | |
| 2101 | + * @param[in] noff number of Off counts | |
| 2102 | + * @param[in] alpha background scaling rate | |
| 2103 | + * @param[in] ngam number of predicted gamma-ray counts | |
| 2104 | + * @param[in,out] nonpred number of predicted On counts | |
| 2105 | + * @param[in,out] nbgd number of predicted background counts | |
| 2106 | + * @param[in,out] dlogLdsky first derivative of log-like w.r.t. sky pars | |
| 2107 | + * @param[in,out] d2logLdsky2 second derivative of log-like w.r.t. sky pars | |
| 2108 | + * @return Log-likelihood value. | |
| 2109 | + * | |
| 2110 | + * Computes the log-likelihood value for the On/Off observation in an energy bin | |
| 2111 | + * by treating the number of background counts as nuisance parameter. The method | |
| 2112 | + * performs an analytical minimisation of the Poisson likelihood and updates | |
| 2113 | + * the relevant values. | |
| 2114 | + * In the general case, the log-likelihood function is computed using | |
| 2115 | + * | |
| 2116 | + * \f[ | |
| 2117 | + * L = \mu_s + (1+\alpha) \mu_b - n_{\rm on} - n_{\rm off} - | |
| 2118 | + * n_{\rm on} \left( \ln(\mu_s + \alpha \mu_b) - \ln(n_{\rm on}) | |
| 2119 | + * \right) - | |
| 2120 | + * n_{\rm off} \left( \ln(\mu_b) - \ln(n_{\rm off}) \right) | |
| 2121 | + * \f] | |
| 2122 | + * | |
| 2123 | + * where | |
| 2124 | + * | |
| 2125 | + * \f[ | |
| 2126 | + * \mu_b = \frac{C+D}{2\alpha(1+\alpha)} | |
| 2127 | + * \f] | |
| 2128 | + * | |
| 2129 | + * are the estimated number of background counts with | |
| 2130 | + * | |
| 2131 | + * \f[ | |
| 2132 | + * C = \alpha (n_{\rm on} + n_{\rm off}) - (1 + \alpha) \mu_s | |
| 2133 | + * \f] | |
| 2134 | + * | |
| 2135 | + * and | |
| 2136 | + * | |
| 2137 | + * \f[ | |
| 2138 | + * D = \sqrt{C^2 + 4 (1 + \alpha) \, \alpha \, n_{\rm off} \, \mu_s} | |
| 2139 | + * \f] | |
| 2140 | + * | |
| 2141 | + * \ | |
| 2142 | + * | |
| 2143 | + * The first derivative of the log-likelihood function is given by | |
| 2144 | + * | |
| 2145 | + * \f[ | |
| 2146 | + * \frac{\delta L}{\delta \mu_s} = | |
| 2147 | + * 1 + (1 + \alpha) \frac{\delta \mu_b}{\delta \mu_s} - | |
| 2148 | + * \frac{n_{\rm on}}{\mu_s + \alpha \mu_b} \left( 1 + \alpha | |
| 2149 | + * \frac{\delta \mu_b}{\delta \mu_s} \right) - | |
| 2150 | + * \frac{n_{\rm off}}{\mu_b} \frac{\delta \mu_b}{\delta \mu_s} | |
| 2151 | + * \f] | |
| 2152 | + * | |
| 2153 | + * with | |
| 2154 | + * | |
| 2155 | + * \f[ | |
| 2156 | + * \frac{\delta \mu_b}{\delta \mu_s} = | |
| 2157 | + * \frac{n_{\rm off} - C}{D} - \frac{1}{2 \alpha} | |
| 2158 | + * \f] | |
| 2159 | + * | |
| 2160 | + * The second derivative of the log-likelihood function is given by | |
| 2161 | + * | |
| 2162 | + * \f[ | |
| 2163 | + * \frac{\delta^2 L}{\delta \mu_s^2} = | |
| 2164 | + * \frac{n_{\rm on}}{(\mu_s + \alpha \mu_b)^2} \left( 1 + \alpha | |
| 2165 | + * \frac{\delta \mu_b}{\delta \mu_s} \right) + | |
| 2166 | + * \frac{\delta^2 \mu_b}{\delta \mu_s^2} \left( (1 + \alpha) - | |
| 2167 | + * \frac{\alpha n_{\rm on}}{\mu_s + \alpha \mu_b} - | |
| 2168 | + * \frac{n_{\rm off}}{\mu_b} \right) + | |
| 2169 | + * \frac{\delta \mu_b}{\delta \mu_s} \left( | |
| 2170 | + * \frac{\alpha n_{\rm on}}{(\mu_s + \alpha \mu_b)^2} \left( | |
| 2171 | + * 1 + \alpha \frac{\delta \mu_b}{\delta \mu_s} \right) + | |
| 2172 | + * \frac{n_{\rm off}}{\mu_b^2} \frac{\delta \mu_b}{\delta \mu_s} | |
| 2173 | + * \right) | |
| 2174 | + * \f] | |
| 2175 | + * | |
| 2176 | + * with | |
| 2177 | + * | |
| 2178 | + * \f[ | |
| 2179 | + * \frac{\delta^2 \mu_b}{\delta \mu_s^2} = | |
| 2180 | + * \frac{-1}{2 \alpha} \left( | |
| 2181 | + * \frac{1}{D} \frac{\delta C}{\delta \mu_s} + | |
| 2182 | + * \frac{2 \alpha \, n_{\rm off} - C}{D^2} \frac{\delta D}{\delta \mu_s} | |
| 2183 | + * \right) | |
| 2184 | + * \f] | |
| 2185 | + * | |
| 2186 | + * where | |
| 2187 | + * | |
| 2188 | + * \f[ | |
| 2189 | + * \frac{\delta C}{\delta \mu_s} = -(1 + \alpha) | |
| 2190 | + * \f] | |
| 2191 | + * | |
| 2192 | + * and | |
| 2193 | + * | |
| 2194 | + * \f[ | |
| 2195 | + * \frac{\delta D}{\delta \mu_s} = | |
| 2196 | + * \frac{4 (1 + \alpha) \, \alpha \, n_{\rm off} - 2 \, C \, (1 + \alpha)} | |
| 2197 | + * {2D} | |
| 2198 | + * \f] | |
| 2199 | + * | |
| 2200 | + * In the special case \f$n_{\rm on}=n_{\rm off}=0\f$ the formal | |
| 2201 | + * background estimate becomes negative, hence we set \f$\mu_b=0\f$ and | |
| 2202 | + * the log-likelihood function becomes | |
| 2203 | + * | |
| 2204 | + * \f[ | |
| 2205 | + * L = \mu_s | |
| 2206 | + * \f] | |
| 2207 | + * | |
| 2208 | + * the first derivative | |
| 2209 | + * | |
| 2210 | + * \f[ | |
| 2211 | + * \frac{\delta L}{\delta \mu_s} = 1 | |
| 2212 | + * \f] | |
| 2213 | + * | |
| 2214 | + * and the second derivative | |
| 2215 | + * | |
| 2216 | + * \f[ | |
| 2217 | + * \frac{\delta^2 L}{\delta \mu_s^2} = 0 | |
| 2218 | + * \f] | |
| 2219 | + * | |
| 2220 | + * In the special case \f$n_{\rm on}=0\f$ and \f$n_{\rm off}>0\f$ | |
| 2221 | + * the log-likelihood function becomes | |
| 2222 | + * | |
| 2223 | + * \f[ | |
| 2224 | + * L = \mu_s + n_{\rm off} \ln(1 + \alpha) | |
| 2225 | + * \f] | |
| 2226 | + * | |
| 2227 | + * the background estimate | |
| 2228 | + * | |
| 2229 | + * \f[ | |
| 2230 | + * \mu_b = \frac{n_{\rm off}}{1+\alpha} | |
| 2231 | + * \f] | |
| 2232 | + * | |
| 2233 | + * the first derivative | |
| 2234 | + * | |
| 2235 | + * \f[ | |
| 2236 | + * \frac{\delta L}{\delta \mu_s} = 1 | |
| 2237 | + * \f] | |
| 2238 | + * | |
| 2239 | + * and the second derivative | |
| 2240 | + * | |
| 2241 | + * \f[ | |
| 2242 | + * \frac{\delta^2 L}{\delta \mu_s^2} = 0 | |
| 2243 | + * \f] | |
| 2244 | + * | |
| 2245 | + * In the special case \f$n_{\rm on}>0\f$ and \f$n_{\rm off}=0\f$ | |
| 2246 | + * the background estimate becomes | |
| 2247 | + * | |
| 2248 | + * \f[ | |
| 2249 | + * \mu_b = \frac{n_{\rm on}}{1+\alpha} - \frac{\mu_s}{\alpha} | |
| 2250 | + * \f] | |
| 2251 | + * | |
| 2252 | + * which is positive for | |
| 2253 | + * | |
| 2254 | + * \f[ | |
| 2255 | + * \mu_s < n_{\rm on} \frac{\alpha}{1+\alpha} | |
| 2256 | + * \f] | |
| 2257 | + * | |
| 2258 | + * For positive \f$\mu_b\f$ the log-likelihood function is given by | |
| 2259 | + * | |
| 2260 | + * \f[ | |
| 2261 | + * L = -\frac{\mu_s}{\alpha} | |
| 2262 | + * - n_{\rm on} \ln \left(\frac{\alpha}{1 + \alpha} \right) | |
| 2263 | + * \f] | |
| 2264 | + * | |
| 2265 | + * the first derivative | |
| 2266 | + * | |
| 2267 | + * \f[ | |
| 2268 | + * \frac{\delta L}{\delta \mu_s} = -\frac{1}{\alpha} | |
| 2269 | + * \f] | |
| 2270 | + * | |
| 2271 | + * and the second derivative | |
| 2272 | + * | |
| 2273 | + * \f[ | |
| 2274 | + * \frac{\delta^2 L}{\delta \mu_s^2} = 0 | |
| 2275 | + * \f] | |
| 2276 | + * | |
| 2277 | + * For negative \f$\mu_b\f$ we set \f$\mu_b=0\f$ and the log-likelihood | |
| 2278 | + * function becomes | |
| 2279 | + * | |
| 2280 | + * \f[ | |
| 2281 | + * L = \mu_s - n_{\rm on} - | |
| 2282 | + * n_{\rm on} \left( \ln(\mu_s) - \ln(n_{\rm on}) \right) | |
| 2283 | + * \f] | |
| 2284 | + * | |
| 2285 | + * the first derivative | |
| 2286 | + * | |
| 2287 | + * \f[ | |
| 2288 | + * \frac{\delta L}{\delta \mu_s} = 1 - \frac{n_{\rm on}}{\mu_s} | |
| 2289 | + * \f] | |
| 2290 | + * | |
| 2291 | + * and the second derivative | |
| 2292 | + * | |
| 2293 | + * \f[ | |
| 2294 | + * \frac{\delta^2 L}{\delta \mu_s^2} = \frac{1}{\mu_s^2} | |
| 2295 | + * \f] | |
| 2296 | + * | |
| 2297 | + * Note that the fit results may be biased and the statistical errors | |
| 2298 | + * overestimated if for some bins \f$n_{\rm on}=0\f$ and/or | |
| 2299 | + * \f$n_{\rm off}=0\f$ (i.e. if the special cases are encountered). | |
| 2300 | + ***********************************************************************/ | |
| 2301 | + | |
| 2302 | +double wstat_value(double non, | |
| 2303 | + double noff, | |
| 2304 | + double alpha, | |
| 2305 | + double ngam, | |
| 2306 | + double& nonpred, | |
| 2307 | + double& nbgd, | |
| 2308 | + double& dlogLdsky, | |
| 2309 | + double& d2logLdsky2) | |
| 2310 | +{ | |
| 2311 | + // Initialise log-likelihood value | |
| 2312 | + double logL; | |
| 2313 | + | |
| 2314 | + // Precompute some values | |
| 2315 | + double alphap1 = alpha + 1.0; | |
| 2316 | + double alpharat = alpha / alphap1; | |
| 2317 | + | |
| 2318 | + // Calculate number of background events, profile likelihood value | |
| 2319 | + // and likelihood derivatives | |
| 2320 | + | |
| 2321 | + // Special case noff = 0 | |
| 2322 | + if (noff == 0.0) { | |
| 2323 | + | |
| 2324 | + // Case A: non = 0. In this case nbgd < 0 hence we set nbgd = 0 | |
| 2325 | + if (non == 0.0) { | |
| 2326 | + nonpred = ngam; | |
| 2327 | + logL = ngam; | |
| 2328 | + dlogLdsky = 1.0; | |
| 2329 | + d2logLdsky2 = 0.0; | |
| 2330 | + } | |
| 2331 | + | |
| 2332 | + // Case B: nbgd is positive | |
| 2333 | + else if (ngam < non * alpharat) { | |
| 2334 | + double nbgd = non / alphap1 - ngam / alpha; | |
| 2335 | + nonpred = ngam + alpha * nbgd; | |
| 2336 | + logL = -ngam / alpha - non * std::log(alpharat); | |
| 2337 | + dlogLdsky = -1.0/alpha; | |
| 2338 | + d2logLdsky2 = 0.0; | |
| 2339 | + } | |
| 2340 | + | |
| 2341 | + // Case C: nbgd is zero or negative, hence set nbgd = 0 | |
| 2342 | + else { | |
| 2343 | + nonpred = ngam; | |
| 2344 | + logL = ngam + non * (std::log(non) - std::log(ngam) - 1.0); | |
| 2345 | + dlogLdsky = 1.0 - non / ngam; | |
| 2346 | + d2logLdsky2 = non / (ngam * ngam); | |
| 2347 | + } | |
| 2348 | + | |
| 2349 | + } // endif: noff = 0 | |
| 2350 | + | |
| 2351 | + // Special case non = 0 | |
| 2352 | + else if (non == 0.0) { | |
| 2353 | + nonpred = ngam + alpharat * noff; | |
| 2354 | + logL = ngam + noff * std::log(alphap1); | |
| 2355 | + dlogLdsky = 1.0; | |
| 2356 | + d2logLdsky2 = 0.0; | |
| 2357 | + } // endif: non = 0 | |
| 2358 | + | |
| 2359 | + // General case | |
| 2360 | + else { | |
| 2361 | + | |
| 2362 | + // Compute log-likelihood value | |
| 2363 | + double alphat2 = 2.0 * alpha; | |
| 2364 | + double C = alpha * (non + noff) - alphap1 * ngam; | |
| 2365 | + double D = std::sqrt(C*C + 4.0 * alpha * alphap1 * noff * ngam); | |
| 2366 | + double nbgd = (C + D) / (alphat2 * alphap1); | |
| 2367 | + nonpred = ngam + alpha * nbgd; | |
| 2368 | + logL = ngam + alphap1 * nbgd - non - noff - | |
| 2369 | + non * (std::log(nonpred) - std::log(non)) - | |
| 2370 | + noff * (std::log(nbgd) - std::log(noff)); | |
| 2371 | + | |
| 2372 | + // Compute derivatives | |
| 2373 | + double f0 = alphat2 * noff - C; | |
| 2374 | + double dCds = -alphap1; | |
| 2375 | + double dDds = (C * dCds + 2.0 * alphap1 * alpha * noff) / D; | |
| 2376 | + double dbds = (f0 / D - 1.0) / alphat2; | |
| 2377 | + double d2bds2 = (-dCds / D - f0 / (D*D) * dDds) / alphat2; | |
| 2378 | + double f1 = alphap1 - alpha*non/nonpred - noff/nbgd; | |
| 2379 | + double f2 = nonpred * nonpred; | |
| 2380 | + double dpds = 1.0 + alpha * dbds; | |
| 2381 | + double f3 = non / f2 * dpds; | |
| 2382 | + dlogLdsky = 1.0 - non / nonpred + dbds * f1; | |
| 2383 | + d2logLdsky2 = f3 + d2bds2 * f1 + | |
| 2384 | + dbds * (alpha * f3 + noff / (nbgd*nbgd) * dbds); | |
| 2385 | + | |
| 2386 | + } // endelse: general case | |
| 2387 | + | |
| 2388 | + // Return | |
| 2389 | + return logL; | |
| 2390 | +} | |
| 2391 | + | |
| 2392 | + | |
| 2065 | 2393 | |
| 2066 | 2394 | /***********************************************************************//** |
| 2067 | 2395 | * @brief Evaluate log-likelihood function for On/Off analysis in the | ... | ... |