-
Notifications
You must be signed in to change notification settings - Fork 78
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
Allow using custom energy dependent cuts (e.g. based on sensitivity optimization) for IRFs and DL3 #1348
base: main
Are you sure you want to change the base?
Allow using custom energy dependent cuts (e.g. based on sensitivity optimization) for IRFs and DL3 #1348
Changes from all commits
168245b
50744b2
930012a
2571297
a54df62
b3d239a
87056e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
{ | ||
"EventSelector": { | ||
"filters": { | ||
"intensity": [50, Infinity], | ||
"width": [0, Infinity], | ||
"length": [0, Infinity], | ||
"r": [0, 1], | ||
"wl": [0.01, 1], | ||
"leakage_intensity_width_2": [0, 1], | ||
"event_type": [32, 32] | ||
} | ||
}, | ||
"IRFFITSWriter": { | ||
"cut_strategy_gh": "edep_custom", | ||
"cut_strategy_theta": "edep_custom", | ||
"cut_strategy_alpha": "edep_custom", | ||
"interpolate_custom": "nearest" | ||
}, | ||
"DL3Cuts": { | ||
"min_event_p_en_bin": 100, | ||
"energy_dependent_gh_cut": { | ||
"energy_bins": [0.01, 0.1, 1, 10, 100], | ||
"cut": [0.4, 0.45, 0.50, 0.55] | ||
}, | ||
"energy_dependent_theta_cut": { | ||
"energy_bins": [0.01, 0.1, 1, 10, 100], | ||
"cut": [0.37, 0.35, 0.3, 0.25] | ||
}, | ||
"energy_dependent_alpha_cut": { | ||
"energy_bins": [0.01, 0.1, 1, 10, 100], | ||
"cut": [4, 4.5, 5, 5.5] | ||
}, | ||
"allowed_tels": [1] | ||
}, | ||
"DataBinning": { | ||
"true_energy_min": 0.005, | ||
"true_energy_max": 500, | ||
"true_energy_n_bins": 25, | ||
"scale_true_energy": 1.0, | ||
"reco_energy_min": 0.005, | ||
"reco_energy_max": 500, | ||
"reco_energy_n_bins": 25, | ||
"energy_migration_min": 0.2, | ||
"energy_migration_max": 5, | ||
"energy_migration_n_bins": 30, | ||
"fov_offset_min": 0.1, | ||
"fov_offset_max": 1.1, | ||
"fov_offset_n_edges": 9, | ||
"bkg_fov_offset_min": 0, | ||
"bkg_fov_offset_max": 10, | ||
"bkg_fov_offset_n_edges": 21, | ||
"source_offset_min": 0, | ||
"source_offset_max": 1, | ||
"source_offset_n_edges": 101 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,5 +1,6 @@ | ||||||
import numpy as np | ||||||
import operator | ||||||
from astropy.table import QTable | ||||||
import astropy.units as u | ||||||
|
||||||
from ctapipe.core import Component | ||||||
|
@@ -10,6 +11,8 @@ | |||||
|
||||||
from pyirf.cuts import calculate_percentile_cut, evaluate_binned_cut | ||||||
|
||||||
from scipy.interpolate import interp1d | ||||||
|
||||||
|
||||||
__all__ = ["EventSelector", "DL3Cuts", "DataBinning"] | ||||||
|
||||||
|
@@ -67,6 +70,11 @@ class DL3Cuts(Component): | |||||
default_value=0.95, | ||||||
).tag(config=True) | ||||||
|
||||||
energy_dependent_gh_cut = Dict( | ||||||
help="Energy dependent selection cuts for gh_score (gammaness)", | ||||||
default_value={}, | ||||||
).tag(config=True) | ||||||
|
||||||
min_gh_cut = Float( | ||||||
help="Minimum gh_score (gammaness) cut in an energy bin", | ||||||
default_value=0.1, | ||||||
|
@@ -105,6 +113,11 @@ class DL3Cuts(Component): | |||||
default_value=0.2, | ||||||
).tag(config=True) | ||||||
|
||||||
energy_dependent_theta_cut = Dict( | ||||||
help="Energy dependent selection cuts (deg) for theta", | ||||||
default_value={}, | ||||||
).tag(config=True) | ||||||
|
||||||
min_alpha_cut = Float( | ||||||
help="Minimum alpha cut (deg) in an energy bin", | ||||||
default_value=1, | ||||||
|
@@ -133,6 +146,11 @@ class DL3Cuts(Component): | |||||
default_value=20, | ||||||
).tag(config=True) | ||||||
|
||||||
energy_dependent_alpha_cut = Dict( | ||||||
help="Energy dependent selection cuts (deg) for alpha", | ||||||
default_value={}, | ||||||
).tag(config=True) | ||||||
|
||||||
allowed_tels = List( | ||||||
help="List of allowed LST telescope ids", | ||||||
trait=Int(), | ||||||
|
@@ -333,6 +351,47 @@ def apply_energy_dependent_alpha_cuts(self, data, alpha_cuts): | |||||
) | ||||||
return data[data["selected_alpha"]] | ||||||
|
||||||
|
||||||
def from_dict(self, parameter, energy_bins, interpolate_kind='nearest'): | ||||||
""" | ||||||
Convert the cut dictionary to a QTable for the requested parameter. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
parameter: string | ||||||
'gh', 'theta' or 'alpha' | ||||||
energy_bins: `astropy.units.quantity.Quantity` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe explicitly |
||||||
energy bins used for the IRFs | ||||||
interpolate_kind: string | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd use interpolation instead of interpolate here |
||||||
Interpolation strategy for `scipy.interpolate.interp1d` | ||||||
|
||||||
Returns | ||||||
------- | ||||||
cut_table: QTable | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
Energy dependent cuts for the requested parameter. | ||||||
|
||||||
""" | ||||||
cut_table = QTable() | ||||||
|
||||||
cuts_dict = {"gh": self.energy_dependent_gh_cut, | ||||||
"theta": self.energy_dependent_theta_cut, | ||||||
"alpha":self.energy_dependent_alpha_cut}[parameter] | ||||||
|
||||||
unit = {"gh": 1, | ||||||
"theta": u.deg, | ||||||
"alpha": u.deg}[parameter] | ||||||
|
||||||
input_ebins_center = (cuts_dict["energy_bins"][:-1]* u.TeV + cuts_dict["energy_bins"][1:] * u.TeV) * 0.5 | ||||||
|
||||||
cut_table["low"] =energy_bins[:-1] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
cut_table["high"] = energy_bins[1:] | ||||||
cut_table["center"] = 0.5 * (cut_table["low"] + cut_table["high"]) | ||||||
f_cut=interp1d(input_ebins_center, cuts_dict["cut"], kind=interpolate_kind, bounds_error=False, | ||||||
fill_value=(cuts_dict["cut"][0], cuts_dict["cut"][-1]), assume_sorted=True) | ||||||
cut_table["cut"] = f_cut(cut_table["center"]) * unit | ||||||
|
||||||
return cut_table | ||||||
|
||||||
def allowed_tels_filter(self, data): | ||||||
""" | ||||||
Applying a filter on telescopes used for observation. | ||||||
|
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 also add that the cut values are interpolated along the IRF energy binning.