Skip to content
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

Add basic facilities for 3D background irfs #276

Open
wants to merge 52 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
8042e5b
Add basic facilities for 3D background irfs
Tobychev Jan 16, 2024
5c5bded
:x
Tobychev Feb 6, 2024
7c6d158
Should now support rectangular arrays
Tobychev Feb 6, 2024
2990605
Remove compatibility pins
maxnoe Apr 2, 2024
c7db045
Merge pull request #283 from cta-observatory/gammapy_pin
maxnoe Apr 3, 2024
17a7514
Add 2023 ICRC paper to README
RuneDominik Apr 8, 2024
8c48951
Merge pull request #284 from cta-observatory/Readme
maxnoe Apr 8, 2024
ec66690
Add basic facilities for 3D background irfs
Tobychev Jan 16, 2024
6d41197
Should now support rectangular arrays
Tobychev Feb 6, 2024
084a2b8
Merge remote-tracking branch 'refs/remotes/origin/background3d' into …
Tobychev Nov 6, 2024
7fc4c74
Fixes requested by Max, added test
Tobychev Nov 8, 2024
a3325f3
Add tests for more correct handling of fill-values in RadMaxEstimator
RuneDominik Feb 16, 2024
0b3e177
Add more correct handling of fill-values in RadMaxEstimator
RuneDominik Feb 16, 2024
7d8f79f
Add newsfragment
RuneDominik Mar 21, 2024
211f712
adress comments
RuneDominik Apr 8, 2024
a46b73a
Render changelog for 0.11
maxnoe May 14, 2024
1682914
Make things compatible with numpy 2.0; replace deprecated logging.warn()
LukasBeiske Sep 30, 2024
dd68f06
Add changelog entry
LukasBeiske Sep 30, 2024
fa5af1f
Update .mailmap
HealthyPear May 28, 2024
0803c77
Add option of multiple quantiles to angular_resolution
LukasBeiske Sep 30, 2024
254c4c1
No mutable default argument; check for sequence, not list and np.ndarray
LukasBeiske Oct 1, 2024
592c4c6
Do not change column naming based on number of quantiles
LukasBeiske Oct 8, 2024
38fff11
Fix docs warning
maxnoe Oct 21, 2024
b80d8fb
Address comments
LukasBeiske Oct 21, 2024
fe9e478
Call np.nanquantile with multiple quantiles
LukasBeiske Oct 21, 2024
01fb541
Rename and update changelog
LukasBeiske Nov 6, 2024
84fda49
Add 2 methods to calculate effective area in energy and 2 spacial dim…
Feb 12, 2024
68c3fa6
Add methods to calculate n_showers in energy and 2 spacial dimensions
Feb 12, 2024
242ecab
Add util for calculating FOV position angle
Feb 13, 2024
50d8002
Fix effective_area_3d and poition angle util
Feb 13, 2024
6547e22
Fix missing comma
Feb 13, 2024
b43c0aa
Fix typos causing error when calling calculate_n_showers_3d_*
Feb 15, 2024
a7c5a9a
Remove redundant argument breaking calculate_n_showers_3d call
Feb 15, 2024
e033135
Fix formatting and issues from pull request Effective Area 3D (no. 28…
Feb 15, 2024
cb58e41
Add functions to transform from sky coordinates to FOV coordinates
Mar 1, 2024
2ec0a19
Update calculate_n_showers_3d functions and add tests
Mar 1, 2024
4674679
Fix position angle function, add rectangle solid angle function and t…
Mar 1, 2024
5e38254
Update effective area 3D functions and add corresponding tests
Mar 1, 2024
8e017c5
Fix code review issues
Apr 15, 2024
2a91a87
Update function names in __all__
Apr 18, 2024
b516419
Fix all changed occurences of gadf coordinate function calls
Apr 18, 2024
e18e1ae
Change az/alt to lon/lat due to support of both AltAz and ICRS
Apr 30, 2024
3162c4a
Add newsfragment
Apr 30, 2024
8cd0e75
Properly handle viewcone_min > 0, add docstring
May 2, 2024
82b60b3
Add missing condition to all_outside check
May 14, 2024
a63a56b
Update energy_dispersion_to_migration
HealthyPear Dec 12, 2023
f3b4d04
Add function to compute energy migration matrix from events
HealthyPear Dec 12, 2023
7f2d45d
Add unit test for energy migration matrix from events
HealthyPear Dec 12, 2023
2bd128c
Update test_energy_dispersion_to_migration
HealthyPear Dec 12, 2023
4bc8f57
fix: docstring irf.energy_dispersion.energy_migration_matrix
HealthyPear Nov 7, 2024
82e2035
Add basic facilities for 3D background irfs
Tobychev Jan 16, 2024
03b9626
Fixes
Tobychev Nov 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pyirf/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
create_psf_table_hdu,
create_rad_max_hdu,
create_background_2d_hdu,
create_background_3d_hdu,
)


