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

Irf maker and cut optimiser #2473

Draft
wants to merge 136 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
136 commits
Select commit Hold shift + click to select a range
5c09d67
First kludge of protopipe irf code as a ctapipe tool
Tobychev Apr 18, 2023
218c9de
Fixed names so the tool can install properly
Tobychev Apr 19, 2023
582ae33
Fixing two small comments from Karl
Tobychev Apr 25, 2023
c18f811
Various small fixes
Tobychev May 3, 2023
bd5efb0
Big refactor to use components as intended
Tobychev May 3, 2023
95c6fe1
Got it all to run
Tobychev May 4, 2023
11f3606
Formatting fixes
Tobychev May 4, 2023
da86aa1
Adjusting defaults to make only one bin in offset?
Tobychev May 4, 2023
e961a21
Moved preselection to start()
Tobychev May 10, 2023
c69337b
Use only one true energy axis
Tobychev May 10, 2023
c33746c
Use only one true energy axis
Tobychev May 10, 2023
d8b3795
Use only one true energy axis
Tobychev May 10, 2023
beabdf0
Refactoring to group things in the same manner
Tobychev May 10, 2023
4e53109
Split preselct into remaning and quality selecting, made EventPreProc…
Tobychev May 12, 2023
723fb26
Fixed serveral problems
Aug 23, 2023
fef7468
Fixed unit issue
Aug 23, 2023
8ab46bd
Updated some defaults
Tobychev Aug 23, 2023
f794b3c
Updated some comments to avoid problems with the doctest
Tobychev Aug 28, 2023
b4b65a1
Add changelog
Tobychev Aug 28, 2023
8edd9dc
Fixed small bug, trying to pass doctests
Tobychev Aug 28, 2023
723433b
Refactored after feedback
Tobychev Sep 5, 2023
e3349f3
Refactored after feedback
Tobychev Sep 5, 2023
b075e73
Refactored after feedback
Tobychev Sep 5, 2023
a4e36ea
Made spectra into enums
Tobychev Sep 5, 2023
2a89265
Added specific configuration of the optimisation grid to the cut opti…
Tobychev Sep 7, 2023
c02eeed
Refactored based on feedback: new tests that simulations stay consist…
Tobychev Sep 8, 2023
c338dc0
Refactored based on feedback: cleaner test
Tobychev Sep 8, 2023
e78e206
Various changes to match reference script.
Tobychev Sep 11, 2023
d850b2e
Reworked how initial theta cuts are calculated, changed some logging …
Tobychev Sep 19, 2023
1dd9738
Update conf.py
Tobychev Sep 20, 2023
de62326
Moved PSF related quantities into its own component
Tobychev Sep 26, 2023
19fddfa
Renamed PSF component to ThetaCutsCalculator, other small refactors
Tobychev Sep 26, 2023
393327e
Update to support newest pyirf version
Tobychev Oct 5, 2023
7218b97
Fix logging error
Tobychev Oct 5, 2023
a96abf7
Use consistent offset binning
Tobychev Oct 18, 2023
410de22
Add theta cut to the background, change logging statments
Tobychev Oct 23, 2023
7e71775
Partial refactoring into optimising and calculating parts
Tobychev Nov 16, 2023
8729e1f
Mayor refactor complete, still not running properly
Tobychev Nov 23, 2023
cab78e9
Various changes to get the code to run end to end
Tobychev Nov 25, 2023
21cd5d1
Pretty large refactoring around how results are saved, cleaned out so…
Tobychev Dec 1, 2023
df5ba51
Further refactoring to decouple things now that there are two tools
Tobychev Dec 5, 2023
5f0e371
Added background and benchmarking option to the make_irf tool
Tobychev Dec 5, 2023
06e0e2d
removed some dead code that had been left behind by mistake
Tobychev Dec 7, 2023
c19a6be
Minor fixes
LukasBeiske Dec 7, 2023
cce0285
Ensure users requested binning is honoured
Tobychev Dec 8, 2023
04f2054
Fixed typo in EXTNAME of energy dispersion
Tobychev Dec 12, 2023
9b53fe9
Add several convenience functions for plotting irfs
Tobychev Dec 12, 2023
d7ae783
Added function to draw 2d hist from a irf table
Tobychev Dec 12, 2023
b1c840e
Use integar indices for fov bounds; fix write out of benchmark hdus
LukasBeiske Dec 19, 2023
a65329d
Remove redundant overwrite flag
LukasBeiske Dec 19, 2023
95cedce
Add some aliases and flags; fix logging bug
LukasBeiske Dec 19, 2023
fd07242
Rename some files and classes
LukasBeiske Dec 19, 2023
fa17d36
Make EventPreProcessor a subcomponent of EventsLoader
LukasBeiske Dec 19, 2023
23d1750
Use reco energy for rad_max table
LukasBeiske Dec 20, 2023
09a67d6
Use n_bins everywhere instead of n_edges
LukasBeiske Jan 12, 2024
e3a64b9
Add reco bins to logging; remove unused bins
LukasBeiske Jan 12, 2024
31f428d
Fix EventPreProcessor configurability
LukasBeiske Jan 13, 2024
90b13d8
Make ThetaCutsCalculator configurable
LukasBeiske Jan 13, 2024
80248d4
Fix help for n_bins config options
LukasBeiske Jan 15, 2024
b74d0c5
Added helper function for plotting just bin-wise statistics of IRF ta…
Tobychev Jan 10, 2024
8c416f1
Added energy binning directly to the PsfIrf class
Tobychev Jan 15, 2024
4601f59
Created a Background2D and Background3D IRF classes
Tobychev Jan 15, 2024
df6e101
Add option for point-like IRF; support diffuse and point-like gammas
LukasBeiske Jan 15, 2024
f55b0c6
Update to consistently use number of bins
Tobychev Jan 16, 2024
51fca72
Added calculation of fov_lat/lon and explicit column descriptions
Tobychev Jan 16, 2024
61fcab0
Added a bit of logging
Tobychev Jan 16, 2024
2d00341
Remove unnecessary conversions
Tobychev Jan 16, 2024
e95b9b1
Moved stuff to match src/ organisatoin
Tobychev Feb 6, 2024
ad88ebe
Fix extra dimension in effective area per offset, adapt to new loader…
Tobychev Feb 25, 2024
e8997a9
Fixed bug where background only used gh-cuts
Tobychev Feb 29, 2024
e87d016
Renamed some options for clarity
Tobychev Mar 5, 2024
9126b6a
Clarified arguments for full-enclosure irfs
Tobychev Apr 10, 2024
d66a91d
Sort and remove duplicates in sphinx nitpicks
LukasBeiske Apr 29, 2024
418d720
Use AstroQuantity trait for observation time
LukasBeiske Apr 29, 2024
65a46ab
Add definition of selectable spectra to irf.select
LukasBeiske Apr 29, 2024
b29636d
Force same clf for computation and application of g/h cuts; warn if o…
LukasBeiske Apr 29, 2024
8d984ca
Use full-enclosure flag for cut optimization tool
LukasBeiske Apr 30, 2024
927ff8c
Remove theta cut re-calculation from irf-tool; move ThetaCutsCalculat…
LukasBeiske May 2, 2024
727b721
Make saving a theta cut optional in cut-opt tool and if saved, also s…
LukasBeiske May 2, 2024
c4ffdf8
Remove redundant bin range check
LukasBeiske May 2, 2024
282070d
Apply event selection per particle type
LukasBeiske May 2, 2024
061424b
More AstroQuantity
LukasBeiske May 2, 2024
1b9c767
Rework irf classes
LukasBeiske May 3, 2024
13daa9a
Make irf parameterizations configurable
LukasBeiske May 6, 2024
1d1e194
Move spectra definition to separate file
LukasBeiske May 6, 2024
90e833c
Revert change of edisp extname
LukasBeiske May 6, 2024
eef9165
Also calculate aeff for protons and electrons
LukasBeiske May 6, 2024
fc9a888
Update cut optimization components and make cut opt algorithm configu…
LukasBeiske May 7, 2024
9bd327a
Clearer class names
LukasBeiske May 7, 2024
8f5cbd8
Remove FoVOffsetBinning; save singular quantities in ResultValidRange
LukasBeiske May 10, 2024
892fb06
No cut on background events based on its true origin position
LukasBeiske May 10, 2024
6eac846
Split out input handling code to separate helper to keep logic of ini…
Tobychev May 13, 2024
448cb55
Fixed typo
Tobychev May 13, 2024
619e3fe
Set min pyirf version to handle astropy 6.0
Tobychev May 14, 2024
2be3d7d
Create a minimal changelog
Tobychev May 14, 2024
96f1cdc
Use classes_with_traits() in tools
LukasBeiske May 14, 2024
5ef1577
cleaning up changelogs
Tobychev May 14, 2024
a28eca7
Added messages explaining which bin range was failing to pass the check
Tobychev May 14, 2024
fd5f6e6
Respect bounds over n_bins_per_decade for energy binning
LukasBeiske May 14, 2024
283a7d5
Made range check optionally only emit warning, made output a bit more…
Tobychev May 14, 2024
bd0d584
Added tracking of where range check came from, made check failure opt…
Tobychev May 14, 2024
93eddef
Discared Lukas changes in error
Tobychev May 14, 2024
a7d30fb
Fixed some code quality issues from sonar
Tobychev May 15, 2024
2d4c950
Fixed typo
Tobychev May 15, 2024
f809ca0
Fixed problems where PSF was not always being generate
Tobychev May 15, 2024
d8771e7
Added optional colorbar plotting to plot_hist2d, additional small fixes
Tobychev May 15, 2024
6a98c35
Move benchmarks into dedicated Components; remove OutputEnergyBinning
LukasBeiske May 16, 2024
0175212
Add type hints to EventsLoader and EventPreProcessor
LukasBeiske May 16, 2024
32c9fbe
Add fov binning for benchmarks
LukasBeiske May 17, 2024
576b887
Only compute psf for full enclosure irf
LukasBeiske Jun 4, 2024
8ad2181
Allow user renaming of cols and check for needed cols after
LukasBeiske Jun 6, 2024
85a0dbc
Add tests for event loading and selection code; minor bugfix
LukasBeiske Jun 6, 2024
befa92b
Shorten bins in range checks a bit
LukasBeiske Jun 7, 2024
58a8f13
Fix number of bin edges in make_bins_per_decade
LukasBeiske Jun 14, 2024
adabf0d
parent=None as default for all components
LukasBeiske Jun 14, 2024
594073f
Add tests for binning
LukasBeiske Jun 14, 2024
0b796cd
Fix caplog binning test
LukasBeiske Jun 14, 2024
bd24bcd
Do not use caplog in test, due to problems with pytest-xdist
LukasBeiske Jun 14, 2024
72c827e
Do not expose base classes
LukasBeiske Jun 14, 2024
1e0407c
Add missing docstring
LukasBeiske Jun 14, 2024
8d8b9fb
Fix imports in binning tests
LukasBeiske Jun 14, 2024
70f4575
Remove wrong bin-in-range checks; fix valid_fov_offset
LukasBeiske Jul 18, 2024
dd97404
Only compute event weights, if a sensitivity is computed
LukasBeiske Jul 18, 2024
10fd643
Make proton and electron files optional, if PercentileCuts is used
LukasBeiske Jul 19, 2024
696f8f5
Move pytest fixtures to conftest.py
LukasBeiske Jul 19, 2024
15df024
Some tests for cut optimization
LukasBeiske Jul 19, 2024
570da7b
Fixed hardcoded nonsensical offset bins for RAD_MAX
Tobychev Jul 19, 2024
2776af5
Add test to ensure BackgroundRate2dMaker stays working once current r…
Tobychev Jul 23, 2024
ff80aa1
Fixed broken background generation
Tobychev Jul 23, 2024
0fa4477
Rework event weight calculation
LukasBeiske Jul 24, 2024
555655d
Fix background2D test
LukasBeiske Aug 14, 2024
0d7a114
More tests for optimization components
LukasBeiske Aug 14, 2024
e32144a
Iterate over cut optimizers in optimize tests
LukasBeiske Aug 16, 2024
df47f71
Add more tests for irf makers
LukasBeiske Sep 2, 2024
99e21cb
Small refactoring of irf tests
LukasBeiske Sep 3, 2024
9da6aeb
Add tests for benchmarks; fix axis order in benchmark output
LukasBeiske Sep 3, 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
3 changes: 0 additions & 3 deletions docs/changes/2411.features.rst

