Commit 07fd4b9edbc4a756dc719caa4938abb0b89b5e97
1 parent
6e9d8a89
Handle wrap around in X axis and add check of skymap size after reading.
The wrap around in the X axis is now correctly dealt with in the interpolation operator. Upon reading of the WCS map the size of the map is checked. Exceptions are thrown in case that the map is larger then 360 in X and larger than 180 in Y.
Showing
1 changed file
with
66 additions
and
27 deletions
src/sky/GSkymap.cpp
| ... | ... | @@ -344,7 +344,7 @@ GSkymap& GSkymap::operator+=(const GSkymap& map) |
| 344 | 344 | std::string msg = "Mismatch of number of maps in skymap object" |
| 345 | 345 | " ("+gammalib::str(nmaps())+" maps in destination" |
| 346 | 346 | " map, "+gammalib::str(map.nmaps())+" in source" |
| 347 | - " map."; | |
| 347 | + " map)."; | |
| 348 | 348 | throw GException::invalid_value(G_OP_UNARY_ADD, msg); |
| 349 | 349 | } |
| 350 | 350 | |
| ... | ... | @@ -418,7 +418,7 @@ GSkymap& GSkymap::operator-=(const GSkymap& map) |
| 418 | 418 | std::string msg = "Mismatch of number of maps in skymap object" |
| 419 | 419 | " ("+gammalib::str(nmaps())+" maps in destination" |
| 420 | 420 | " map, "+gammalib::str(map.nmaps())+" in source" |
| 421 | - " map."; | |
| 421 | + " map)."; | |
| 422 | 422 | throw GException::invalid_value(G_OP_UNARY_SUB, msg); |
| 423 | 423 | } |
| 424 | 424 | |
| ... | ... | @@ -492,7 +492,7 @@ GSkymap& GSkymap::operator*=(const GSkymap& map) |
| 492 | 492 | std::string msg = "Mismatch of number of maps in skymap object" |
| 493 | 493 | " ("+gammalib::str(nmaps())+" maps in destination" |
| 494 | 494 | " map, "+gammalib::str(map.nmaps())+" in source" |
| 495 | - " map."; | |
| 495 | + " map)."; | |
| 496 | 496 | throw GException::invalid_value(G_OP_UNARY_MUL, msg); |
| 497 | 497 | } |
| 498 | 498 | |
| ... | ... | @@ -567,7 +567,7 @@ GSkymap& GSkymap::operator/=(const GSkymap& map) |
| 567 | 567 | std::string msg = "Mismatch of number of maps in skymap object" |
| 568 | 568 | " ("+gammalib::str(nmaps())+" maps in destination" |
| 569 | 569 | " map, "+gammalib::str(map.nmaps())+" in source" |
| 570 | - " map."; | |
| 570 | + " map)."; | |
| 571 | 571 | throw GException::invalid_value(G_OP_UNARY_DIV, msg); |
| 572 | 572 | } |
| 573 | 573 | |
| ... | ... | @@ -847,35 +847,53 @@ double GSkymap::operator()(const GSkyDir& dir, const int& map) const |
| 847 | 847 | // Continue only if pixel is within the map |
| 848 | 848 | if (m_contained) { |
| 849 | 849 | |
| 850 | - // Set left indices for interpolation. The left index is | |
| 851 | - // comprised between 0 and npixels-2. By definition, the | |
| 852 | - // right index is then the left index + 1 | |
| 853 | - int inx_x = int(pixel.x()); | |
| 854 | - int inx_y = int(pixel.y()); | |
| 855 | - if (inx_x < 0) { | |
| 856 | - inx_x = 0; | |
| 850 | + // Signal that we have a wrap around in the x axis | |
| 851 | + double x_size = std::abs(m_num_x * static_cast<GWcs*>(m_proj)->cdelt(0)); | |
| 852 | + bool x_wrap = (x_size > 359.99); | |
| 853 | + | |
| 854 | + // Set left and right indices for interpolation. The left | |
| 855 | + // index needs to non-negative and the right index needs | |
| 856 | + // to be not larger that the number of pixels. We treat | |
| 857 | + // here also the special case of wrap around in the x | |
| 858 | + // axis that may occur if we have an allsky map. | |
| 859 | + int inx_x_left = int(pixel.x()); | |
| 860 | + int inx_y_left = int(pixel.y()); | |
| 861 | + int inx_x_right = inx_x_left + 1; | |
| 862 | + int inx_y_right = inx_y_left + 1; | |
| 863 | + if (inx_x_left < 0) { | |
| 864 | + if (x_wrap) { | |
| 865 | + inx_x_left += m_num_x; | |
| 866 | + } | |
| 867 | + else { | |
| 868 | + inx_x_left = 0; | |
| 869 | + } | |
| 857 | 870 | } |
| 858 | - else if (inx_x > m_num_x-2) { | |
| 859 | - inx_x = m_num_x - 2; | |
| 871 | + if (inx_y_right >= m_num_x) { | |
| 872 | + if (x_wrap) { | |
| 873 | + inx_y_right -= m_num_x; | |
| 874 | + } | |
| 875 | + else { | |
| 876 | + inx_y_right = m_num_x - 1; | |
| 877 | + } | |
| 860 | 878 | } |
| 861 | - if (inx_y < 0) { | |
| 862 | - inx_y = 0; | |
| 879 | + if (inx_y_left < 0) { | |
| 880 | + inx_y_left = 0; | |
| 863 | 881 | } |
| 864 | - else if (inx_y > m_num_y-2) { | |
| 865 | - inx_y = m_num_y - 2; | |
| 882 | + if (inx_y_right >= m_num_y) { | |
| 883 | + inx_y_right = m_num_y - 1; | |
| 866 | 884 | } |
| 867 | 885 | |
| 868 | 886 | // Set weighting factors for interpolation |
| 869 | - double wgt_x_right = (pixel.x() - inx_x); | |
| 887 | + double wgt_x_right = (pixel.x() - int(pixel.x())); | |
| 870 | 888 | double wgt_x_left = 1.0 - wgt_x_right; |
| 871 | - double wgt_y_right = (pixel.y() - inx_y); | |
| 889 | + double wgt_y_right = (pixel.y() - int(pixel.y())); | |
| 872 | 890 | double wgt_y_left = 1.0 - wgt_y_right; |
| 873 | 891 | |
| 874 | 892 | // Compute skymap pixel indices for bi-linear interpolation |
| 875 | - m_interpol.index1() = inx_x + inx_y * m_num_x; | |
| 876 | - m_interpol.index2() = m_interpol.index1() + m_num_x; | |
| 877 | - m_interpol.index3() = m_interpol.index1() + 1; | |
| 878 | - m_interpol.index4() = m_interpol.index2() + 1; | |
| 893 | + m_interpol.index1() = inx_x_left + inx_y_left * m_num_x; | |
| 894 | + m_interpol.index2() = inx_x_left + inx_y_right * m_num_x; | |
| 895 | + m_interpol.index3() = inx_x_right + inx_y_left * m_num_x; | |
| 896 | + m_interpol.index4() = inx_x_right + inx_y_right * m_num_x; | |
| 879 | 897 | |
| 880 | 898 | // Compute weighting factors for bi-linear interpolation |
| 881 | 899 | m_interpol.weight1() = wgt_x_left * wgt_y_left; |
| ... | ... | @@ -1644,7 +1662,6 @@ void GSkymap::load(const std::string& filename) |
| 1644 | 1662 | |
| 1645 | 1663 | // Load WCS map |
| 1646 | 1664 | read_wcs(static_cast<const GFitsImage&>(hdu)); |
| 1647 | - //loaded = true; | |
| 1648 | 1665 | break; |
| 1649 | 1666 | |
| 1650 | 1667 | } // endfor: looped over HDUs |
| ... | ... | @@ -2129,8 +2146,9 @@ void GSkymap::read_healpix(const GFitsTable& table) |
| 2129 | 2146 | * |
| 2130 | 2147 | * @param[in] image FITS image. |
| 2131 | 2148 | * |
| 2132 | - * @exception GException::skymap_bad_image_dim | |
| 2133 | - * WCS image has invalid dimension (naxis=2 or 3). | |
| 2149 | + * @exception GException::invalid_value | |
| 2150 | + * WCS image has an invalid dimension or covers a too large | |
| 2151 | + * range. | |
| 2134 | 2152 | ***************************************************************************/ |
| 2135 | 2153 | void GSkymap::read_wcs(const GFitsImage& image) |
| 2136 | 2154 | { |
| ... | ... | @@ -2152,7 +2170,10 @@ void GSkymap::read_wcs(const GFitsImage& image) |
| 2152 | 2170 | m_num_maps = image.naxes(2); |
| 2153 | 2171 | } |
| 2154 | 2172 | else { |
| 2155 | - throw GException::skymap_bad_image_dim(G_READ_WCS, image.naxis()); | |
| 2173 | + std::string msg = "Skymap has a dimension of "+ | |
| 2174 | + gammalib::str(image.naxis())+" but only dimensions " | |
| 2175 | + "of 2 or 3 are supported."; | |
| 2176 | + throw GException::invalid_value(G_READ_WCS, msg); | |
| 2156 | 2177 | } |
| 2157 | 2178 | #if defined(G_READ_WCS_DEBUG) |
| 2158 | 2179 | std::cout << "m_num_x=" << m_num_x << std::endl; |
| ... | ... | @@ -2189,6 +2210,24 @@ void GSkymap::read_wcs(const GFitsImage& image) |
| 2189 | 2210 | } |
| 2190 | 2211 | } |
| 2191 | 2212 | |
| 2213 | + // Check if the map is too large | |
| 2214 | + double x_size = std::abs(m_num_x * static_cast<GWcs*>(m_proj)->cdelt(0)); | |
| 2215 | + double y_size = std::abs(m_num_y * static_cast<GWcs*>(m_proj)->cdelt(1)); | |
| 2216 | + if (x_size > 360.001) { | |
| 2217 | + std::string msg = "Skymap covers "+gammalib::str(x_size)+" degrees " | |
| 2218 | + "in the X axis which results in ambiguous " | |
| 2219 | + "coordinate transformations. Please provide a " | |
| 2220 | + "skymap that does not cover more than 360 degrees."; | |
| 2221 | + throw GException::invalid_value(G_READ_WCS, msg); | |
| 2222 | + } | |
| 2223 | + if (y_size > 180.001) { | |
| 2224 | + std::string msg = "Skymap covers "+gammalib::str(y_size)+" degrees " | |
| 2225 | + "in the Y axis which results in ambiguous " | |
| 2226 | + "coordinate transformations. Please provide a " | |
| 2227 | + "skymap that does not cover more than 180 degrees."; | |
| 2228 | + throw GException::invalid_value(G_READ_WCS, msg); | |
| 2229 | + } | |
| 2230 | + | |
| 2192 | 2231 | // Return |
| 2193 | 2232 | return; |
| 2194 | 2233 | } | ... | ... |