/*************************************************************************** * GLATLtCube.cpp - Fermi/LAT livetime cube class * * ----------------------------------------------------------------------- * * copyright (C) 2010-2014 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ***************************************************************************/ /** * @file GLATLtCube.cpp * @brief Fermi/LAT livetime cube class implementation * @author Juergen Knoedlseder */ /* __ Includes ___________________________________________________________ */ #ifdef HAVE_CONFIG_H #include #endif #include "GLATLtCube.hpp" #include "GTools.hpp" /* __ Method name definitions ____________________________________________ */ /* __ Macros _____________________________________________________________ */ /* __ Coding definitions _________________________________________________ */ /* __ Debug definitions __________________________________________________ */ /* __ Constants __________________________________________________________ */ /*========================================================================== = = = Constructors/destructors = = = ==========================================================================*/ /***********************************************************************//** * @brief Void constructor ***************************************************************************/ GLATLtCube::GLATLtCube(void) { // Initialise class members init_members(); // Return return; } /***********************************************************************//** * @brief File constructor * * @param[in] filename Livetime cube filename. ***************************************************************************/ GLATLtCube::GLATLtCube(const std::string& filename) { // Initialise class members init_members(); // Load livetime cube from file load(filename); // Return return; } /***********************************************************************//** * @brief Copy constructor * * @param[in] cube Livetime cube. ***************************************************************************/ GLATLtCube::GLATLtCube(const GLATLtCube& cube) { // Initialise class members init_members(); // Copy members copy_members(cube); // Return return; } /***********************************************************************//** * @brief Destructor ***************************************************************************/ GLATLtCube::~GLATLtCube(void) { // Free members free_members(); // Return return; } /*========================================================================== = = = Operators = = = ==========================================================================*/ /***********************************************************************//** * @brief Assignment operator * * @param[in] cube Livetime cube. * @return Livetime cube. ***************************************************************************/ GLATLtCube& GLATLtCube::operator=(const GLATLtCube& cube) { // Execute only if object is not identical if (this != &cube) { // Free members free_members(); // Initialise private members init_members(); // Copy members copy_members(cube); } // endif: object was not identical // Return this object return *this; } /***********************************************************************//** * @brief Sum function multiplied by efficiency corrected livetime over * zenith angle * * @param[in] dir Sky direction. * @param[in] energy Energy. * @param[in] fct Function to evaluate. * * Computes * \f[\sum_{\cos \theta} T_{\rm corr.~live}(\cos \theta) f(\cos \theta)\f] * where * \f$T_{\rm corr.~live}(\cos \theta)\f$ is the efficiency corrected * livetime as a function of the cosine of the zenith angle, and * \f$f(\cos \theta)\f$ is a function that depends on the cosine of the * zenith angle. * * Note that no efficieny correction is implemented for this method as the * efficiency factors are stored together with the effective area. If we * want efficiency correction here, we should think about passing this * information to the method. ***************************************************************************/ double GLATLtCube::operator()(const GSkyDir& dir, const GEnergy& energy, _ltcube_ctheta fct) const { // Compute exposure double exposure = m_exposure(dir, fct); // Optionally compute livetime factors for trigger rate- and // energy-dependent efficiency corrections /* if (aeff.has_efficiency()) { // Compute correction factors double f1 = aeff.efficiency_factor1(energy); double f2 = aeff.efficiency_factor2(energy); // Compute correction double correction = m_weighted_exposure(dir, fct); // Set exposure exposure = f1 * exposure + f2 * correction; } // endif: corrections requested */ // Return exposure return exposure; } /***********************************************************************//** * @brief Sum function multiplied by efficiency corrected livetime over * zenith and azimuth angles * * @param[in] dir Sky direction. * @param[in] energy Energy. * @param[in] fct Function to evaluate. * * Computes * \f[\sum_{\cos \theta, \phi} T_{\rm corr.~live}(\cos \theta, \phi) * f(\cos \theta, \phi)\f] * where * \f$T_{\rm corr.~live}(\cos \theta, \phi)\f$ is the efficiency corrected * livetime as a function of the cosine of the zenith and of the azimuth * angle, and * \f$f(\cos \theta, \phi)\f$ is a function that depends on the cosine of * the zenith angle and of the azimuth angle. * * Note that no efficieny correction is implemented for this method as the * efficiency factors are stored together with the effective area. If we * want efficiency correction here, we should think about passing this * information to the method. ***************************************************************************/ double GLATLtCube::operator()(const GSkyDir& dir, const GEnergy& energy, _ltcube_ctheta_phi fct) const { // Compute exposure double exposure = m_exposure(dir, fct); // Optionally compute livetime factors for trigger rate- and // energy-dependent efficiency corrections /* if (aeff.has_efficiency()) { // Compute correction factors double f1 = aeff.efficiency_factor1(energy); double f2 = aeff.efficiency_factor2(energy); // Compute correction double correction = m_weighted_exposure(dir, fct); // Set exposure exposure = f1 * exposure + f2 * correction; } // endif: corrections requested */ // Return exposure return exposure; } /***********************************************************************//** * @brief Sum effective area multiplied by efficiency corrected livetime * over zenith and (optionally) azimuth angles * * @param[in] dir Sky direction. * @param[in] energy Energy. * @param[in] aeff Effective area. * * Computes * \f[\sum_{\cos \theta, \phi} T_{\rm corr.~live}(\cos \theta, \phi) * A_{\rm eff}(\cos \theta, \phi)\f] * where * \f$T_{\rm corr.~live}(\cos \theta, \phi)\f$ is the efficiency corrected * livetime as a function of the cosine of the zenith and of the azimuth * angle, and * \f$A_{\rm eff}(\cos \theta, \phi)\f$ is the effective area that depends * on the cosine of the zenith angle and (optionally) of the azimuth angle. ***************************************************************************/ double GLATLtCube::operator()(const GSkyDir& dir, const GEnergy& energy, const GLATAeff& aeff) const { // Compute exposure double exposure = m_exposure(dir, energy, aeff); // Optionally compute livetime factors for trigger rate- and // energy-dependent efficiency corrections if (aeff.has_efficiency()) { // Compute correction factors double f1 = aeff.efficiency_factor1(energy); double f2 = aeff.efficiency_factor2(energy); // Compute correction double correction = m_weighted_exposure(dir, energy, aeff); // Set exposure exposure = f1 * exposure + f2 * correction; } // endif: corrections requested // Return exposure return exposure; } /***********************************************************************//** * @brief Sum point spread function multiplied by efficiency corrected * livetime over zenith angles * * @param[in] dir Sky direction. * @param[in] energy Energy. * @param[in] offset Offset from true direction (deg). * @param[in] psf Point spread function. * @param[in] aeff Effective area. * * Computes * \f[\sum_{\cos \theta, \phi} T_{\rm corr.~live}(\cos \theta, \phi) * PSF(\log E, \delta, \cos \theta) A_{\rm eff}(\cos \theta, \phi)\f] * where * \f$T_{\rm corr.~live}(\cos \theta, \phi)\f$ is the efficiency corrected * livetime as a function of the cosine of the zenith and of the azimuth * angle, * \f$PSF(\log E, \delta, \cos \theta)\f$ is the point spread function that * depends on * the log10 of the energy (in MeV), * the offset angle from the true direction (in degrees), and * the cosine of the zenith angle, and * \f$A_{\rm eff}(\cos \theta, \phi)\f$ is the effective area that depends * on the cosine of the zenith angle and (optionally) of the azimuth angle. ***************************************************************************/ double GLATLtCube::operator()(const GSkyDir& dir, const GEnergy& energy, const double& offset, const GLATPsf& psf, const GLATAeff& aeff) const { // Compute exposure double exposure = m_exposure(dir, energy, offset, psf, aeff); // Optionally compute livetime factors for trigger rate- and // energy-dependent efficiency corrections if (aeff.has_efficiency()) { // Compute correction factors double f1 = aeff.efficiency_factor1(energy); double f2 = aeff.efficiency_factor2(energy); // Compute correction double correction = m_weighted_exposure(dir, energy, offset, psf, aeff); // Set exposure exposure = f1 * exposure + f2 * correction; } // endif: corrections requested // Return exposure return exposure; } /*========================================================================== = = = Public methods = = = ==========================================================================*/ /***********************************************************************//** * @brief Clear lifetime cube ***************************************************************************/ void GLATLtCube::clear(void) { // Free class members free_members(); // Initialise members init_members(); // Return return; } /***********************************************************************//** * @brief Clone lifetime cube * * @return Pointer to deep copy of lifetime cube. ***************************************************************************/ GLATLtCube* GLATLtCube::clone(void) const { return new GLATLtCube(*this); } /***********************************************************************//** * @brief Load livetime cube from FITS file * * @param[in] filename FITS file name. * * @todo Loading of cos theta boundaries not yet implemented. This is not * critical since they are not really needed. We just need them once * we want to implement also saving. ***************************************************************************/ void GLATLtCube::load(const std::string& filename) { // Clear object clear(); // Open lifetime cube FITS file GFits file(filename); // Get HDUs const GFitsTable& hdu_exposure = *file.table("EXPOSURE"); const GFitsTable& hdu_weighted_exposure = *file.table("WEIGHTED_EXPOSURE"); //const GFitsTable& hdu_cthetabounds = *file.table("CTHETABOUNDS"); const GFitsTable& hdu_gti = *file.table("GTI"); // Load exposure m_exposure.read(hdu_exposure); // Load weighted exposure m_weighted_exposure.read(hdu_weighted_exposure); // Load cos theta boundaries // Load GTIs m_gti.read(hdu_gti); // Close FITS file file.close(); // Return return; } /***********************************************************************//** * @brief Save livetime cube into FITS file * * @param[in] filename FITS file name. * @param[in] clobber Overwrite existing file? * * @todo Not yet implemented. ***************************************************************************/ void GLATLtCube::save(const std::string& filename, const bool& clobber) const { // Return return; } /***********************************************************************//** * @brief Print livetime cube information * * @param[in] chatter Chattiness (defaults to NORMAL). * @return String containing livetime cube information. ***************************************************************************/ std::string GLATLtCube::print(const GChatter& chatter) const { // Initialise result string std::string result; // Continue only if chatter is not silent if (chatter != SILENT) { // Append header result.append("=== GLATLtCube ==="); // Append detailed information GChatter reduced_chatter = gammalib::reduce(chatter); if (reduced_chatter > SILENT) { result.append("\n"+m_exposure.print(reduced_chatter)); result.append("\n"+m_weighted_exposure.print(reduced_chatter)); result.append("\n"+m_gti.print(reduced_chatter)); } } // endif: chatter was not silent // Return result return result; } /*========================================================================== = = = Private methods = = = ==========================================================================*/ /***********************************************************************//** * @brief Initialise class members ***************************************************************************/ void GLATLtCube::init_members(void) { // Initialise members m_exposure.clear(); m_weighted_exposure.clear(); m_gti.clear(); // Return return; } /***********************************************************************//** * @brief Copy class members * * @param[in] cube Livetime cube. ***************************************************************************/ void GLATLtCube::copy_members(const GLATLtCube& cube) { // Copy members m_exposure = cube.m_exposure; m_weighted_exposure = cube.m_weighted_exposure; m_gti = cube.m_gti; // Return return; } /***********************************************************************//** * @brief Delete class members ***************************************************************************/ void GLATLtCube::free_members(void) { // Return return; }