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

Add a display module to save images and video of events #726

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

juanjq
Copy link
Collaborator

@juanjq juanjq commented Jul 29, 2021

A module (event_displayer.py) to filter events, and calibrate and save images and video of the events. There is also a notebook (example_event_displayer.ipynb) with an explanation and examples of how it works.

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@codecov
Copy link

codecov bot commented Jul 29, 2021

Codecov Report

Merging #726 (f5f614a) into master (7b967de) will increase coverage by 0.13%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master     #726      +/-   ##
==========================================
+ Coverage   85.75%   85.88%   +0.13%     
==========================================
  Files          78       78              
  Lines        6619     6645      +26     
==========================================
+ Hits         5676     5707      +31     
+ Misses        943      938       -5     
Impacted Files Coverage Δ
lstchain/tests/test_lstchain.py 97.00% <0.00%> (+0.03%) ⬆️
lstchain/reco/dl1_to_dl2.py 76.96% <0.00%> (+3.44%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7b967de...f5f614a. Read the comment docs.

@maxnoe
Copy link
Member

maxnoe commented Jul 29, 2021

Hi,

Is this the code to create the videos send around by @moralejo? If yes, great job!

Looking at the code, I think this needs a lot of cleanup though, to be useful for inclusion in lstchain.

To be included in the library for example means that we cannot just change the script to change input values. We need to use the configuration system for this, and for example give input / output files on the command line or as configuration.

Also, matplotlib can be more efficient and directly store videos, when you use the FuncAnimation class.

Here is a script I wrote a while ago for creating a video of a single event using the ctapipe configuration system (a Tool):

from ctapipe.visualization import CameraDisplay
from ctapipe.coordinates import TelescopeFrame
from ctapipe.io import EventSource
from ctapipe.calib import CameraCalibrator
from ctapipe.core import Tool
from ctapipe.core.traits import Float, Path, Int

import matplotlib.pyplot as plt
import astropy.units as u
import numpy as np
from matplotlib.animation import FuncAnimation
from tqdm import tqdm


class ShowerAnimation(Tool):
    tel_id = Int(default_value=1, help="Telescope to show").tag(config=True)
    output = Path(help="Output file").tag(config=True)
    fps = Float(default_value=10, help="FPS for the final video").tag(config=True)


    aliases = {
        ('i', 'input'): 'EventSource.input_url',
        ('o', 'output'): 'ShowerAnimation.output',
    }

    def setup(self):
        self.source = EventSource(
            parent=self,
            allowed_tels={self.tel_id, }
        )
        self.subarray = self.source.subarray
        self.cam = self.subarray.tel[self.tel_id].camera.geometry
        # self.calib = CameraCalibrator(self.subarray)


        self.event = next(iter(self.source))
        self.r1 = self.event.r1.tel[self.tel_id].waveform

        self.frames = self.r1.shape[1]

        # figsize / dpi will make FullHD video
        self.fig = plt.figure(figsize=(19.2, 10.8), dpi=100)
        self.ax = self.fig.add_axes([0, 0, 1, 1])
        self.ax.set_axis_off()

        self.disp = CameraDisplay(self.cam, cmap='inferno')
        self.disp.add_colorbar()
        self.progress = tqdm(total=self.frames)


    def init_ani(self):
        self.disp.image = self.r1[:, 0]
        self.disp.set_limits_minmax(self.r1.min(), self.r1.max())
        return self.disp.pixels,

    def update_ani(self, frame):
        self.progress.update(1)
        self.disp.image = self.r1[:, frame]
        return self.disp.pixels,

    def start(self):

        ani = FuncAnimation(
            fig=self.fig,
            func=self.update_ani,
            init_func=self.init_ani,
            frames=self.frames,
            interval=1000 / self.fps,
        )
        ani.save(self.output, fps=self.fps, dpi=100)
        # plt.show()

if __name__ == '__main__':
    ShowerAnimation().run()

You can find more about how the config system and the tools work here:
https://cta-observatory.github.io/ctapipe/api/ctapipe.core.Component.html#ctapipe.core.Component
https://cta-observatory.github.io/ctapipe/api/ctapipe.core.Tool.html#ctapipe.core.Tool
https://cta-observatory.github.io/ctapipe/examples/Tools.html

@moralejo
Copy link
Collaborator

Thanks for the feedback @maxnoe. Certainly the code can be simplified and improved.
About the input files, @juanjq , I thought it would be possible to change them in the notebook - indeed changing them in the .py file is not the right way. But for using this from a notebook, I do not think we need a configuration file, etc.

About matplotlib's FuncAnimation, @maxnoe what do you mean? The class is being used already, right?

@moralejo moralejo marked this pull request as draft July 29, 2021 14:14
@maxnoe
Copy link
Member

maxnoe commented Jul 29, 2021

About matplotlib's FuncAnimation, @maxnoe what do you mean? The class is being used already, right?

Sorry, didn't see it. I ony saw the different savefig call and assumed the frames were stored as images.

@juanjq
Copy link
Collaborator Author

juanjq commented Jul 30, 2021

Hi @moralejo , @maxnoe, thanks for the suggestions.
After talking about it this morning with @moralejo , I decided to change the input files for the data to the notebook. Now for using the code you only have to change this directories in the notebook, i supose that this could be done in a more general way, but it works.

Also if is there something at the code to be optimised always it could be changed, the parts at the code are separated and commented.

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