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

Vectorize operations in HillasReconstructor #2036

Merged
merged 11 commits into from Sep 23, 2022
Merged

Vectorize operations in HillasReconstructor #2036

merged 11 commits into from Sep 23, 2022

Conversation

maxnoe
Copy link
Member

@maxnoe maxnoe commented Jul 21, 2022

Timing script:

from ctapipe.io import EventSource
from ctapipe.reco import HillasReconstructor
import numpy as np
from timeit import repeat
from cProfile import Profile



source = EventSource("../data/gamma_20deg_180deg_run3___cta-prod6-paranal-2147m-Paranal-dark.dl1.h5", max_events=200)
events = list(source)

reco = HillasReconstructor(subarray=source.subarray)

code = '''
print("start")
for event in events:
    reco(event)
'''

with Profile() as profile:
    exec(code)

profile.dump_stats("hillas_reco.profile")


n_repeat = 5
number = 1
times = np.array(repeat(code, number=number, repeat=n_repeat, globals=globals()))
times /= number

On master:

11.73 ± 0.31 s

on this branch:

2.25 ± 0.02 s

Units tests are passing, but I will also process a larger DL2 run and check that results are the same.

Most time is not spend in astropy coordinate transforms and project_to_ground.

@codecov
Copy link

codecov bot commented Jul 21, 2022

Codecov Report

Base: 92.49% // Head: 92.49% // Decreases project coverage by -0.00% ⚠️

Coverage data is based on head (cf7f20e) compared to base (4905dc1).
Patch coverage: 94.53% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2036      +/-   ##
==========================================
- Coverage   92.49%   92.49%   -0.01%     
==========================================
  Files         197      197              
  Lines       16246    16276      +30     
==========================================
+ Hits        15027    15054      +27     
- Misses       1219     1222       +3     
Impacted Files Coverage Δ
ctapipe/reco/tests/test_reconstruction_methods.py 100.00% <ø> (ø)
ctapipe/coordinates/nominal_frame.py 89.65% <66.66%> (ø)
ctapipe/reco/hillas_reconstructor.py 95.77% <94.17%> (-2.62%) ⬇️
ctapipe/reco/tests/test_HillasReconstructor.py 99.23% <98.00%> (-0.77%) ⬇️
ctapipe/coordinates/__init__.py 100.00% <100.00%> (ø)
ctapipe/coordinates/ground_frames.py 100.00% <100.00%> (ø)
ctapipe/coordinates/telescope_frame.py 90.00% <100.00%> (+0.34%) ⬆️
ctapipe/instrument/camera/geometry.py 90.47% <0.00%> (+0.56%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@kosack
Copy link
Contributor

kosack commented Jul 22, 2022

as suggested in #1922 perhaps we should also drop the CameraFrame support in HillasReconstructor (either here or in a separate PR) to simplify this code even more and remove a few branch points.

@maxnoe
Copy link
Member Author

maxnoe commented Jul 22, 2022

@kosack If you look at the code, the branching for CameraFrame vs. TelescopeFrame is now very minimal, so I'd say not really a concern here.

I am investigating a few issues with astropy concerning performance and I have identified several spots where astropy can be much improved.

For now, I would keep it in the current version I think, we already get a very noticeable speedup.

@maxnoe maxnoe marked this pull request as ready for review September 21, 2022 08:21
@maxnoe maxnoe added this to the v0.17.0 milestone Sep 21, 2022
Copy link
Contributor

@kosack kosack left a comment

Choose a reason for hiding this comment

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

Looks good!

Before merging, It might be a good idea to do a regression test on a largish number of events to be sure the results have not changed since before the refactoring. (if you have not done that already).

@maxnoe
Copy link
Member Author

maxnoe commented Sep 21, 2022

Will do

Copy link
Contributor

@kosack kosack left a comment

Choose a reason for hiding this comment

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

One minor annoyance that would be nice to fix in this is that the azimuths end up in a strange quadrant (negative). It would be nice for sources with azimuth=180.0 that the reconstructed position is centered there, not at -180.0. It's still correct, but may be confusing when we use that value in a ML algorithm without any transforms.

E.g.: can it return values more like the right plot?
image

@maxnoe
Copy link
Member Author

maxnoe commented Sep 21, 2022

Sure, I'll wrap the angle into [-180, 180)

@kosack
Copy link
Contributor

kosack commented Sep 21, 2022

Astropy.coord seems to wrap to (0,360], not sure which is better (either way the user has to do a wrap transform if you are one of the usual North or South pointings). At least we should make all Reconstructors consistent. I think HillasIntersection returns something in (0,360]. Not sure about ImPACT.

I only noticed this in #2073 when using multiple reconstructors

@maxnoe
Copy link
Member Author

maxnoe commented Sep 21, 2022

Ok, let's go with the astropy default then

@maxnoe
Copy link
Member Author

maxnoe commented Sep 21, 2022

I processed 100 gamma diffuse runs (~25k successfully reconstructed events) using 0.16.0 and this branch.

The results are not exactly identical, but they are very close for almost all events and the angular resolution is the same or even slightly better with the new code:

angular_resolution_vectorize_hillas

kosack
kosack previously approved these changes Sep 23, 2022
Copy link
Contributor

@kosack kosack left a comment

Choose a reason for hiding this comment

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

I guess the small differences are just due to the different order of operations. In any case as the results are generally better, I think it's ok.

@maxnoe
Copy link
Member Author

maxnoe commented Sep 23, 2022

Had to rebase, please re-review @kosack @nbiederbeck @LukasNickel

@LukasNickel
Copy link
Member

AttributeError: 'Quantity' object has no 'deg' member

error in docs

point_tel = point_cam.transform_to(telframe)
self._cam_radius_deg[cam] = point_tel.fov_lon
_cam_radius_deg[cam] = point_tel.fov_lon.to_value(u.deg)
Copy link
Member

Choose a reason for hiding this comment

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

Not directly related to this PR, but is anyone else really disliking this code block and would rather have the cam radius in meter and degree be a property of the camera geometry?

Copy link
Member Author

Choose a reason for hiding this comment

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

We currently have the geometry strictly in one frame and I quite like this...

Copy link
Member Author

Choose a reason for hiding this comment

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

This should rather be replaced by dropping support for doing high-level things in camera frame

self._cam_radius_deg[cam] = point_tel.fov_lon
_cam_radius_deg[cam] = point_tel.fov_lon.to_value(u.deg)

# store for each tel_id to avoid costly hash of camera
Copy link
Member

Choose a reason for hiding this comment

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

For my understanding:
Why not directly assign to self._cam_radius_x above?
I am guessing you save calculations by performing them once per camery type above and only then looping over the actual telescopes down here?

ctapipe/reco/hillas_reconstructor.py Show resolved Hide resolved
@maxnoe
Copy link
Member Author

maxnoe commented Sep 23, 2022

Errors should be fixed now

@maxnoe maxnoe merged commit c8c61a1 into master Sep 23, 2022
@maxnoe maxnoe deleted the hillas_reco_perf branch September 23, 2022 11:14
@maxnoe maxnoe mentioned this pull request Oct 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants