Skip to content

Commit

Permalink
Remove wrong bin-in-range checks; fix valid_fov_offset
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasBeiske committed Jul 18, 2024
1 parent db40538 commit 0e879d3
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 55 deletions.
22 changes: 11 additions & 11 deletions src/ctapipe/irf/optimize.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""module containing optimization related functions and classes"""

import operator
from abc import abstractmethod

Expand Down Expand Up @@ -141,7 +142,7 @@ class CutOptimizerBase(Component):
default_value=5,
).tag(config=True)

min_fov_offset = AstroQuantity(
min_bkg_fov_offset = AstroQuantity(
help=(
"Minimum distance from the fov center for background events "
"to be taken into account"
Expand All @@ -150,7 +151,7 @@ class CutOptimizerBase(Component):
physical_type=u.physical.angle,
).tag(config=True)

max_fov_offset = AstroQuantity(
max_bkg_fov_offset = AstroQuantity(
help=(
"Maximum distance from the fov center for background events "
"to be taken into account"
Expand Down Expand Up @@ -342,11 +343,11 @@ def optimize_cuts(
result_saver.set_result(
gh_cuts=gh_cuts,
valid_energy=[self.reco_energy_min, self.reco_energy_max],
valid_offset=[self.min_fov_offset, self.max_fov_offset],
# A single set of cuts is calculated for the whole fov atm
valid_offset=[0 * u.deg, np.inf * u.deg],
clf_prefix=clf_prefix,
theta_cuts=theta_cuts if point_like else None,
)

return result_saver


Expand Down Expand Up @@ -420,18 +421,17 @@ def optimize_cuts(
theta_cuts["low"] = reco_energy_bins[:-1]
theta_cuts["center"] = 0.5 * (reco_energy_bins[:-1] + reco_energy_bins[1:])
theta_cuts["high"] = reco_energy_bins[1:]
theta_cuts["cut"] = self.max_fov_offset
theta_cuts["cut"] = self.max_bkg_fov_offset
self.log.info(
"Optimizing G/H separation cut for best sensitivity "
"with `max_fov_radius` as theta cut."
"with `max_bkg_fov_offset` as theta cut."
)

gh_cut_efficiencies = np.arange(
self.gh_cut_efficiency_step,
self.max_gh_cut_efficiency + self.gh_cut_efficiency_step / 2,
self.gh_cut_efficiency_step,
)

opt_sens, gh_cuts = optimize_gh_cut(
signal,
background,
Expand All @@ -440,8 +440,8 @@ def optimize_cuts(
op=operator.ge,
theta_cuts=theta_cuts,
alpha=alpha,
fov_offset_max=self.max_fov_offset,
fov_offset_min=self.min_fov_offset,
fov_offset_max=self.max_bkg_fov_offset,
fov_offset_min=self.min_bkg_fov_offset,
)
valid_energy = self._get_valid_energy_range(opt_sens)

Expand All @@ -463,11 +463,11 @@ def optimize_cuts(
result_saver.set_result(
gh_cuts=gh_cuts,
valid_energy=valid_energy,
valid_offset=[self.min_fov_offset, self.max_fov_offset],
# A single set of cuts is calculated for the whole fov atm
valid_offset=[0 * u.deg, np.inf * u.deg],
clf_prefix=clf_prefix,
theta_cuts=theta_cuts_opt if point_like else None,
)

return result_saver

def _get_valid_energy_range(self, opt_sens):
Expand Down
61 changes: 18 additions & 43 deletions src/ctapipe/tools/make_irf.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class IrfTool(Tool):
).tag(config=True)

range_check_error = Bool(
True,
False,
help="Raise error if asking for IRFs outside range where cut optimisation is valid",
).tag(config=True)

Expand Down Expand Up @@ -219,11 +219,6 @@ def setup(self):
valid_range=self.opt_result.valid_energy,
raise_error=self.range_check_error,
)
check_fov_offset_bins = partial(
check_bins_in_range,
valid_range=self.opt_result.valid_offset,
raise_error=self.range_check_error,
)
self.particles = [
EventsLoader(
parent=self,
Expand Down Expand Up @@ -262,29 +257,16 @@ def setup(self):
check_e_bins(
bins=self.bkg.reco_energy_bins, source="background reco energy"
)
check_fov_offset_bins(
bins=self.bkg.fov_offset_bins, source="background fov offset"
)

self.edisp = EnergyMigrationMakerBase.from_name(
self.edisp_parameterization, parent=self
)
check_e_bins(bins=self.edisp.true_energy_bins, source="Edisp true energy")
check_fov_offset_bins(
bins=self.edisp.fov_offset_bins, source="Edisp fov offset"
)
self.aeff = EffectiveAreaMakerBase.from_name(
self.aeff_parameterization, parent=self
)
check_e_bins(bins=self.aeff.true_energy_bins, source="Aeff true energy")
check_fov_offset_bins(bins=self.aeff.fov_offset_bins, source="Aeff fov offset")

if self.full_enclosure:
self.psf = PsfMakerBase.from_name(self.psf_parameterization, parent=self)
check_e_bins(bins=self.psf.true_energy_bins, source="PSF true energy")
check_fov_offset_bins(
bins=self.psf.fov_offset_bins, source="PSF fov offset"
)

if self.do_benchmarks:
self.b_output = self.output_path.with_name(
Expand All @@ -293,35 +275,20 @@ def setup(self):
self.ang_res = AngularResolutionMakerBase.from_name(
self.ang_res_parameterization, parent=self
)
check_e_bins(
bins=self.ang_res.true_energy_bins
if self.ang_res.use_true_energy
else self.ang_res.reco_energy_bins,
source="Angular resolution energy",
)
check_fov_offset_bins(
bins=self.ang_res.fov_offset_bins,
source="Angular resolution fov offset",
)
if not self.ang_res.use_true_energy:
check_e_bins(
bins=self.ang_res.reco_energy_bins,
source="Angular resolution energy",
)
self.bias_res = EnergyBiasResolutionMakerBase.from_name(
self.energy_bias_res_parameterization, parent=self
)
check_e_bins(
bins=self.bias_res.true_energy_bins,
source="Bias resolution true energy",
)
check_fov_offset_bins(
bins=self.bias_res.fov_offset_bins, source="Bias resolution fov offset"
)
self.sens = SensitivityMakerBase.from_name(
self.sens_parameterization, parent=self
)
check_e_bins(
bins=self.sens.reco_energy_bins, source="Sensitivity reco energy"
)
check_fov_offset_bins(
bins=self.sens.fov_offset_bins, source="Sensitivity fov offset"
)

def calculate_selections(self, reduced_events: dict) -> dict:
"""
Expand Down Expand Up @@ -466,7 +433,7 @@ def _make_benchmark_hdus(self, hdus):
theta_cuts["center"] = 0.5 * (
self.sens.reco_energy_bins[:-1] + self.sens.reco_energy_bins[1:]
)
theta_cuts["cut"] = self.opt_result.valid_offset.max
theta_cuts["cut"] = self.sens.fov_offset_max
else:
theta_cuts = self.opt_result.theta_cuts

