Commit 647c4d1108d64cfa1dfa37723cbc0f61a1f2184a
1 parent
a9ac5437
GModelSpatialDiffuseCube::set_mc_cone() recomputes MC cache only in case of cone changes.
Showing
4 changed files
with
170 additions
and
148 deletions
ChangeLog
| @@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
| 3 | * Version 1.1.0 released | 3 | * Version 1.1.0 released |
| 4 | ========================= | 4 | ========================= |
| 5 | 5 | ||
| 6 | + Optimise GModelSpatialDiffuseCube::set_mc_cone() method (#1673) | ||
| 6 | Use default GTime in GObservation::deadc() method (#1670) | 7 | Use default GTime in GObservation::deadc() method (#1670) |
| 7 | The GApplicationPar::filename() methods now take and return GFilename (#1671) | 8 | The GApplicationPar::filename() methods now take and return GFilename (#1671) |
| 8 | Add GFilename methods and remove equivalents from GTools (#1666) | 9 | Add GFilename methods and remove equivalents from GTools (#1666) |
NEWS
| @@ -111,7 +111,10 @@ None | @@ -111,7 +111,10 @@ None | ||
| 111 | 111 | ||
| 112 | 8. Model module | 112 | 8. Model module |
| 113 | --------------- | 113 | --------------- |
| 114 | -None | 114 | +The GModelSpatialDiffuseCube::set_mc_cone() method now recomputes only |
| 115 | +the Monte Carlo acceptance cone in case that the cone centre or radius | ||
| 116 | +have changed since the last computation. This speeds up the computations | ||
| 117 | +(#1673). | ||
| 115 | 118 | ||
| 116 | 119 | ||
| 117 | 9. Numerics module | 120 | 9. Numerics module |
include/GModelSpatialDiffuseCube.hpp
| @@ -130,6 +130,8 @@ protected: | @@ -130,6 +130,8 @@ protected: | ||
| 130 | GEbounds m_ebounds; //!< Energy bounds of the maps | 130 | GEbounds m_ebounds; //!< Energy bounds of the maps |
| 131 | 131 | ||
| 132 | // Monte Carlo cache | 132 | // Monte Carlo cache |
| 133 | + mutable GSkyDir m_mc_centre; //!< Centre of MC cone | ||
| 134 | + mutable double m_mc_radius; //!< Radius of MC cone | ||
| 133 | mutable std::vector<double> m_mc_cache; //!< Monte Carlo cache | 135 | mutable std::vector<double> m_mc_cache; //!< Monte Carlo cache |
| 134 | mutable std::vector<double> m_mc_max; //!< Maximum values for MC | 136 | mutable std::vector<double> m_mc_max; //!< Maximum values for MC |
| 135 | mutable GModelSpectralNodes m_mc_spectrum; //!< Map cube spectrum | 137 | mutable GModelSpectralNodes m_mc_spectrum; //!< Map cube spectrum |
src/model/GModelSpatialDiffuseCube.cpp
| @@ -782,186 +782,198 @@ GEnergies GModelSpatialDiffuseCube::energies(void) | @@ -782,186 +782,198 @@ GEnergies GModelSpatialDiffuseCube::energies(void) | ||
| 782 | void GModelSpatialDiffuseCube::set_mc_cone(const GSkyDir& centre, | 782 | void GModelSpatialDiffuseCube::set_mc_cone(const GSkyDir& centre, |
| 783 | const double& radius) const | 783 | const double& radius) const |
| 784 | { | 784 | { |
| 785 | - // Initialise cache | ||
| 786 | - m_mc_cache.clear(); | ||
| 787 | - m_mc_max.clear(); | ||
| 788 | - m_mc_spectrum.clear(); | 785 | + // Continue only if the simulation cone has changed |
| 786 | + if ((centre != m_mc_centre) || (radius != m_mc_radius)) { | ||
| 789 | 787 | ||
| 790 | - // Fetch cube | ||
| 791 | - fetch_cube(); | 788 | + // Save simulation cone definition |
| 789 | + m_mc_centre = centre; | ||
| 790 | + m_mc_radius = radius; | ||
| 792 | 791 | ||
| 793 | - // Determine number of cube pixels and maps | ||
| 794 | - int npix = pixels(); | ||
| 795 | - int nmaps = maps(); | ||
| 796 | - | ||
| 797 | - // Continue only if there are pixels and maps | ||
| 798 | - if (npix > 0 && nmaps > 0) { | ||
| 799 | - | ||
| 800 | - // Reserve space for all pixels in cache | ||
| 801 | - m_mc_cache.reserve((npix+1)*nmaps); | ||
| 802 | - m_mc_max.reserve((npix+1)*nmaps); | ||
| 803 | - m_mc_spectrum.reserve(nmaps); | ||
| 804 | - | ||
| 805 | - // Loop over all maps | ||
| 806 | - for (int i = 0; i < nmaps; ++i) { | ||
| 807 | - | ||
| 808 | - // Compute pixel offset | ||
| 809 | - int offset = i * (npix+1); | ||
| 810 | - | ||
| 811 | - // Set first cache value to 0 | ||
| 812 | - m_mc_cache.push_back(0.0); | ||
| 813 | - | ||
| 814 | - // Initialise cache with cumulative pixel fluxes and compute | ||
| 815 | - // total flux in skymap for normalization. Negative pixels are | ||
| 816 | - // excluded from the cumulative map. | ||
| 817 | - double sum = 0.0; | ||
| 818 | - double sum_map = 0.0; | ||
| 819 | - for (int k = 0; k < npix; ++k) { | ||
| 820 | - | ||
| 821 | - // Derive effective pixel radius from half opening angle | ||
| 822 | - // that corresponds to the pixel's solid angle. For security, | ||
| 823 | - // the radius is enhanced by 50%. | ||
| 824 | - /* | ||
| 825 | - double pixel_radius = | ||
| 826 | - std::acos(1.0 - m_cube.solidangle(k)/gammalib::twopi) * | ||
| 827 | - gammalib::rad2deg * 1.5; | ||
| 828 | - */ | ||
| 829 | - | ||
| 830 | - // Add up flux with simulation cone radius + effective pixel | ||
| 831 | - // radius. The effective pixel radius is added to make sure | ||
| 832 | - // that all pixels that overlap with the simulation cone are | ||
| 833 | - // taken into account. There is no problem of having even | ||
| 834 | - // pixels outside the simulation cone taken into account as | ||
| 835 | - // long as the mc() method has an explicit test of whether a | ||
| 836 | - // simulated event is contained in the simulation cone. | ||
| 837 | - double flux = m_cube.flux(k,i); | ||
| 838 | - if (flux > 0.0) { | ||
| 839 | - //double distance = centre.dist_deg(m_cube.pix2dir(k)); | ||
| 840 | - //if (distance <= radius+pixel_radius) { | ||
| 841 | - sum += flux; | ||
| 842 | - //} | ||
| 843 | - sum_map += flux; // sum up total flux in map | ||
| 844 | - } | 792 | + // Initialise cache |
| 793 | + m_mc_cache.clear(); | ||
| 794 | + m_mc_max.clear(); | ||
| 795 | + m_mc_spectrum.clear(); | ||
| 845 | 796 | ||
| 846 | - // Push back flux | ||
| 847 | - m_mc_cache.push_back(sum); // units: ph/cm2/s/MeV | ||
| 848 | - } | 797 | + // Fetch cube |
| 798 | + fetch_cube(); | ||
| 849 | 799 | ||
| 850 | - // Normalize cumulative pixel fluxes so that the values in the | ||
| 851 | - // cache run from 0 to 1 | ||
| 852 | - if (sum > 0.0) { | ||
| 853 | - for (int k = 0; k < npix; ++k) { | ||
| 854 | - m_mc_cache[k+offset] /= sum; | ||
| 855 | - } | ||
| 856 | - } | 800 | + // Determine number of cube pixels and maps |
| 801 | + int npix = pixels(); | ||
| 802 | + int nmaps = maps(); | ||
| 803 | + | ||
| 804 | + // Continue only if there are pixels and maps | ||
| 805 | + if (npix > 0 && nmaps > 0) { | ||
| 806 | + | ||
| 807 | + // Reserve space for all pixels in cache | ||
| 808 | + m_mc_cache.reserve((npix+1)*nmaps); | ||
| 809 | + m_mc_max.reserve((npix+1)*nmaps); | ||
| 810 | + m_mc_spectrum.reserve(nmaps); | ||
| 811 | + | ||
| 812 | + // Loop over all maps | ||
| 813 | + for (int i = 0; i < nmaps; ++i) { | ||
| 857 | 814 | ||
| 858 | - // Make sure that last pixel in the cache is >1 | ||
| 859 | - m_mc_cache[npix+offset] = 1.0001; | 815 | + // Compute pixel offset |
| 816 | + int offset = i * (npix+1); | ||
| 860 | 817 | ||
| 861 | - // Store flux as spectral node | ||
| 862 | - if (m_logE.size() == nmaps) { | 818 | + // Set first cache value to 0 |
| 819 | + m_mc_cache.push_back(0.0); | ||
| 863 | 820 | ||
| 864 | - // Compute mean energy | ||
| 865 | - GEnergy energy; | ||
| 866 | - energy.log10MeV(m_logE[i]); | 821 | + // Initialise cache with cumulative pixel fluxes and compute |
| 822 | + // total flux in skymap for normalization. Negative pixels | ||
| 823 | + // are excluded from the cumulative map. | ||
| 824 | + double sum = 0.0; | ||
| 825 | + double sum_map = 0.0; | ||
| 826 | + for (int k = 0; k < npix; ++k) { | ||
| 827 | + | ||
| 828 | + // Derive effective pixel radius from half opening angle | ||
| 829 | + // that corresponds to the pixel's solid angle. For | ||
| 830 | + // security, the radius is enhanced by 50%. | ||
| 831 | + /* | ||
| 832 | + double pixel_radius = | ||
| 833 | + std::acos(1.0 - m_cube.solidangle(k)/gammalib::twopi) * | ||
| 834 | + gammalib::rad2deg * 1.5; | ||
| 835 | + */ | ||
| 836 | + | ||
| 837 | + // Add up flux with simulation cone radius + effective | ||
| 838 | + // pixel radius. The effective pixel radius is added to | ||
| 839 | + // make sure that all pixels that overlap with the | ||
| 840 | + // simulation cone are taken into account. There is no | ||
| 841 | + // problem of having even pixels outside the simulation | ||
| 842 | + // cone taken into account as long as the mc() method has | ||
| 843 | + // an explicit test of whether a simulated event is | ||
| 844 | + // contained in the simulation cone. | ||
| 845 | + double flux = m_cube.flux(k,i); | ||
| 846 | + if (flux > 0.0) { | ||
| 847 | + //double distance = centre.dist_deg(m_cube.pix2dir(k)); | ||
| 848 | + //if (distance <= radius+pixel_radius) { | ||
| 849 | + sum += flux; | ||
| 850 | + //} | ||
| 851 | + sum_map += flux; // sum up total flux in map | ||
| 852 | + } | ||
| 867 | 853 | ||
| 868 | - // Only append node if flux > 0 | 854 | + // Push back flux |
| 855 | + m_mc_cache.push_back(sum); // units: ph/cm2/s/MeV | ||
| 856 | + } | ||
| 857 | + | ||
| 858 | + // Normalize cumulative pixel fluxes so that the values in | ||
| 859 | + // the cache run from 0 to 1 | ||
| 869 | if (sum > 0.0) { | 860 | if (sum > 0.0) { |
| 870 | - m_mc_spectrum.append(energy, sum); | 861 | + for (int k = 0; k < npix; ++k) { |
| 862 | + m_mc_cache[k+offset] /= sum; | ||
| 863 | + } | ||
| 871 | } | 864 | } |
| 872 | 865 | ||
| 873 | - } | 866 | + // Make sure that last pixel in the cache is >1 |
| 867 | + m_mc_cache[npix+offset] = 1.0001; | ||
| 874 | 868 | ||
| 875 | - // Do we have a HealPix map? | ||
| 876 | - if (m_cube.projection()->code() == "HPX") { | 869 | + // Store flux as spectral node |
| 870 | + if (m_logE.size() == nmaps) { | ||
| 877 | 871 | ||
| 878 | - // Get pointer on HealPix projection | ||
| 879 | - const GHealpix* healpix = | ||
| 880 | - static_cast<const GHealpix*>(m_cube.projection()); | 872 | + // Compute mean energy |
| 873 | + GEnergy energy; | ||
| 874 | + energy.log10MeV(m_logE[i]); | ||
| 881 | 875 | ||
| 882 | - // Compute maximum value that may occur from bilinear | ||
| 883 | - // interpolation within this pixel and push this value on the | ||
| 884 | - // stack. We do this by checking values of all neighbours. | ||
| 885 | - for (int k = 0; k < npix; ++k) { | 876 | + // Only append node if flux > 0 |
| 877 | + if (sum > 0.0) { | ||
| 878 | + m_mc_spectrum.append(energy, sum); | ||
| 879 | + } | ||
| 886 | 880 | ||
| 887 | - // Get neighbours | ||
| 888 | - std::vector<int> neighbours = healpix->neighbours(k); | 881 | + } |
| 889 | 882 | ||
| 890 | - // Loop over neighbours | ||
| 891 | - double max = m_cube(k,i); | ||
| 892 | - for (int j = 0; j < neighbours.size(); ++j) { | ||
| 893 | - if (neighbours[j] != -1) { | ||
| 894 | - double value = m_cube(neighbours[j],i); | ||
| 895 | - if (value > max) { | ||
| 896 | - max = value; | 883 | + // Do we have a HealPix map? |
| 884 | + if (m_cube.projection()->code() == "HPX") { | ||
| 885 | + | ||
| 886 | + // Get pointer on HealPix projection | ||
| 887 | + const GHealpix* healpix = | ||
| 888 | + static_cast<const GHealpix*>(m_cube.projection()); | ||
| 889 | + | ||
| 890 | + // Compute maximum value that may occur from bilinear | ||
| 891 | + // interpolation within this pixel and push this value | ||
| 892 | + // on the stack. We do this by checking values of all | ||
| 893 | + // neighbours. | ||
| 894 | + for (int k = 0; k < npix; ++k) { | ||
| 895 | + | ||
| 896 | + // Get neighbours | ||
| 897 | + std::vector<int> neighbours = healpix->neighbours(k); | ||
| 898 | + | ||
| 899 | + // Loop over neighbours | ||
| 900 | + double max = m_cube(k,i); | ||
| 901 | + for (int j = 0; j < neighbours.size(); ++j) { | ||
| 902 | + if (neighbours[j] != -1) { | ||
| 903 | + double value = m_cube(neighbours[j],i); | ||
| 904 | + if (value > max) { | ||
| 905 | + max = value; | ||
| 906 | + } | ||
| 897 | } | 907 | } |
| 898 | } | 908 | } |
| 899 | - } | ||
| 900 | 909 | ||
| 901 | - // Store maximum | ||
| 902 | - m_mc_max[k+offset] = max; | 910 | + // Store maximum |
| 911 | + m_mc_max[k+offset] = max; | ||
| 903 | 912 | ||
| 904 | - } // endfor: looped over pixels | 913 | + } // endfor: looped over pixels |
| 905 | 914 | ||
| 906 | - } // endif: Healpix projection | 915 | + } // endif: Healpix projection |
| 907 | 916 | ||
| 908 | - // ... no, then we have a WCS map | ||
| 909 | - else { | 917 | + // ... no, then we have a WCS map |
| 918 | + else { | ||
| 910 | 919 | ||
| 911 | - // Compute maximum value that may occur from bilinear | ||
| 912 | - // interpolation within this pixel and push this value on the | ||
| 913 | - // stack. We do this by checking the map values at the corners | ||
| 914 | - // and the centre of each edge. | ||
| 915 | - for (int k = 0; k < npix; ++k) { | ||
| 916 | - GSkyPixel pixel = m_cube.inx2pix(k); | ||
| 917 | - double max = m_cube(pixel,i); | ||
| 918 | - for (int ix = -1; ix < 2; ++ix) { | ||
| 919 | - for (int iy = -1; iy < 2; ++iy) { | ||
| 920 | - if (ix != 0 && iy != 0) { | ||
| 921 | - GSkyPixel edge(pixel.x()+ix*0.5, pixel.y()+iy*0.5); | ||
| 922 | - if (m_cube.contains(edge)) { | ||
| 923 | - GSkyDir dir = m_cube.pix2dir(edge); | ||
| 924 | - double value = m_cube(dir,i); | ||
| 925 | - if (value > max) { | ||
| 926 | - max = value; | 920 | + // Compute maximum value that may occur from bilinear |
| 921 | + // interpolation within this pixel and push this value | ||
| 922 | + // on the stack. We do this by checking the map values | ||
| 923 | + // at the corners and the centre of each edge. | ||
| 924 | + for (int k = 0; k < npix; ++k) { | ||
| 925 | + GSkyPixel pixel = m_cube.inx2pix(k); | ||
| 926 | + double max = m_cube(pixel,i); | ||
| 927 | + for (int ix = -1; ix < 2; ++ix) { | ||
| 928 | + for (int iy = -1; iy < 2; ++iy) { | ||
| 929 | + if (ix != 0 && iy != 0) { | ||
| 930 | + GSkyPixel edge(pixel.x()+ix*0.5, pixel.y()+iy*0.5); | ||
| 931 | + if (m_cube.contains(edge)) { | ||
| 932 | + GSkyDir dir = m_cube.pix2dir(edge); | ||
| 933 | + double value = m_cube(dir,i); | ||
| 934 | + if (value > max) { | ||
| 935 | + max = value; | ||
| 936 | + } | ||
| 927 | } | 937 | } |
| 928 | } | 938 | } |
| 929 | } | 939 | } |
| 930 | } | 940 | } |
| 941 | + m_mc_max[k+offset] = max; | ||
| 931 | } | 942 | } |
| 932 | - m_mc_max[k+offset] = max; | ||
| 933 | - } | ||
| 934 | 943 | ||
| 935 | - } // endelse: computed maximum pixel value | 944 | + } // endelse: computed maximum pixel value |
| 936 | 945 | ||
| 937 | - // Make sure that last pixel in the maximum cache has a well defined value | ||
| 938 | - m_mc_max[npix+offset] = 0.0; | 946 | + // Make sure that last pixel in the maximum cache has a |
| 947 | + // well defined value | ||
| 948 | + m_mc_max[npix+offset] = 0.0; | ||
| 939 | 949 | ||
| 940 | - } // endfor: looped over all maps | 950 | + } // endfor: looped over all maps |
| 941 | 951 | ||
| 942 | - // Dump cache values for debugging | ||
| 943 | - #if defined(G_DEBUG_CACHE) | ||
| 944 | - std::cout << "GModelSpatialDiffuseCube::set_mc_cone: cache"; | ||
| 945 | - std::cout << std::endl; | ||
| 946 | - for (int i = 0; i < m_mc_cache.size(); ++i) { | ||
| 947 | - std::cout << "i=" << i; | ||
| 948 | - std::cout << " cache=" << m_mc_cache[i]; | ||
| 949 | - std::cout << " max=" << m_mc_max[i] << std::endl; | ||
| 950 | - } | ||
| 951 | - #endif | ||
| 952 | - | ||
| 953 | - // Dump spectrum for debugging | ||
| 954 | - #if defined(G_DEBUG_CACHE) | ||
| 955 | - std::cout << "GModelSpatialDiffuseCube::set_mc_cone: spectrum"; | ||
| 956 | - std::cout << std::endl; | ||
| 957 | - for (int i = 0; i < m_mc_spectrum.nodes(); ++i) { | ||
| 958 | - std::cout << i; | ||
| 959 | - std::cout << " " << m_mc_spectrum.energy(i); | ||
| 960 | - std::cout << " " << m_mc_spectrum.intensity(i) << std::endl; | ||
| 961 | - } | ||
| 962 | - #endif | 952 | + // Dump cache values for debugging |
| 953 | + #if defined(G_DEBUG_CACHE) | ||
| 954 | + std::cout << "GModelSpatialDiffuseCube::set_mc_cone: cache"; | ||
| 955 | + std::cout << std::endl; | ||
| 956 | + for (int i = 0; i < m_mc_cache.size(); ++i) { | ||
| 957 | + std::cout << "i=" << i; | ||
| 958 | + std::cout << " cache=" << m_mc_cache[i]; | ||
| 959 | + std::cout << " max=" << m_mc_max[i] << std::endl; | ||
| 960 | + } | ||
| 961 | + #endif | ||
| 962 | + | ||
| 963 | + // Dump spectrum for debugging | ||
| 964 | + #if defined(G_DEBUG_CACHE) | ||
| 965 | + std::cout << "GModelSpatialDiffuseCube::set_mc_cone: spectrum"; | ||
| 966 | + std::cout << std::endl; | ||
| 967 | + for (int i = 0; i < m_mc_spectrum.nodes(); ++i) { | ||
| 968 | + std::cout << i; | ||
| 969 | + std::cout << " " << m_mc_spectrum.energy(i); | ||
| 970 | + std::cout << " " << m_mc_spectrum.intensity(i) << std::endl; | ||
| 971 | + } | ||
| 972 | + #endif | ||
| 973 | + | ||
| 974 | + } // endif: there were cube pixels and maps | ||
| 963 | 975 | ||
| 964 | - } // endif: there were cube pixels and maps | 976 | + } // endif: simulation cone has changed |
| 965 | 977 | ||
| 966 | // Return | 978 | // Return |
| 967 | return; | 979 | return; |
| @@ -1155,6 +1167,8 @@ void GModelSpatialDiffuseCube::init_members(void) | @@ -1155,6 +1167,8 @@ void GModelSpatialDiffuseCube::init_members(void) | ||
| 1155 | m_loaded = false; | 1167 | m_loaded = false; |
| 1156 | 1168 | ||
| 1157 | // Initialise MC cache | 1169 | // Initialise MC cache |
| 1170 | + m_mc_centre.clear(); | ||
| 1171 | + m_mc_radius = -1.0; //!< Signal that initialisation is needed | ||
| 1158 | m_mc_cache.clear(); | 1172 | m_mc_cache.clear(); |
| 1159 | m_mc_max.clear(); | 1173 | m_mc_max.clear(); |
| 1160 | m_mc_spectrum.clear(); | 1174 | m_mc_spectrum.clear(); |
| @@ -1180,6 +1194,8 @@ void GModelSpatialDiffuseCube::copy_members(const GModelSpatialDiffuseCube& mode | @@ -1180,6 +1194,8 @@ void GModelSpatialDiffuseCube::copy_members(const GModelSpatialDiffuseCube& mode | ||
| 1180 | m_loaded = model.m_loaded; | 1194 | m_loaded = model.m_loaded; |
| 1181 | 1195 | ||
| 1182 | // Copy MC cache | 1196 | // Copy MC cache |
| 1197 | + m_mc_centre = model.m_mc_centre; | ||
| 1198 | + m_mc_radius = model.m_mc_radius; | ||
| 1183 | m_mc_cache = model.m_mc_cache; | 1199 | m_mc_cache = model.m_mc_cache; |
| 1184 | m_mc_max = model.m_mc_max; | 1200 | m_mc_max = model.m_mc_max; |
| 1185 | m_mc_spectrum = model.m_mc_spectrum; | 1201 | m_mc_spectrum = model.m_mc_spectrum; |