Expand All @@ -16,4 +17,5 @@
"create_psf_table_hdu",
"create_rad_max_hdu",
"create_background_2d_hdu",
"create_background_3d_hdu",
]
51 changes: 51 additions & 0 deletions pyirf/io/gadf.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,57 @@
return BinTableHDU(bkg, header=header, name=extname)


@u.quantity_input(
background=GADF_BACKGROUND_UNIT, reco_energy_bins=u.TeV, fov_offset_bins=u.deg,
)
def create_background_3d_hdu(
background_3d,
reco_energy_bins,
fov_offset_bins,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should have fov_lon_bins / fov_lat_bins

extname="BACKGROUND",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to define the alignment

**header_cards,
):
"""
Create a fits binary table HDU in GADF format for the background 3d table. Assumes ALTAZ coordinates.
See the specification at
https://gamma-astro-data-formats.readthedocs.io/en/latest/irfs/full_enclosure/bkg/index.html#bkg-2d

Parameters
----------
background_3d: astropy.units.Quantity[(MeV s sr)^-1]
Background rate, must have shape
(n_energy_bins, n_fov_offset_bins, n_fov_offset_bins)
reco_energy_bins: astropy.units.Quantity[energy]
Bin edges in reconstructed energy
fov_offset_bins: astropy.units.Quantity[angle]
Bin edges in the field of view offset.
extname: str
Name for BinTableHDU
**header_cards
Additional metadata to add to the header, use this to set e.g. TELESCOP or
INSTRUME.
"""

bkg = QTable()
bkg["ENERG_LO"], bkg["ENERG_HI"] = binning.split_bin_lo_hi(reco_energy_bins[np.newaxis, :].to(u.TeV))
bkg["DETX_LO"], bkg["DETX_HI"] = binning.split_bin_lo_hi(fov_offset_bins[np.newaxis, :].to(u.deg))
bkg["DETY_LO"], bkg["DETY_HI"] = binning.split_bin_lo_hi(fov_offset_bins[np.newaxis, :].to(u.deg))

Check warning on line 297 in pyirf/io/gadf.py

View check run for this annotation

Codecov / codecov/patch

pyirf/io/gadf.py#L294-L297

Added lines #L294 - L297 were not covered by tests
# transpose as FITS uses opposite dimension order
bkg["BKG"] = background_3d.T[np.newaxis, ...].to(GADF_BACKGROUND_UNIT)

Check warning on line 299 in pyirf/io/gadf.py

View check run for this annotation

Codecov / codecov/patch

pyirf/io/gadf.py#L299

Added line #L299 was not covered by tests

# required header keywords
header = DEFAULT_HEADER.copy()
header["HDUCLAS1"] = "RESPONSE"
header["HDUCLAS2"] = "BKG"
header["HDUCLAS3"] = "FULL-ENCLOSURE"
header["HDUCLAS4"] = "BKG_2D"
Tobychev marked this conversation as resolved.
Show resolved Hide resolved
header["FOVALIGN"] = "ALTAZ"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an argument, not hard-coded

header["DATE"] = Time.now().utc.iso
_add_header_cards(header, **header_cards)

Check warning on line 309 in pyirf/io/gadf.py

View check run for this annotation

Codecov / codecov/patch

pyirf/io/gadf.py#L302-L309

Added lines #L302 - L309 were not covered by tests

return BinTableHDU(bkg, header=header, name=extname)

Check warning on line 311 in pyirf/io/gadf.py

View check run for this annotation

Codecov / codecov/patch

pyirf/io/gadf.py#L311

Added line #L311 was not covered by tests


@u.quantity_input(
rad_max=u.deg,
reco_energy_bins=u.TeV,
Expand Down
3 changes: 2 additions & 1 deletion pyirf/irf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
)
from .energy_dispersion import energy_dispersion
from .psf import psf_table
from .background import background_2d
from .background import background_2d, background_3d

__all__ = [
"effective_area",
Expand All @@ -14,4 +14,5 @@
"energy_dispersion",
"psf_table",
"background_2d",
"background_3d",
]
70 changes: 68 additions & 2 deletions pyirf/irf/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from ..utils import cone_solid_angle

#: Unit of the background rate IRF
BACKGROUND_UNIT = u.Unit('s-1 TeV-1 sr-1')
BACKGROUND_UNIT = u.Unit("s-1 TeV-1 sr-1")


