/***********************************************************************//** * @brief Return normalization of radial source for Monte Carlo simulations * * @param[in] dir Centre of simulation cone. * @param[in] radius Radius of simulation cone (degrees). * @return Normalization. * * Returns the normalization for a radial source within a circular region. * The normalization is 1 if the radial source falls within the circle * defined by @p dir and @p radius, 0 otherwise. ***************************************************************************/ inline double GModelSpatialRadial::mc_norm(const GSkyDir& dir, const double& radius) const { double norm = (dir.dist_deg(this->dir()) <= radius+theta_max()) ? 1.0 : 0.0; return (norm); }
/*************************************************************************** * @brief GSkymap_wcs_construct ***************************************************************************/ void TestGSky::test_GSkymap_wcs_construct(void) { // Set precision double eps = 1.0e-5; // Test void constructor test_try("Test void constructor"); try { GSkymap map; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test non-Healpix constructors test_try("Test non-Healpix constructors"); try { GSkymap map1("CAR", "GAL", 0.0, 0.0, 1.0, 1.0, 100, 100); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test CAR projection test_try("Test CAR projection"); try { GSkymap map1("CAR", "GAL", 138.817, 37.293, 0.521, 0.931, 100, 100); GSkyDir dir; for (int l = -180; l < 180; ++l) { for (int b = -90; b < 90; ++b) { dir.lb_deg(double(l),double(b)); GSkyPixel pixel = map1.dir2pix(dir); GSkyDir dir_back = map1.pix2dir(pixel); double dist = dir.dist_deg(dir_back); if (dist > eps) { throw exception_failure("Sky direction differs: dir="+dir.print()+" pixel="+pixel.print()+" dir_back"+ dir_back.print()+" dist="+gammalib::str(dist)+" deg"); } } } test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }
/***********************************************************************//** * @brief Return zenith angle of sky direction in COMPTEL coordinates * * @param[in] sky Sky direction. * @return Zenith angle of sky direction in COMPTEL coordinates (deg). * * Returns the zenith angle of a sky direction in COMPTEL coordinates. ***************************************************************************/ inline double GCOMOad::theta(const GSkyDir& sky) const { return (m_zaxis.dist_deg(sky)); }
/***********************************************************************//** * @brief Set Monte Carlo simulation cone * * @param[in] centre Simulation cone centre. * @param[in] radius Simulation cone radius (degrees). * * Sets the simulation cone centre and radius that defines the directions * that will be simulated using the mc() method. ***************************************************************************/ void GModelSpatialDiffuseCube::set_mc_cone(const GSkyDir& centre, const double& radius) { // Initialise cache m_mc_cache.clear(); m_mc_spectrum.clear(); // Fetch cube fetch_cube(); // Determine number of cube pixels and maps int npix = pixels(); int nmaps = maps(); // Continue only if there are pixels and maps if (npix > 0 && nmaps > 0) { // Reserve space for all pixels in cache m_mc_cache.reserve((npix+1)*nmaps); // Loop over all maps for (int i = 0; i < nmaps; ++i) { // Compute pixel offset int offset = i * (npix+1); // Set first cache value to 0 m_mc_cache.push_back(0.0); // Initialise cache with cumulative pixel fluxes and compute // total flux in skymap for normalization. Negative pixels are // excluded from the cumulative map. double total_flux = 0.0; for (int k = 0; k < npix; ++k) { // Derive effective pixel radius from half opening angle // that corresponds to the pixel's solid angle. For security, // the radius is enhanced by 50%. double pixel_radius = std::acos(1.0 - m_cube.solidangle(k)/gammalib::twopi) * gammalib::rad2deg * 1.5; // Add up flux with simulation cone radius + effective pixel // radius. The effective pixel radius is added to make sure // that all pixels that overlap with the simulation cone are // taken into account. There is no problem of having even // pixels outside the simulation cone taken into account as // long as the mc() method has an explicit test of whether a // simulated event is contained in the simulation cone. double distance = centre.dist_deg(m_cube.pix2dir(k)); if (distance <= radius+pixel_radius) { double flux = m_cube(k,i) * m_cube.solidangle(k); if (flux > 0.0) { total_flux += flux; } } // Push back flux m_mc_cache.push_back(total_flux); // units: ph/cm2/s/MeV } // Normalize cumulative pixel fluxes so that the values in the // cache run from 0 to 1 if (total_flux > 0.0) { for (int k = 0; k < npix; ++k) { m_mc_cache[k+offset] /= total_flux; } } // Make sure that last pixel in the cache is >1 m_mc_cache[npix+offset] = 1.0001; // Store centre flux in node array if (m_logE.size() == nmaps) { GEnergy energy; energy.log10MeV(m_logE[i]); // Only append node if flux > 0 if (total_flux > 0.0) { m_mc_spectrum.append(energy, total_flux); } } } // endfor: looped over all maps // Dump cache values for debugging #if defined(G_DEBUG_CACHE) for (int i = 0; i < m_mc_cache.size(); ++i) { std::cout << "i=" << i; std::cout << " c=" << m_mc_cache[i] << std::endl; } #endif } // endif: there were cube pixels and maps // Return return; }