Commit 735726c7829fc612eb17088d964673de00cdf031
1 parent
2c2465cd
Renormalize H.E.S.S. energy dispersion from linear to dlog10(E_reco)
Showing
3 changed files
with
114 additions
and
4 deletions
inst/cta/include/GCTAEdisp2D.hpp
inst/cta/src/GCTAEdisp2D.cpp
| ... | ... | @@ -57,6 +57,7 @@ |
| 57 | 57 | //#define G_SMOOTH_EDISP_SAVE_TEST //!< Save test matrix |
| 58 | 58 | |
| 59 | 59 | /* __ Debug definitions __________________________________________________ */ |
| 60 | +//#define G_DEBUG_HESS_RENORMALIZATION | |
| 60 | 61 | |
| 61 | 62 | /* __ Constants __________________________________________________________ */ |
| 62 | 63 | |
| ... | ... | @@ -1366,6 +1367,11 @@ void GCTAEdisp2D::set_table(void) |
| 1366 | 1367 | // Set table boundaries |
| 1367 | 1368 | set_boundaries(); |
| 1368 | 1369 | |
| 1370 | + // Renormalize energy dispersion table for H.E.S.S. | |
| 1371 | + if (gammalib::strip_whitespace(m_edisp.telescope()) == "HESS") { | |
| 1372 | + hess_renormalization(); | |
| 1373 | + } | |
| 1374 | + | |
| 1369 | 1375 | // Smooth energy dispersion table (kludge only for CTA) |
| 1370 | 1376 | #if defined(G_SMOOTH_EDISP_KLUDGE) |
| 1371 | 1377 | if (gammalib::strip_whitespace(m_edisp.telescope()) == "CTA") { |
| ... | ... | @@ -1373,8 +1379,11 @@ void GCTAEdisp2D::set_table(void) |
| 1373 | 1379 | } |
| 1374 | 1380 | #endif |
| 1375 | 1381 | |
| 1376 | - // Normalize energy dispersion table | |
| 1377 | - normalize_table(); | |
| 1382 | + // Normalize energy dispersion table (not for H.E.S.S. normalization | |
| 1383 | + // since we renormalized the H.E.S.S. data before) | |
| 1384 | + if (gammalib::strip_whitespace(m_edisp.telescope()) != "HESS") { | |
| 1385 | + normalize_table(); | |
| 1386 | + } | |
| 1378 | 1387 | |
| 1379 | 1388 | // Set maximum energy dispersion value |
| 1380 | 1389 | set_max_edisp(); |
| ... | ... | @@ -1557,6 +1566,106 @@ void GCTAEdisp2D::normalize_table(void) |
| 1557 | 1566 | |
| 1558 | 1567 | |
| 1559 | 1568 | /***********************************************************************//** |
| 1569 | + * @brief Renormalize H.E.S.S. energy dispersion table | |
| 1570 | + * | |
| 1571 | + * The H.E.S.S. energy dispersion table is normalized so that | |
| 1572 | + * | |
| 1573 | + * \f[ | |
| 1574 | + * \int_{{\rm migra}_{\rm min}}^{{\rm migra}_{\rm max}} | |
| 1575 | + * E_{\rm disp}({\rm migra}) \, d{\rm migra} = 1 | |
| 1576 | + * \f] | |
| 1577 | + * | |
| 1578 | + * while the class needs values that are normalize according to | |
| 1579 | + * | |
| 1580 | + * \f[ | |
| 1581 | + * \int_{\log_{10} E_{\rm reco}^{\rm min}}^{\log_{10} E_{\rm reco}^{\rm max}} | |
| 1582 | + * E_{\rm disp}(\log_{10} E_{\rm reco}) \, d(\log_{10} E_{\rm reco}) = 1 | |
| 1583 | + * \f] | |
| 1584 | + * | |
| 1585 | + * The method thus multiplies each matrix element with | |
| 1586 | + * | |
| 1587 | + * \f[ | |
| 1588 | + * \frac{{\rm migra}_{\rm max} - {\rm migra}_{\rm min}} | |
| 1589 | + * {\log_{10} E_{\rm reco}^{\rm max} - \log_{10} E_{\rm reco}^{\rm min}} | |
| 1590 | + * \f] | |
| 1591 | + * | |
| 1592 | + * where | |
| 1593 | + * \f${\rm migra}_{\rm min}\f$ and \f${\rm migra}_{\rm max}\f$ are the | |
| 1594 | + * minimum and maximum migration values of a given bin and | |
| 1595 | + * \f$E_{\rm reco}^{\rm min}\f$ and \f$E_{\rm reco}^{\rm max}\f$ are the | |
| 1596 | + * minimum and maximum reconstructed energy values for the same bin. | |
| 1597 | + ***************************************************************************/ | |
| 1598 | +void GCTAEdisp2D::hess_renormalization(void) | |
| 1599 | +{ | |
| 1600 | + // Optional dump header | |
| 1601 | + #if defined(G_DEBUG_HESS_RENORMALIZATION) | |
| 1602 | + std::cout << "GCTAEdisp2D::hess_renormalization:" << std::endl; | |
| 1603 | + #endif | |
| 1604 | + | |
| 1605 | + // Get axes dimensions | |
| 1606 | + int etrue_size = m_edisp.axis_bins(m_inx_etrue); | |
| 1607 | + int migra_size = m_edisp.axis_bins(m_inx_migra); | |
| 1608 | + int theta_size = m_edisp.axis_bins(m_inx_theta); | |
| 1609 | + | |
| 1610 | + // Perform renormalization | |
| 1611 | + for (int i_etrue = 0; i_etrue < etrue_size; ++i_etrue) { | |
| 1612 | + | |
| 1613 | + // Get true energy in TeV | |
| 1614 | + double etrue = std::sqrt(m_edisp.axis_lo(m_inx_etrue, i_etrue) * | |
| 1615 | + m_edisp.axis_hi(m_inx_etrue, i_etrue)); | |
| 1616 | + | |
| 1617 | + // Get offset angle | |
| 1618 | + for (int i_theta = 0; i_theta < theta_size; ++i_theta) { | |
| 1619 | + | |
| 1620 | + // Intialize control sum | |
| 1621 | + #if defined(G_DEBUG_HESS_RENORMALIZATION) | |
| 1622 | + double sum = 0.0; | |
| 1623 | + #endif | |
| 1624 | + | |
| 1625 | + // Loop over all migration bins | |
| 1626 | + int offset = table_index(i_etrue, 0, i_theta); | |
| 1627 | + int stride = table_stride(m_inx_migra); | |
| 1628 | + for (int i_migra = 0, i = offset; i_migra < migra_size; ++i_migra, i += stride) { | |
| 1629 | + | |
| 1630 | + // Get migration bin size | |
| 1631 | + double migra_bin = m_edisp.axis_hi(m_inx_migra, i_migra) - | |
| 1632 | + m_edisp.axis_lo(m_inx_migra, i_migra); | |
| 1633 | + | |
| 1634 | + // Get dlog10(E_reco) bin size | |
| 1635 | + double ereco_min = m_edisp.axis_lo(m_inx_migra, i_migra) * etrue; | |
| 1636 | + double ereco_max = m_edisp.axis_hi(m_inx_migra, i_migra) * etrue; | |
| 1637 | + double dlogE_bin = std::log10(ereco_max) - std::log10(ereco_min); | |
| 1638 | + | |
| 1639 | + // Compute normalization factor | |
| 1640 | + double norm = migra_bin / dlogE_bin; | |
| 1641 | + | |
| 1642 | + // Multiply matrix element | |
| 1643 | + m_edisp(m_inx_matrix, i) *= norm; | |
| 1644 | + | |
| 1645 | + // Update test sum | |
| 1646 | + #if defined(G_DEBUG_HESS_RENORMALIZATION) | |
| 1647 | + sum += m_edisp(m_inx_matrix, i) * dlogE_bin; | |
| 1648 | + #endif | |
| 1649 | + | |
| 1650 | + } // endfor: looped over migration bins | |
| 1651 | + | |
| 1652 | + // Optional test dump | |
| 1653 | + #if defined(G_DEBUG_HESS_RENORMALIZATION) | |
| 1654 | + std::cout << "etrue=" << etrue << " TeV "; | |
| 1655 | + std::cout << "i_theta=" << i_theta << ": "; | |
| 1656 | + std::cout << sum << std::endl; | |
| 1657 | + #endif | |
| 1658 | + | |
| 1659 | + } // endfor: looped over offset angle | |
| 1660 | + | |
| 1661 | + } // endfor: looped over true energies | |
| 1662 | + | |
| 1663 | + // Return | |
| 1664 | + return; | |
| 1665 | +} | |
| 1666 | + | |
| 1667 | + | |
| 1668 | +/***********************************************************************//** | |
| 1560 | 1669 | * @brief Return index of response table element |
| 1561 | 1670 | * |
| 1562 | 1671 | * @param[in] ietrue True energy index. | ... | ... |
src/obs/GResponse.cpp
| ... | ... | @@ -187,10 +187,10 @@ double GResponse::convolve(const GModelSky& model, |
| 187 | 187 | |
| 188 | 188 | // Case A: Integration |
| 189 | 189 | if (use_edisp()) { |
| 190 | - | |
| 190 | + | |
| 191 | 191 | // Retrieve true energy boundaries |
| 192 | 192 | GEbounds ebounds = this->ebounds(event.energy()); |
| 193 | - | |
| 193 | + | |
| 194 | 194 | // Loop over all boundaries |
| 195 | 195 | for (int i = 0; i < ebounds.size(); ++i) { |
| 196 | 196 | ... | ... |