Repository: gammapy/gammapy

Issue:
IndexError from SpectrumEnergyGroupMaker
In this example CTA DC1 analysis the SpectrumEnergyGroupMaker give an IndexError if e.g. `emax=100 TeV` is chosen (see comment in cell 23):

https://github.com/gammasky/cta-analyses/blob/bf571038b389b3eb13ce8ba81b35384ebd4b6750/dc-1-checks/hess_j1702/spectrum.ipynb


Discussion:
@robertazanin - I've edited the issue and description above. The bug must be in the energy group computation.
Should be fixed in gammapy master now, since last week (see #1493).
Please try again!
If there's still any issue with energy grouping, please re-open or file a new issue!
@robertazanin still has a case with an `IndexError`, see cell 32 here:

```
# TODO: this gives an IndexError. Why?
# ebounds = EnergyBounds.equal_log_spacing(0.11, 159, 5, unit = u.TeV)
```
https://github.com/gammasky/cta-analyses/blob/master/dc-1-checks/hess_j1702/1D_spectral_analysis.ipynb

@joleroi - Please have a look or assign over to me.
Indeed I can reproduce the error with this MWP

```
from gammapy.utils.energy import EnergyBounds
import astropy.units as u 
from gammapy.spectrum import SpectrumEnergyGroupMaker

e_reco = EnergyBounds.equal_log_spacing(0.01, 100, 72, u.TeV)
desired = EnergyBounds.equal_log_spacing(0.1, 160, 35, u.TeV)
print(desired)

class DummyObs(object): pass

obs = DummyObs
obs.e_reco = e_reco.to('keV')

seg = SpectrumEnergyGroupMaker(obs=obs)
seg.compute_groups_fixed(desired)
```

The error does not occure if I remove the conversion of ``e_reco`` to ``keV`` so it's probably a lacking unit converison somewhere and should be trivial to fix.

Resolving patch:
diff --git a/gammapy/spectrum/energy_group.py b/gammapy/spectrum/energy_group.py
--- a/gammapy/spectrum/energy_group.py
+++ b/gammapy/spectrum/energy_group.py
@@ -251,7 +251,7 @@ def compute_groups_fixed(self, ebounds):
         ebounds : `~astropy.units.Quantity`
             Energy bounds array
         """
-        ebounds_src = self.obs.e_reco
+        ebounds_src = self.obs.e_reco.to(ebounds.unit)
         bin_edges_src = np.arange(len(ebounds_src))
 
         temp = np.interp(ebounds, ebounds_src, bin_edges_src)
@@ -278,6 +278,11 @@ def compute_groups_fixed(self, ebounds):
             )
             groups.append(group)
 
+        if groups == []:
+            err_str = "Input binning\n{}\n has no overlap with"
+            err_str += " target binning\n{}"
+            raise ValueError(err_str.format(ebounds, ebounds_src))
+
         # Add underflow bin
         start_edge = groups[0].bin_idx_min
         if start_edge != 0:


Test patch:
diff --git a/gammapy/spectrum/tests/test_energy_group.py b/gammapy/spectrum/tests/test_energy_group.py
--- a/gammapy/spectrum/tests/test_energy_group.py
+++ b/gammapy/spectrum/tests/test_energy_group.py
@@ -127,7 +127,10 @@ def test_compute_groups_fixed_basic(self, obs):
 
         assert groups == expected
 
-    @pytest.mark.parametrize("ebounds", [[1.8, 4.8, 7.2] * u.TeV, [2, 5, 7] * u.TeV])
+    @pytest.mark.parametrize("ebounds", [
+        [1.8, 4.8, 7.2] * u.TeV,
+        [2, 5, 7] * u.TeV,
+        [2000, 5000, 7000] * u.GeV])
     def test_compute_groups_fixed_edges(self, obs, ebounds):
         seg = SpectrumEnergyGroupMaker(obs=obs)
         seg.compute_groups_fixed(ebounds=ebounds)
@@ -168,3 +171,9 @@ def test_compute_groups_fixed_above_range(self, obs):
         ])
 
         assert groups == expected
+
+    def test_compute_groups_fixed_outside_range(self, obs):
+        ebounds = [20, 30, 40] * u.TeV
+        seg = SpectrumEnergyGroupMaker(obs=obs)
+        with pytest.raises(ValueError):
+            seg.compute_groups_fixed(ebounds=ebounds)