Repository: gammapy/gammapy

Issue:
Incorrect results for SkyPointSource
The SkyPointSource spatial model gives a wrong npred.

eg:

`spatial_model = SkyGaussian(
    lon_0='0.2 deg',
    lat_0='0.1 deg',
    sigma='0.01 deg',
)
spectral_model = PowerLaw(
    index=3,
    amplitude='1e-11 cm-2 s-1 TeV-1',
    reference='1 TeV',
)
sky_model = SkyModel(
    spatial_model=spatial_model,
    spectral_model=spectral_model,
)'
'evaluator = MapEvaluator(sky_model, exposure=exposure_map)'
'npred = evaluator.compute_npred()'
'print(npred.sum())`

gives  `3846` predicted events in total.

`spatial_model1 = SkyPointSource(
    lon_0='0.2 deg',
    lat_0='0.1 deg',
)
spectral_model = PowerLaw(
    index=3,
    amplitude='1e-11 cm-2 s-1 TeV-1',
    reference='1 TeV',
)
sky_model1 = SkyModel(
    spatial_model=spatial_model1,
    spectral_model=spectral_model,
)'
`evaluator = MapEvaluator(sky_model1, exposure=exposure_map)`
`npred = evaluator.compute_npred()`
`print(npred.sum())`

gives `0.0004824` predicted events in total



(for the detailed code, see https://gist.github.com/AtreyeeS/d5161ebe30f29c1a19b34757a1916301)






Discussion:
I'm pretty sure that this is an issue of flux vs. surface density, so a missing division by the solid angle of the pixel. I'll look into it...  
@AtreyeeS - If you do the checks in a bit more systematic way, it could either be Python scripts or notebooks in gammapy-extra, and/or it could by one test per sky model with an assert on an npred when passing it to a SkyModelEvaluator. Then we know where we stand, and can refactor evaluation between the sky model evaluate and the evaluator.
I see that just the test for the SkyPointSource` woks well, but the  MapEvaluator has tests only for the `SkyGaussian` spectral model. I am guessing that the error lies there. 
Cleaning up my pull distribution code now.

Resolving patch:
diff --git a/gammapy/image/models/new.py b/gammapy/image/models/new.py
--- a/gammapy/image/models/new.py
+++ b/gammapy/image/models/new.py
@@ -82,7 +82,7 @@ def __init__(self, lon_0, lat_0):
     def evaluate(lon, lat, lon_0, lat_0):
         """Evaluate the model (static function)."""
 
-        wrapval=lon_0 + 180*u.deg
+        wrapval = lon_0 + 180 * u.deg
         lon = Angle(lon).wrap_at(wrapval)
 
         _, grad_lon = np.gradient(lon)
@@ -90,10 +90,10 @@ def evaluate(lon, lat, lon_0, lat_0):
         lon_diff = np.abs((lon - lon_0) / grad_lon)
         lat_diff = np.abs((lat - lat_0) / grad_lat)
 
-        lon_val = np.select([lon_diff < 1], [1 - lon_diff], 0)
-        lat_val = np.select([lat_diff < 1], [1 - lat_diff], 0)
+        lon_val = np.select([lon_diff < 1], [1 - lon_diff], 0) / np.abs(grad_lon)
+        lat_val = np.select([lat_diff < 1], [1 - lat_diff], 0) / np.abs(grad_lat)
         val = lon_val * lat_val
-        return val * u.Unit('sr-1')
+        return val.to('sr-1')
 
 
 class SkyGaussian(SkySpatialModel):
@@ -189,7 +189,7 @@ class SkyShell(SkySpatialModel):
                 \begin{cases}
                     \sqrt{r_{out}^2 - \theta^2} - \sqrt{r_{in}^2 - \theta^2} &
                                  \text{for } \theta \lt r_{in} \\
-                    \sqrt{r_{out}^2 - \theta^2} & 
+                    \sqrt{r_{out}^2 - \theta^2} &
                                  \text{for } r_{in} \leq \theta \lt r_{out} \\
                     0 & \text{for } \theta > r_{out}
                 \end{cases}


Test patch:
diff --git a/gammapy/image/models/tests/test_models.py b/gammapy/image/models/tests/test_models.py
--- a/gammapy/image/models/tests/test_models.py
+++ b/gammapy/image/models/tests/test_models.py
@@ -22,7 +22,7 @@ def test_sky_point_source():
     lat, lon = np.mgrid[0:6, 0:6] * u.deg
     val = model(lon, lat)
     assert val.unit == 'sr-1'
-    assert_allclose(val.sum().value, 1.0)
+    assert_allclose(val.sum().value, 3282.80635)
 
 
 def test_sky_gaussian():