Skip to content

fix(HillasIntersection): use geometry frame focal length for CameraFrame reconstruction - #3054

Open
STSpencer wants to merge 2 commits into
cta-observatory:mainfrom
STSpencer:fix/hillas-intersection-focal-length
Open

fix(HillasIntersection): use geometry frame focal length for CameraFrame reconstruction#3054
STSpencer wants to merge 2 commits into
cta-observatory:mainfrom
STSpencer:fix/hillas-intersection-focal-length

Conversation

@STSpencer

@STSpencer STSpencer commented Jul 9, 2026

Copy link
Copy Markdown
Contributor
image ## Summary

HillasIntersection._predict builds a CameraFrame for coordinate transforms using the telescope's equivalent_focal_length when processing CameraHillasParametersContainer input. However, the camera geometry — and therefore the Hillas parametrisation itself — is defined with the focal length chosen at read time (SimTelEventSource.focal_length_choice, which defaults to FocalLengthKind.EFFECTIVE). The effective and equivalent focal lengths differ by ~4–5% for typical CTA telescopes (e.g. LST: ~29.3 m effective vs 28 m equivalent).

Because the reconstructed angular position is proportional to camera_position / focal_length, using the wrong value introduces a plate-scale error. This error grows with the distance of the image from the camera centre. High-energy showers produce large, off-axis images far from the centre, so they are disproportionately affected — degrading angular resolution exactly at high energies.

The sibling reconstructor HillasReconstructor already handles this correctly by reading camera.geometry.frame.focal_length.

Change

# Before
focal_length = self.subarray.tel[tel_id].optics.equivalent_focal_length

# After
focal_length = self.subarray.tel[tel_id].camera.geometry.frame.focal_length

This reads back the focal length that was actually used when building the camera geometry frame, regardless of which focal_length_choice was configured — making HillasIntersection consistent with HillasReconstructor and with the parametrisation frame.

Notes

  • Only affects reconstruction from CameraHillasParametersContainer (i.e. ImageProcessor.use_telescope_frame=False). The default telescope-frame path is unaffected as it operates directly in angular coordinates.
  • All 62 reco tests pass.
  • ruff format --check and ruff check pass clean on the changed file.
  • SonarQube analysis reports 0 security issues on the changed file; no new code smells are introduced.

…quivalent

When reconstructing from CameraHillasParametersContainer, the focal length
used to build the CameraFrame for coordinate transforms must match the focal
length with which the camera geometry (and thus the Hillas parametrization)
was defined. Previously, HillasIntersection hardcoded
optics.equivalent_focal_length, which diverges from the effective focal
length selected at data read time (SimTelEventSource.focal_length_choice
defaults to FocalLengthKind.EFFECTIVE).

Using the wrong focal length introduces a plate-scale error that grows with
the distance of the image from the camera centre. High-energy showers produce
large, off-axis images far from the centre, so they suffer the largest
directional bias—degrading angular resolution precisely at high energies.

Fix: read camera.geometry.frame.focal_length, consistent with
HillasReconstructor and with the frame used for parametrization.

Refs: cta-observatory#3051
@STSpencer STSpencer self-assigned this Jul 9, 2026
@kosack

kosack commented Jul 22, 2026

Copy link
Copy Markdown
Member

That is definitely a bug! I suspect that is one of the reasons why HillasIntersection never gave as good results as HillasReconstructor. Maybe we should consider just dropping HillasIntersection altogether? Is it worth maintaining two versions of the same algorithms?

Comment thread docs/changes/3054.bugfix.rst
@maxnoe
maxnoe marked this pull request as ready for review August 3, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants