New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spectrum energy grouping #709
Conversation
@joleroi @registerrier @leajouvin - If you have time, could you please have a look at this and let me know if you have any thoughts on how energy bin grouping should be implemented and exposed in Gammapy? (Alternatively, do you have examples how to use the energy bin grouping in Sherpa and do you think we should just use that or wrap it in Gammapy?) |
2147ab4
to
9e3642f
Compare
@joleroi - I'll merge this tomorrow morning. But comments or even a full review would still be very welcome. I plan to continue improving and extending this in the coming days. |
I had a look at your notes. Here are my comments
|
OVERFLOW_BIN_INDEX = -2 | ||
|
||
|
||
class SpectrumEnergyGroupMaker(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think at the coding sprint we agreed to not use Makers
in Gammapy.
Why not just SpectrumEnergyGrouping
?
Attributes | ||
---------- | ||
obs : `~gammapy.spectrum.SpectrumObservation` | ||
Spectrum observation data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this stacked or not? Looks like stacked, but it should be clear from the docstring
|
||
# Methods to compute groupings | ||
|
||
def compute_groups_fixed(self, ebounds): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stacked spectrum object does not have data outside the safe energy range. What does this method do if ebounds[0] < obs.lo_threshold?
|
||
def compute_groups_npoints(self, npoints): | ||
"""TODO: document""" | ||
emin, emax = self.get_safe_range() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't find the get_safe_range() method? Anyway, IMO it should be on SpectrumObservation
.
def compute_groups_npoints(self, npoints): | ||
"""TODO: document""" | ||
emin, emax = self.get_safe_range() | ||
npoints = self.config['n_points'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the config attribute?
return ss | ||
|
||
|
||
class EnergyRange(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is the appropriate place for this class. It reproduces a lot of the functionality that is already in the EnergyBounds. See also
http://docs.gammapy.org/en/latest/utils/index.html#energy-handling-in-gammapy
return str(self.to_dict()) | ||
|
||
|
||
class SpectrumEnergyGroups(list): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to see the purpose of this class without much documentation. At first sight it looks super-complicated. In the end we just want a list with integers to put each fine energy bin into one flux points group, this list then goes to the flux point computation method. Can you add some explanation what this is for?
'SpectrumObservation', | ||
'SpectrumObservationList', | ||
] | ||
|
||
|
||
class SpectrumStats(ObservationStats): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I wanted to have this since a long time ago
@@ -78,6 +99,11 @@ def alpha(self): | |||
return self.on_vector.backscal / self.off_vector.backscal | |||
|
|||
@property | |||
def ebounds(self): | |||
"""Energy bounds array.""" | |||
return self.on_vector.energy.data.to('TeV') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you have the ``to('TeV')`?
# in order to add spectrum specific information | ||
kwargs = dict( | ||
return SpectrumStats( | ||
energy_min=self.ebounds[:-1], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be self.lo_threshold, no? That's at least what I would expect
obs_id=self.obs_id, | ||
livetime=self.livetime, | ||
) | ||
return ObservationStats(**kwargs) | ||
|
||
def stats_table(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@cdeil Do you still plan to work on this? |
This pull request
gammapy/spectrum/group.py
togammapy/spectrum/obs_group.py
to make the distinction between grouping energy bins or observations clear.ObservationStats.to_dict
andSpectrumObservation.stats_table
, which are useful to have to compute energy groupings.table_from_row_data
utility functionSpectrumStats
classgammapy/spectrum/energy_group.py
and moves thecalculate_flux_point_binning
function which was ingammapy/spectrum/utils.py
there.SpectrumEnergyGroupMaker
class that takes aSpectrumObservation
and has methods to compute energy groupings (energy bin range selection and grouping)SpectrumEnergyGroupMaker
uses aSpectrumEnergyGroups
object to do the bookkeeping and some of the calculations, which is a list ofSpectrumEnergyGroup
objects, which are simple containers to do book-keeping and some simple operations.This is left to future PRs:
calculate_flux_point_binning
to work withENERGY_GROUP_ID
index arrays instead ofENERGY_BOUNDS
float arrays with the brittle float eps check will be done in a future pull request.