This file was deleted.

3 changes: 3 additions & 0 deletions docs/changes/2473.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add a ``ctapipe-make-irf`` tool and a able to produce irfs given a cut-selection file and gamma, proton, and electron DL2 input files.
Copy link
Member

Choose a reason for hiding this comment

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

I think we should have a bit more extensive changelog here. What is currently supported? How is the intended use? It's a big step.


Add a ``ctapipe-optimize-event-selection`` tool to produce cut-selection files.
30 changes: 15 additions & 15 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def setup(app):
("py:class", "t.Type"),
("py:class", "t.List"),
("py:class", "t.Tuple"),
("py:class", "t.Sequence"),
("py:class", "Config"),
("py:class", "traitlets.config.configurable.Configurable"),
("py:class", "traitlets.traitlets.HasTraits"),
Expand All @@ -132,35 +133,34 @@ def setup(app):
("py:class", "traitlets.config.application.Application"),
("py:class", "traitlets.utils.sentinel.Sentinel"),
("py:class", "traitlets.traitlets.ObserveHandler"),
("py:class", "traitlets.traitlets.T"),
("py:class", "traitlets.traitlets.G"),
("py:class", "Sentinel"),
("py:class", "ObserveHandler"),
("py:class", "dict[K, V]"),
("py:class", "G"),
("py:class", "K"),
("py:class", "V"),
("py:class", "t.Sequence"),
("py:class", "StrDict"),
("py:class", "ClassesType"),
("py:class", "traitlets.traitlets.G"),
("py:class", "re.Pattern"),
("py:class", "re.Pattern[t.Any]"),
("py:class", "astropy.coordinates.baseframe.BaseCoordinateFrame"),
("py:class", "astropy.table.table.Table"),
("py:class", "eventio.simtel.simtelfile.SimTelFile"),
("py:class", "ctapipe.compat.StrEnum"),
("py:class", "ctapipe.compat.StrEnum"),
("py:obj", "traitlets.traitlets.T"),
("py:obj", "traitlets.traitlets.G"),
("py:obj", "traitlets.traitlets.S"),
("py:obj", "traitlets.traitlets.T"),
("py:class", "traitlets.traitlets.T"),
("py:class", "re.Pattern[t.Any]"),
("py:class", "re.Pattern"),
("py:class", "Sentinel"),
("py:class", "ObserveHandler"),
("py:obj", "traitlets.config.boolean_flag"),
("py:obj", "traitlets.TraitError"),
("py:obj", "-v"), # fix for wrong syntax in a traitlets docstring
("py:obj", "cls"),
("py:obj", "name"),
("py:meth", "MetaHasDescriptors.__init__"),
("py:meth", "HasTraits.__new__"),
("py:meth", "BaseDescriptor.instance_init"),
("py:obj", "cls"),
("py:obj", "name"),
("py:class", "astropy.coordinates.baseframe.BaseCoordinateFrame"),
("py:class", "astropy.table.table.Table"),
("py:class", "eventio.simtel.simtelfile.SimTelFile"),
("py:class", "ctapipe.compat.StrEnum"),
("py:class", "ctapipe.compat.StrEnum"),
]

