/***********************************************************************//** * @brief Return instrument response * * @param[in] event Event. * @param[in] source Source. * @param[in] obs Observation. * @return Instrument response. * * Returns the instrument response for a given event, source and observation. ***************************************************************************/ double GCOMResponse::irf(const GEvent& event, const GSource& source, const GObservation& obs) const { // Initialise IRF value double irf = 0.0; // Select IRF depending on the spatial model type switch (source.model()->code()) { case GMODEL_SPATIAL_POINT_SOURCE: { const GModelSpatialPointSource* src = static_cast<const GModelSpatialPointSource*>(source.model()); GPhoton photon(src->dir(), source.energy(), source.time()); irf = this->irf(event, photon, obs); } break; case GMODEL_SPATIAL_RADIAL: case GMODEL_SPATIAL_ELLIPTICAL: case GMODEL_SPATIAL_DIFFUSE: { std::string msg = "Response computation not yet implemented for " "spatial model type \""+source.model()->type()+"\"."; throw GException::feature_not_implemented(G_IRF, msg); } break; default: break; } // Return IRF value return irf; }
/***********************************************************************//** * @brief Return instrument response to point source * * @param[in] event Observed event. * @param[in] source Source. * @param[in] obs Observation (not used). * @return Instrument response to point source. * * Returns the instrument response to a specified point source. ***************************************************************************/ double GCTAResponseCube::irf_ptsrc(const GEvent& event, const GSource& source, const GObservation& obs) const { // Initialise IRF double irf = 0.0; // Get pointer to model source model const GModelSpatialPointSource* ptsrc = static_cast<const GModelSpatialPointSource*>(source.model()); // Get point source direction GSkyDir srcDir = ptsrc->dir(); // Get pointer on CTA event bin if (!event.is_bin()) { std::string msg = "The current event is not a CTA event bin. " "This method only works on binned CTA data. Please " "make sure that a CTA observation containing binned " "CTA data is provided."; throw GException::invalid_value(G_IRF_PTSRC, msg); } const GCTAEventBin* bin = static_cast<const GCTAEventBin*>(&event); // Determine angular separation between true and measured photon // direction in radians double delta = bin->dir().dir().dist(srcDir); // Get maximum angular separation for PSF (in radians) double delta_max = psf().delta_max(); // Get livetime (in seconds) double livetime = exposure().livetime(); // Continue only if livetime is >0 and if we're sufficiently close // to the PSF if ((livetime > 0.0) && (delta <= delta_max)) { // Get exposure irf = exposure()(srcDir, source.energy()); // Multiply-in PSF if (irf > 0.0) { // Recover effective area from exposure irf /= livetime; // Get PSF component irf *= psf()(srcDir, delta, source.energy()); // Apply deadtime correction irf *= exposure().deadc(); } // endif: exposure was non-zero } // endif: we were sufficiently close to PSF and livetime >0 // Compile option: Check for NaN/Inf #if defined(G_NAN_CHECK) if (gammalib::is_notanumber(irf) || gammalib::is_infinite(irf)) { std::cout << "*** ERROR: GCTAResponseCube::irf_ptsrc:"; std::cout << " NaN/Inf encountered"; std::cout << " irf=" << irf; std::cout << std::endl; } #endif // Return IRF value return irf; }