-
Notifications
You must be signed in to change notification settings - Fork 26
Add asymmetric energy dispersion/migration support #300
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
base: main
Are you sure you want to change the base?
Conversation
- energy_migration_matrix_polar calculates the migration matrix with FoV binning in true_source_fov_offset and true_source_fov_position angle of the FoV - energy_migration_matrix_lonlat uses true_source_fov_longitude and true_source_fov_latitude
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #300 +/- ##
==========================================
+ Coverage 95.60% 95.95% +0.34%
==========================================
Files 62 65 +3
Lines 3278 3856 +578
==========================================
+ Hits 3134 3700 +566
- Misses 144 156 +12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
pyirf/io/gadf.py
Outdated
| **header_cards, | ||
| ): | ||
| """ | ||
| Create a fits binary table HDU in GADF format for the asymmetric energy dispersion with polar FoV coordinates. |
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 have a small worry about the terminology: Since it's not obvious that "asymmetric" here means "non-radially-symmetric", i.e. with an azimuthal dependence, it would be good to explain that better. Otherwise, i would think "asymmetric energy dispersion" is asymmetric in true energy, which it is, but that is not what we are talking about here. Maybe just use similar terminology for describing spatial models as gammapy: 1D vs 2D, i.e.:
- 1D-polar: model is radially symmetric, i.e. no azimuthal dependance, f(r)
- 2D-polar: model depends on radius and azimuth, f(r,phi)
- 2D-cartesian: projected (?) fov_lon and fov_lat dependance, f(dlon,dlat)
Then your functions become, e.g. create_energy_dispersion_2d_polar_hdu
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.
Thanks for your input!
Yes, I can see there certainly is some ambiguity in just calling it "asymmetric" and I agree that there might be a better way to express this.
Gammapy does not use the "nD" terminology to describe just the spatial axes though (at least for the IRFs), but includes the energy axis as well, e.g.
EnergyDispersion2Daxes:energy_trueandoffset,migra(This implies to me themigraaxis is ignored. Is this intentional or an inconsistency?)PSF3Daxes:energy_true,offsetandrad.
I definitely think we should be consistent in the naming convention and that there is probably value in also being consistent with gammapy in the future. Whatever way is decided on should be applied to the rest of the IRF package in my opinion, but the details warrant some discussion. For reference, in the non-radially symmetric effective area I also chose the "3D" naming convention, see #281.
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 inconsistency is in calling PSF3D 3D.
I think the "ND" should refer to the dimensions in the phase space in which an IRF component is stored, excluding intrinsic axes of the IRF component itself.
GADF calls effective area and energy dispersion 2d (energy and offset). The migra axis for the dispersion is an intrinsic axis of the IRF.
But then GADF calls the the "2d" PSF PSF_TABLE and gammapy changed that to PSF3D for some reason. It should have been PSF2D
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 the "ND" should refer to the dimensions in the phase space in which an IRF component is stored, excluding intrinsic axes of the IRF component itself.
This also seems reasonable to me, however then the GADF PSF_TABLE breaks with this again, as you said of course.
I would propose that for this PR in accordance with the GADF I change the naming to "3D", however this leaves the PSF for which I would also soon want to create a PR. Is this worth an issue to discuss the naming etc.?
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.
Yes, I agree with the dimensionality being the spatial+energy, so my comment above becomes just d+1.
But you are right... for PSF you really need to describe both the internal (source coordinate) and external (field-of-view coordinate) dimensionality to be fully unambiguous. Not sure the best way to name those... e.g. a model with a "2D" distribution of the PSF that changes with energy, radius and azimuth in the FOV: PSF2D_3D? 2DPSF3D?, PolarPSF3D (vs RadialPSF3D for the case where the PSF itself is only radial in source coordinates)?, . It gets ugly! @bkhelifi let's try to get this right for VODF...
pyirf/io/gadf.py
Outdated
| Bin edges in true energy | ||
| migration_bins: numpy.ndarray | ||
| Bin edges for the relative energy migration (``reco_energy / true_energy``) | ||
| fov_offset_bins: astropy.units.Quantity[angle] |
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.
Docstring doesn't match signature: cut and paste error?
|
Once you have some example file, do not hesitate to send them to the Gammapy team in order to make some tests... except if you have already made them;) |
docs/changes/300.feature.rst
Outdated
| * ``energy_migration_matrix_asymmetric_lonlat`` | ||
| * ``energy_dispersion_to_migration_asymmetric`` | ||
|
|
||
| Also adds functions to create fits table HDUs in GADF format for the energy dispersion to ``pyirf.io.gadf``. |
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.
Technically, this is not GADF as GADF does not have these.
Maybe write "similar to existing GADF defintions"?
pyirf/io/gadf.py
Outdated
| header["HDUCLAS4"] = "EDISP_3D" | ||
| header["DATE"] = Time.now().utc.iso | ||
| idx = edisp.colnames.index("MATRIX") + 1 | ||
| header[f"CREF{idx}"] = "(ENERG_LO:ENERG_HI,MIGRA_LO:MIGRA_HI,DETX_LO:DETX_HI,DETY_LO:DETY_HI)" |
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'd put the migra axis last, see open-gamma-ray-astro/gamma-astro-data-formats#178
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 see the point, however in that case for consistency's sake the same should be applied to the 2D energy dispersion as well in my opinion. After checking this causes problems with the current tests for IO, specifically with the test_cref function. Will try to resolve these.
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 agree in principle, but we are in a different situation with the 2d energy dispersion: we have it in GADF with the preferred axis order defined, so we should follow it. That this order is not the one we would prefer is an issue for GADF.
The 3D is new, so we should do what we think is most appropriate.
pyirf/irf/energy_dispersion.py
Outdated
| np.column_stack( | ||
| [ | ||
| selected_events["true_energy"].to_value(u.TeV), | ||
| mu, |
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.
See comment above about axis order.
Please put the migra axis last. In general, the IRF intrinsic axes should come after the "parameter" axes.
Axis order for 3D EDISP is now changed to put the intrinsic axis last. Relevant tests updated accordingly. 3D EDISP is no longer wrongly referred to as part of GADF definitions.
This adds functions for calculating the asymmetric energy dispersion and migration matricies to
pyirf.irf.energy_dispersionand creating FITS table HDUs for the asymmetric energy dispersion topyirf.io.gadf.The functions are separated into functions for a
theta/phiandlon/latFoV binning for the direct calculation of energy dispersion and migration and the HDUs:energy_dispersion_asymmetric_polarenergy_dispersion_asymmetric_lonlatenergy_migration_matrix_asymmetric_polarenergy_migration_matrix_asymmetric_lonlatcreate_energy_dispersion_asymmetric_polar_hducreate_energy_dispersion_asymmetric_lonlat_hduWhereas the function for conversion from dispersion to migration
energy_dispersion_to_migration_asymmetricdoes not require this.