# Sphinx gallery config
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dependencies:
- pypandoc
- pre-commit
- psutil
- pyirf
- pytables
- pytest
- pytest-cov
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dependencies = [
"numba >=0.56",
"numpy ~=1.16",
"psutil",
"pyirf >0.10.1",
Copy link
Member

Choose a reason for hiding this comment

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

I think we should require an exact or at least a "compatible" version of pyirf.

This should probably be pyirf ~=0.11.0 now

"pyyaml >=5.1",
"requests",
"scikit-learn !=1.4.0", # 1.4.0 breaks with astropy tables, before and after works
Expand Down Expand Up @@ -96,6 +97,8 @@ ctapipe-dump-instrument = "ctapipe.tools.dump_instrument:main"
ctapipe-display-dl1 = "ctapipe.tools.display_dl1:main"
ctapipe-process = "ctapipe.tools.process:main"
ctapipe-merge = "ctapipe.tools.merge:main"
ctapipe-optimize-event-selection = "ctapipe.tools.optimize_event_selection:main"
ctapipe-make-irf = "ctapipe.tools.make_irf:main"
ctapipe-fileinfo = "ctapipe.tools.fileinfo:main"
ctapipe-quickstart = "ctapipe.tools.quickstart:main"
ctapipe-train-energy-regressor = "ctapipe.tools.train_energy_regressor:main"
Expand Down
108 changes: 107 additions & 1 deletion src/ctapipe/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
common pytest fixtures for tests in ctapipe
"""

import shutil
from copy import deepcopy

Expand All @@ -9,7 +10,7 @@
import pytest
import tables
from astropy.coordinates import EarthLocation
from astropy.table import Table
from astropy.table import QTable, Table, vstack
from pytest_astropy_header.display import PYTEST_HEADER_MODULES

from ctapipe.core import run_tool
Expand Down Expand Up @@ -684,3 +685,108 @@ def dl1_mon_pointing_file(dl1_file, dl1_tmp_path):
f.remove_node("/configuration/telescope/pointing", recursive=True)

return path


@pytest.fixture(scope="session")
def gamma_diffuse_full_reco_file(
gamma_train_clf,
particle_classifier_path,
model_tmp_path,
):
"""
Energy reconstruction and geometric origin reconstruction have already been done.
"""
from ctapipe.tools.apply_models import ApplyModels

output_path = model_tmp_path / "gamma_diffuse_full_reco.dl2.h5"
run_tool(
ApplyModels(),
argv=[
f"--input={gamma_train_clf}",
f"--output={output_path}",
f"--reconstructor={particle_classifier_path}",
"--no-dl1-parameters",
"--StereoMeanCombiner.weights=konrad",
],
raises=True,
)
return output_path


@pytest.fixture(scope="session")
def proton_full_reco_file(
proton_train_clf,
particle_classifier_path,
model_tmp_path,
):
"""
Energy reconstruction and geometric origin reconstruction have already been done.
"""
from ctapipe.tools.apply_models import ApplyModels

output_path = model_tmp_path / "proton_full_reco.dl2.h5"
run_tool(
ApplyModels(),
argv=[
f"--input={proton_train_clf}",
f"--output={output_path}",
f"--reconstructor={particle_classifier_path}",
"--no-dl1-parameters",
"--StereoMeanCombiner.weights=konrad",
],
raises=True,
)
return output_path


@pytest.fixture(scope="session")
def irf_events_loader_test_config():
from traitlets.config import Config

return Config(
{
"EventPreProcessor": {
"energy_reconstructor": "ExtraTreesRegressor",
"geometry_reconstructor": "HillasReconstructor",
"gammaness_classifier": "ExtraTreesClassifier",
"quality_criteria": [
(
"multiplicity 4",
"np.count_nonzero(tels_with_trigger,axis=1) >= 4",
Copy link
Member

Choose a reason for hiding this comment

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

this is "trigger multiplicity". I think for the IRFs it makes more sense to look at "reconstruction multiplicity", i.e. HillasReconstructor_telescopes.

Not really important for the test config though.

),
("valid classifier", "ExtraTreesClassifier_is_valid"),
("valid geom reco", "HillasReconstructor_is_valid"),
("valid energy reco", "ExtraTreesRegressor_is_valid"),
],
}
}
)


@pytest.fixture(scope="session")
def irf_events_table():
from ctapipe.irf import EventPreProcessor

N1 = 1000
N2 = 100
N = N1 + N2
epp = EventPreProcessor()
tab = epp.make_empty_table()
# Add fake weight column
tab.add_column((), name="weight")
units = {c: tab[c].unit for c in tab.columns}

empty = np.zeros((len(tab.columns), N)) * np.nan
e_tab = QTable(data=empty.T, names=tab.colnames, units=units)
# Setting values following pyirf test in pyirf/irf/tests/test_background.py
e_tab["reco_energy"] = np.append(np.full(N1, 1), np.full(N2, 2)) * u.TeV
e_tab["true_energy"] = np.append(np.full(N1, 0.9), np.full(N2, 2.1)) * u.TeV
e_tab["reco_source_fov_offset"] = (
np.append(np.full(N1, 0.1), np.full(N2, 0.05)) * u.deg
)
e_tab["true_source_fov_offset"] = (
np.append(np.full(N1, 0.11), np.full(N2, 0.04)) * u.deg
)

ev = vstack([e_tab, tab], join_type="exact", metadata_conflicts="silent")
return ev
51 changes: 51 additions & 0 deletions src/ctapipe/irf/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Top level module for the irf functionality"""

from .benchmarks import (
AngularResolution2dMaker,
EnergyBiasResolution2dMaker,
Sensitivity2dMaker,
)
from .binning import (
ResultValidRange,
check_bins_in_range,
make_bins_per_decade,
)
from .irfs import (
BackgroundRate2dMaker,
EffectiveArea2dMaker,
EnergyMigration2dMaker,
Psf3dMaker,
)
from .optimize import (
GhPercentileCutCalculator,
OptimizationResult,
OptimizationResultStore,
PercentileCuts,
PointSourceSensitivityOptimizer,
ThetaPercentileCutCalculator,
)
from .select import EventPreProcessor, EventsLoader
from .spectra import SPECTRA, Spectra

__all__ = [
"AngularResolution2dMaker",
"EnergyBiasResolution2dMaker",
"Sensitivity2dMaker",
"Psf3dMaker",
"BackgroundRate2dMaker",
"EnergyMigration2dMaker",
"EffectiveArea2dMaker",
"ResultValidRange",
"OptimizationResult",
"OptimizationResultStore",
"PointSourceSensitivityOptimizer",
"PercentileCuts",
"EventsLoader",
"EventPreProcessor",
"Spectra",
"GhPercentileCutCalculator",
"ThetaPercentileCutCalculator",
"SPECTRA",
"check_bins_in_range",
"make_bins_per_decade",
]
Loading