def background_2d(events, reco_energy_bins, fov_offset_bins, t_obs):
Expand Down Expand Up @@ -43,7 +43,7 @@
reco_energy_bins.to_value(u.TeV),
fov_offset_bins.to_value(u.deg),
],
weights=events['weight'],
weights=events["weight"],
)

# divide all energy bins by their width
Expand All @@ -56,3 +56,69 @@
bg_rate = per_energy / t_obs / bin_solid_angle

return bg_rate.to(BACKGROUND_UNIT)


def background_3d(events, reco_energy_bins, fov_offset_bins, t_obs):
"""
Calculate background rates in square bins in the field of view.

GADF documentation here:
https://gamma-astro-data-formats.readthedocs.io/en/latest/irfs/full_enclosure/bkg/index.html#bkg-3d

Parameters
----------
events: astropy.table.QTable
DL2 events table of the selected background events.
Needed columns for this function: `reco_fov_lon`, `reco_fov_lat`,
`reco_energy`, `weight`.
reco_energy: astropy.units.Quantity[energy]
The bins in reconstructed energy to be used for the IRF
fov_offset_bins: astropy.units.Quantity[angle]
Tobychev marked this conversation as resolved.
Show resolved Hide resolved
The bins in the field of view offset to be used for the IRF, either a (N,) or (1,N) or a (2,N) array
t_obs: astropy.units.Quantity[time]
Observation time. This must match with how the individual event
weights are calculated.

Returns
-------
bg_rate: astropy.units.Quantity
The background rate as particles per energy, time and solid angle
in the specified bins.

Shape: (len(reco_energy_bins) - 1, len(fov_offset_bins) - 1, len(fov_offset_bins) - 1)
"""
if (fov_offset_bins.shape[0] == 1) or (len(fov_offset_bins.shape) == 1):
fov_x_offset_bins = fov_offset_bins
fov_y_offset_bins = fov_offset_bins
elif fov_offset_bins.shape[0] == 2:
fov_x_offset_bins = fov_offset_bins[0, :]
fov_y_offset_bins = fov_offset_bins[1, :]

Check warning on line 95 in pyirf/irf/background.py

View check run for this annotation

Codecov / codecov/patch

pyirf/irf/background.py#L90-L95

Added lines #L90 - L95 were not covered by tests
else:
raise ValueError(

Check warning on line 97 in pyirf/irf/background.py

View check run for this annotation

Codecov / codecov/patch

pyirf/irf/background.py#L97

Added line #L97 was not covered by tests
f"fov_offset_bins must be eiher (N,) or (1,N) or (2,N), found {fov_offset_bins.shape}"
)

hist, _ = np.histogramdd(

Check warning on line 101 in pyirf/irf/background.py

View check run for this annotation

Codecov / codecov/patch

pyirf/irf/background.py#L101

Added line #L101 was not covered by tests
[
events["reco_energy"].to_value(u.TeV),
(events["reco_fov_lon"]).to_value(u.deg),
Tobychev marked this conversation as resolved.
Show resolved Hide resolved
(events["reco_fov_lat"]).to_value(u.deg),
Tobychev marked this conversation as resolved.
Show resolved Hide resolved
],
bins=[
reco_energy_bins.to_value(u.TeV),
fov_x_offset_bins.to_value(u.deg),
fov_y_offset_bins.to_value(u.deg),
],
weights=events["weight"],
)

# divide all energy bins by their width
# hist has shape (n_energy, n_fov_offset) so we need to transpose and then back
bin_width_energy = np.diff(reco_energy_bins)
per_energy = (hist.T / bin_width_energy).T

Check warning on line 118 in pyirf/irf/background.py

View check run for this annotation

Codecov / codecov/patch

pyirf/irf/background.py#L117-L118

Added lines #L117 - L118 were not covered by tests
Tobychev marked this conversation as resolved.
Show resolved Hide resolved

# divide by solid angle in each fov bin and the observation time
bin_solid_angle = np.diff(fov_offset_bins)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The solid angle of the bins is not just the difference of the bin edges.

@luca-dib implemented the proper code here: #281 but it's not yet a proper function there but just computed inline

bg_rate = per_energy / t_obs / bin_solid_angle**2

Check warning on line 122 in pyirf/irf/background.py

View check run for this annotation

Codecov / codecov/patch

pyirf/irf/background.py#L121-L122

Added lines #L121 - L122 were not covered by tests

return bg_rate.to(BACKGROUND_UNIT)

Check warning on line 124 in pyirf/irf/background.py

View check run for this annotation

Codecov / codecov/patch

pyirf/irf/background.py#L124

Added line #L124 was not covered by tests
Loading