Expand Down Expand Up @@ -516,10 +483,18 @@ def start(self):
sel.epp.gammaness_classifier = self.opt_result.gh_cuts.meta["CLFNAME"]

self.log.debug("%s Precuts: %s" % (sel.kind, sel.epp.quality_criteria))
# TODO: This fov range is only used for the event weights for the sensitivity calculation.
# This should only be done if `do_benchmarks == True` and for each fov bin
# for which the sensitivity is calculated.
if self.do_benchmarks:
valid_fov = [self.sens.fov_offset_min, self.sens.fov_offset_max]
else:
valid_fov = [0, 5] * u.deg

evs, cnt, meta = sel.load_preselected_events(
self.chunk_size,
self.obs_time,
self.opt_result.valid_offset,
chunk_size=self.chunk_size,
obs_time=self.obs_time,
valid_fov=valid_fov,
)
reduced_events[sel.kind] = evs
reduced_events[f"{sel.kind}_count"] = cnt
Expand Down
2 changes: 1 addition & 1 deletion src/ctapipe/tools/optimize_event_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def start(self):
evs, cnt, meta = sel.load_preselected_events(
self.chunk_size,
self.obs_time,
[self.optimizer.min_fov_offset, self.optimizer.max_fov_offset],
[self.optimizer.min_bkg_fov_offset, self.optimizer.max_bkg_fov_offset],
)
reduced_events[sel.kind] = evs
reduced_events[f"{sel.kind}_count"] = cnt
Expand Down

0 comments on commit 0e879d3

Please sign in to comment.