Skip to content

Commit 49d836d

Browse files
authored
Merge pull request #2958 from cta-observatory/fix_impact_type
Introduce new `needs_atmosphere_profile` property to reconstructors
2 parents 388937e + b4256ec commit 49d836d

9 files changed

Lines changed: 35 additions & 7 deletions

File tree

docs/changes/2958.maintenance.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Introduce ``needs_atmosphere_profile`` property to ``Reconstructors``.

src/ctapipe/reco/hillas_intersection.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class HillasIntersection(HillasGeometryReconstructor):
100100
).tag(config=True)
101101

102102
property = ReconstructionProperty.GEOMETRY
103+
needs_atmosphere_profile = False
103104

104105
def __init__(self, subarray, atmosphere_profile=None, **kwargs):
105106
"""

src/ctapipe/reco/hillas_reconstructor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class that reconstructs the direction of an atmospheric shower
107107
108108
"""
109109

110+
needs_atmosphere_profile = False
111+
110112
def __init__(
111113
self, subarray: SubarrayDescription, atmosphere_profile=None, **kwargs
112114
):

src/ctapipe/reco/impact.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class ImPACTReconstructor(HillasGeometryReconstructor):
136136
spe = 0.6 # Also hard code single p.e. distribution width
137137

138138
property = ReconstructionProperty.ENERGY | ReconstructionProperty.GEOMETRY
139+
needs_atmosphere_profile = True
139140

140141
def __init__(
141142
self, subarray, atmosphere_profile, dummy_reconstructor=False, **kwargs

src/ctapipe/reco/reconstructor.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ def __init__(self, subarray, atmosphere_profile=None, **kwargs):
8989
self.quality_query = StereoQualityQuery(parent=self)
9090
self.atmosphere_profile = atmosphere_profile
9191

92+
@property
93+
@abstractmethod
94+
def needs_atmosphere_profile(self) -> bool:
95+
"""Whether this reconstructor requires ``atmosphere_profile``."""
96+
9297
@abstractmethod
9398
def __call__(self, event: ArrayEventContainer):
9499
"""

src/ctapipe/reco/shower_processor.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,6 @@ def __init__(
6767
super().__init__(config=config, parent=parent, **kwargs)
6868
self.subarray = subarray
6969
self.atmosphere_profile = atmosphere_profile
70-
if (
71-
atmosphere_profile is None
72-
and "ImPACTReconstrcutor" in self.reconstructor_types
73-
):
74-
raise TypeError(
75-
"Argument 'atmosphere_profile' can not be 'None' if 'ImPACTReconstructor' is in 'reconstructor_types'"
76-
)
7770
self.reconstructors = [
7871
Reconstructor.from_name(
7972
reco_type,
@@ -84,6 +77,14 @@ def __init__(
8477
for reco_type in self.reconstructor_types
8578
]
8679

80+
if atmosphere_profile is None and any(
81+
r.needs_atmosphere_profile for r in self.reconstructors
82+
):
83+
raise TypeError(
84+
"Argument 'atmosphere_profile' can not be 'None' if one of the selected "
85+
"reconstructors requires an atmosphere profile."
86+
)
87+
8788
def __call__(self, event: ArrayEventContainer):
8889
"""
8990
Apply all configured stereo reconstructors to the given event.

src/ctapipe/reco/sklearn.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class SKLearnReconstructor(Reconstructor):
9595
#: Property predicted, overridden in subclass.
9696
property = None
9797

98+
needs_atmosphere_profile = False
99+
98100
prefix = traits.Unicode(
99101
default_value=None,
100102
allow_none=True,
@@ -521,6 +523,8 @@ class DispReconstructor(Reconstructor):
521523

522524
target = "true_disp"
523525

526+
needs_atmosphere_profile = False
527+
524528
prefix = traits.Unicode(
525529
default_value="disp",
526530
allow_none=False,

src/ctapipe/reco/tests/test_shower_processor.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,14 @@ def test_shower_processor_geometry(
107107
assert not isfinite(DL2a.core_y)
108108
assert not DL2a.is_valid
109109
assert not isfinite(DL2a.average_intensity)
110+
111+
112+
def test_shower_processor_requires_atmosphere_profile_for_impact(example_subarray):
113+
pytest.importorskip("iminuit")
114+
115+
with pytest.raises(TypeError):
116+
ShowerProcessor(
117+
subarray=example_subarray,
118+
atmosphere_profile=None,
119+
reconstructor_types=["ImPACTReconstructor"],
120+
)

test_plugin/ctapipe_test_plugin/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ def _generator(self):
9797
class PluginReconstructor(Reconstructor):
9898
"""A plugin Reconstructor"""
9999

100+
needs_atmosphere_profile = False
101+
100102
foo = traits.Bool(
101103
True, help="example traitlet to see that it is included in --help"
102104
).tag(config=True)

0 commit comments

Comments
 (0)