コード例 #1
0
class DumpInstrumentTool(Tool):
    description = Unicode(__doc__)
    name = "ctapipe-dump-instrument"

    infile = Path(exists=True, help="input simtelarray file").tag(config=True)
    format = Enum(
        ["fits", "ecsv", "hdf5"],
        default_value="fits",
        help="Format of output file",
        config=True,
    )

    aliases = Dict(
        dict(infile="DumpInstrumentTool.infile",
             format="DumpInstrumentTool.format"))

    def setup(self):
        with event_source(self.infile) as source:
            self.subarray = source.subarray

    def start(self):
        self.write_camera_geometries()
        self.write_optics_descriptions()
        self.write_subarray_description()

    def finish(self):
        pass

    @staticmethod
    def _get_file_format_info(format_name, table_type, table_name):
        """ returns file extension + dict of required parameters for
        Table.write"""
        if format_name == "fits":
            return "fits.gz", dict()
        elif format_name == "ecsv":
            return "ecsv.txt", dict(format="ascii.ecsv")
        elif format_name == "hdf5":
            return "h5", dict(path="/" + table_type + "/" + table_name)
        else:
            raise NameError("format not supported")

    def write_camera_geometries(self):
        cam_types = get_camera_types(self.subarray)
        self.subarray.info(printer=self.log.info)
        for cam_name in cam_types:
            ext, args = self._get_file_format_info(self.format, "CAMGEOM",
                                                   cam_name)

            self.log.debug(f"writing {cam_name}")
            tel_id = cam_types[cam_name].pop()
            geom = self.subarray.tel[tel_id].camera.geometry
            table = geom.to_table()
            table.meta["SOURCE"] = self.infile
            filename = f"{cam_name}.camgeom.{ext}"

            try:
                table.write(filename, **args)
                Provenance().add_output_file(filename, "dl0.tel.svc.camera")
            except IOError as err:
                self.log.warning(
                    "couldn't write camera definition '%s' because: %s",
                    filename, err)

    def write_optics_descriptions(self):
        sub = self.subarray
        ext, args = self._get_file_format_info(self.format, sub.name, "optics")

        tab = sub.to_table(kind="optics")
        tab.meta["SOURCE"] = self.infile
        filename = f"{sub.name}.optics.{ext}"
        try:
            tab.write(filename, **args)
            Provenance().add_output_file(filename, "dl0.sub.svc.optics")
        except IOError as err:
            self.log.warning(
                "couldn't write optics description '%s' because: %s", filename,
                err)

    def write_subarray_description(self):
        sub = self.subarray
        ext, args = self._get_file_format_info(self.format, sub.name,
                                               "subarray")
        tab = sub.to_table(kind="subarray")
        tab.meta["SOURCE"] = self.infile
        filename = f"{sub.name}.subarray.{ext}"
        try:
            tab.write(filename, **args)
            Provenance().add_output_file(filename, "dl0.sub.svc.subarray")
        except IOError as err:
            self.log.warning(
                "couldn't write subarray description '%s' because: %s",
                filename, err)
コード例 #2
0
class DumpInstrumentTool(Tool):
    description = Unicode(__doc__)
    name = "ctapipe-dump-instrument"

    infile = Path(exists=True, help="input simtelarray file").tag(config=True)
    format = Enum(
        ["fits", "ecsv", "hdf5"],
        default_value="fits",
        help="Format of output file",
        config=True,
    )

    aliases = Dict(
        dict(input="DumpInstrumentTool.infile",
             format="DumpInstrumentTool.format"))

    def setup(self):
        with EventSource(self.infile) as source:
            self.subarray = source.subarray

    def start(self):
        if self.format == "hdf5":
            self.subarray.to_hdf("subarray.h5")
        else:
            self.write_camera_definitions()
            self.write_optics_descriptions()
            self.write_subarray_description()

    def finish(self):
        pass

    @staticmethod
    def _get_file_format_info(format_name):
        """ returns file extension + dict of required parameters for
        Table.write"""
        if format_name == "fits":
            return "fits.gz", dict()
        elif format_name == "ecsv":
            return "ecsv", dict()
        else:
            raise NameError(f"format {format_name} not supported")

    def write_camera_definitions(self):
        """ writes out camgeom and camreadout files for each camera"""
        cam_types = get_camera_types(self.subarray)
        self.subarray.info(printer=self.log.info)
        for cam_name in cam_types:
            ext, args = self._get_file_format_info(self.format)

            self.log.debug(f"writing {cam_name}")
            tel_id = cam_types[cam_name].pop()
            geom = self.subarray.tel[tel_id].camera.geometry
            readout = self.subarray.tel[tel_id].camera.readout

            geom_table = geom.to_table()
            geom_table.meta["SOURCE"] = str(self.infile)
            geom_filename = f"{cam_name}.camgeom.{ext}"

            readout_table = readout.to_table()
            readout_table.meta["SOURCE"] = str(self.infile)
            readout_filename = f"{cam_name}.camreadout.{ext}"

            try:
                geom_table.write(geom_filename, **args)
                readout_table.write(readout_filename, **args)
                Provenance().add_output_file(geom_filename, "CameraGeometry")
                Provenance().add_output_file(readout_filename, "CameraReadout")
            except IOError as err:
                self.log.warning(
                    "couldn't write camera definition because: %s", err)

    def write_optics_descriptions(self):
        """ writes out optics files for each telescope type"""
        sub = self.subarray
        ext, args = self._get_file_format_info(self.format)

        tab = sub.to_table(kind="optics")
        tab.meta["SOURCE"] = str(self.infile)
        filename = f"{sub.name}.optics.{ext}"
        try:
            tab.write(filename, **args)
            Provenance().add_output_file(filename, "OpticsDescription")
        except IOError as err:
            self.log.warning(
                "couldn't write optics description '%s' because: %s", filename,
                err)

    def write_subarray_description(self):
        sub = self.subarray
        ext, args = self._get_file_format_info(self.format)
        tab = sub.to_table(kind="subarray")
        tab.meta["SOURCE"] = str(self.infile)
        filename = f"{sub.name}.subarray.{ext}"
        try:
            tab.write(filename, **args)
            Provenance().add_output_file(filename, "SubarrayDescription")
        except IOError as err:
            self.log.warning(
                "couldn't write subarray description '%s' because: %s",
                filename, err)
コード例 #3
0
class DumpTriggersTool(Tool):
    description = Unicode(__doc__)

    # =============================================
    # configuration parameters:
    # =============================================

    infile = Unicode(help='input simtelarray file').tag(config=True)

    outfile = Unicode('triggers.fits',
                      help='output filename (*.fits, *.h5)').tag(config=True)

    overwrite = Bool(False,
                     help="overwrite existing output file").tag(config=True)

    # =============================================
    # map low-level options to high-level command-line options
    # =============================================

    aliases = Dict({
        'infile': 'DumpTriggersTool.infile',
        'outfile': 'DumpTriggersTool.outfile'
    })

    flags = Dict({
        'overwrite': ({
            'DumpTriggersTool': {
                'overwrite': True
            }
        }, 'Enable overwriting of output file')
    })

    examples = ('ctapipe-dump-triggers --infile gamma.simtel.gz '
                '--outfile trig.fits --overwrite'
                '\n\n'
                'If you want to see more output, use --log_level=DEBUG')

    # =============================================
    # The methods of the Tool (initialize, start, finish):
    # =============================================

    def add_event_to_table(self, event):
        """
        add the current hessio event to a row in the `self.events` table
        """
        gpstime = event.trig.gps_time

        if self._prev_gpstime is None:
            self._prev_gpstime = gpstime

        if self._current_starttime is None:
            self._current_starttime = gpstime

        relative_time = gpstime - self._current_starttime
        delta_t = gpstime - self._prev_gpstime
        self._prev_gpstime = gpstime

        # build the trigger pattern as a fixed-length array
        # (better for storage in FITS format)
        #trigtels = event.get_telescope_with_data_list()
        trigtels = event.dl0.tels_with_data
        self._current_trigpattern[:] = 0  # zero the trigger pattern
        self._current_trigpattern[list(trigtels)] = 1  # set the triggered tels
        # to 1

        # insert the row into the table
        self.events.add_row(
            (event.dl0.event_id, relative_time.sec, delta_t.sec, len(trigtels),
             self._current_trigpattern))

    def setup(self):
        """ setup function, called before `start()` """

        if self.infile == '':
            raise ValueError("No 'infile' parameter was specified. "
                             "Use --help for info")

        self.events = Table(
            names=['EVENT_ID', 'T_REL', 'DELTA_T', 'N_TRIG', 'TRIGGERED_TELS'],
            dtype=[np.int64, np.float64, np.float64, np.int32, np.uint8])

        self.events['TRIGGERED_TELS'].shape = (0, MAX_TELS)
        self.events['T_REL'].unit = u.s
        self.events['T_REL'].description = 'Time relative to first event'
        self.events['DELTA_T'].unit = u.s
        self.events.meta['INPUT'] = self.infile

        self._current_trigpattern = np.zeros(MAX_TELS)
        self._current_starttime = None
        self._prev_gpstime = None

    def start(self):
        """ main event loop """
        source = hessio.hessio_event_source(self.infile)

        for event in source:
            self.add_event_to_table(event)

    def finish(self):
        """
        finish up and write out results (called automatically after
        `start()`)
        """
        # write out the final table
        if self.outfile.endswith('fits') or self.outfile.endswith('fits.gz'):
            self.events.write(self.outfile, overwrite=self.overwrite)
        elif self.outfile.endswith('h5'):
            self.events.write(self.outfile,
                              path='/events',
                              overwrite=self.overwrite)
        else:
            self.events.write(self.outfile)

        self.log.info("Table written to '{}'".format(self.outfile))
        self.log.info('\n %s', self.events)
コード例 #4
0
class DumpInstrumentTool(Tool):
    description = Unicode(__doc__)
    name = 'ctapipe-dump-instrument'

    infile = Unicode(help='input simtelarray file').tag(config=True)
    format = Enum(['fits', 'ecsv', 'hdf5'],
                  default_value='fits',
                  help='Format of output file',
                  config=True)

    aliases = Dict(
        dict(infile='DumpInstrumentTool.infile',
             format='DumpInstrumentTool.format'))

    def setup(self):
        with event_source(self.infile) as source:
            data = next(iter(
                source))  # get one event, so the instrument table is there

        self.inst = data.inst  # keep a reference to the instrument stuff

    def start(self):
        self.write_camera_geometries()
        self.write_optics_descriptions()
        self.write_subarray_description()

    def finish(self):
        pass

    @staticmethod
    def _get_file_format_info(format_name, table_type, table_name):
        """ returns file extension + dict of required parameters for
        Table.write"""
        if format_name == 'fits':
            return 'fits.gz', dict()
        elif format_name == 'ecsv':
            return 'ecsv.txt', dict(format='ascii.ecsv')
        elif format_name == 'hdf5':
            return 'h5', dict(path="/" + table_type + "/" + table_name)
        else:
            raise NameError("format not supported")

    def write_camera_geometries(self):
        cam_types = get_camera_types(self.inst.subarray)
        self.inst.subarray.info(printer=self.log.info)
        for cam_name in cam_types:
            ext, args = self._get_file_format_info(self.format, 'CAMGEOM',
                                                   cam_name)

            self.log.debug(f"writing {cam_name}")
            tel_id = cam_types[cam_name].pop()
            geom = self.inst.subarray.tel[tel_id].camera.geometry
            table = geom.to_table()
            table.meta['SOURCE'] = self.infile
            filename = f"{cam_name}.camgeom.{ext}"

            try:
                table.write(filename, **args)
                Provenance().add_output_file(filename, 'dl0.tel.svc.camera')
            except IOError as err:
                self.log.warning(
                    "couldn't write camera definition '%s' because: %s",
                    filename, err)

    def write_optics_descriptions(self):
        sub = self.inst.subarray
        ext, args = self._get_file_format_info(self.format, sub.name, 'optics')

        tab = sub.to_table(kind='optics')
        tab.meta['SOURCE'] = self.infile
        filename = f'{sub.name}.optics.{ext}'
        try:
            tab.write(filename, **args)
            Provenance().add_output_file(filename, 'dl0.sub.svc.optics')
        except IOError as err:
            self.log.warning(
                "couldn't write optics description '%s' because: %s", filename,
                err)

    def write_subarray_description(self):
        sub = self.inst.subarray
        ext, args = self._get_file_format_info(self.format, sub.name,
                                               'subarray')
        tab = sub.to_table(kind='subarray')
        tab.meta['SOURCE'] = self.infile
        filename = f'{sub.name}.subarray.{ext}'
        try:
            tab.write(filename, **args)
            Provenance().add_output_file(filename, 'dl0.sub.svc.subarray')
        except IOError as err:
            self.log.warning(
                "couldn't write subarray description '%s' because: %s",
                filename, err)
コード例 #5
0
class DumpTriggersTool(Tool):
    description = Unicode(__doc__)
    name = "ctapipe-dump-triggers"

    # =============================================
    # configuration parameters:
    # =============================================

    infile = Path(exists=True,
                  directory_ok=False,
                  help="input simtelarray file").tag(config=True)

    outfile = Path(
        default_value="triggers.fits",
        directory_ok=False,
        help="output filename (*.fits, *.h5)",
    ).tag(config=True)

    overwrite = Bool(False,
                     help="overwrite existing output file").tag(config=True)

    # =============================================
    # map low-level options to high-level command-line options
    # =============================================

    aliases = Dict({
        "infile": "DumpTriggersTool.infile",
        "outfile": "DumpTriggersTool.outfile"
    })

    flags = Dict({
        "overwrite": (
            {
                "DumpTriggersTool": {
                    "overwrite": True
                }
            },
            "Enable overwriting of output file",
        )
    })

    examples = ("ctapipe-dump-triggers --infile gamma.simtel.gz "
                "--outfile trig.fits --overwrite"
                "\n\n"
                "If you want to see more output, use --log_level=DEBUG")

    # =============================================
    # The methods of the Tool (initialize, start, finish):
    # =============================================

    def add_event_to_table(self, event):
        """
        add the current hessio event to a row in the `self.events` table
        """
        time = event.trigger.time

        if self._prev_time is None:
            self._prev_time = time

        if self._current_starttime is None:
            self._current_starttime = time

        relative_time = time - self._current_starttime
        delta_t = time - self._prev_time
        self._prev_time = time

        # build the trigger pattern as a fixed-length array
        # (better for storage in FITS format)
        # trigtels = event.get_telescope_with_data_list()
        trigtels = event.dl0.tel.keys()
        self._current_trigpattern[:] = 0  # zero the trigger pattern
        self._current_trigpattern[list(trigtels)] = 1  # set the triggered tels
        # to 1

        # insert the row into the table
        self.events.add_row((
            event.index.event_id,
            relative_time.sec,
            delta_t.sec,
            len(trigtels),
            self._current_trigpattern,
        ))

    def setup(self):
        """ setup function, called before `start()` """

        if self.infile == "":
            raise ToolConfigurationError(
                "No 'infile' parameter was specified. ")

        self.events = Table(
            names=["EVENT_ID", "T_REL", "DELTA_T", "N_TRIG", "TRIGGERED_TELS"],
            dtype=[np.int64, np.float64, np.float64, np.int32, np.uint8],
        )

        self.events["TRIGGERED_TELS"].shape = (0, MAX_TELS)
        self.events["T_REL"].unit = u.s
        self.events["T_REL"].description = "Time relative to first event"
        self.events["DELTA_T"].unit = u.s
        self.events.meta["INPUT"] = str(self.infile)

        self._current_trigpattern = np.zeros(MAX_TELS)
        self._current_starttime = None
        self._prev_time = None

    def start(self):
        """ main event loop """
        with EventSource(self.infile) as source:
            for event in source:
                self.add_event_to_table(event)

    def finish(self):
        """
        finish up and write out results (called automatically after
        `start()`)
        """
        # write out the final table
        try:
            if ".fits" in self.outfile.suffixes:
                self.events.write(self.outfile, overwrite=self.overwrite)
            elif self.outfile.suffix in (".hdf5", ".h5", ".hdf"):
                self.events.write(self.outfile,
                                  path="/events",
                                  overwrite=self.overwrite)
            else:
                self.events.write(self.outfile)

            Provenance().add_output_file(self.outfile)
        except IOError as err:
            self.log.warning("Couldn't write output (%s)", err)

        self.log.info("\n %s", self.events)
コード例 #6
0
class SingleTelEventDisplay(Tool):
    name = "ctapipe-display-televents"
    description = Unicode(__doc__)

    tel = Int(help="Telescope ID to display", default_value=0).tag(config=True)

    write = Bool(help="Write out images to PNG files",
                 default_value=False).tag(config=True)

    clean = Bool(help="Apply image cleaning",
                 default_value=False).tag(config=True)

    hillas = Bool(help="Apply and display Hillas parametrization",
                  default_value=False).tag(config=True)

    samples = Bool(help="Show each sample",
                   default_value=False).tag(config=True)

    display = Bool(help="Display results in interactive window",
                   default_value=True).tag(config=True)

    delay = Float(help="delay between events in s",
                  default_value=0.01,
                  min=0.001).tag(config=True)
    progress = Bool(help="display progress bar",
                    default_value=True).tag(config=True)

    aliases = Dict({
        "input": "EventSource.input_url",
        "tel": "SingleTelEventDisplay.tel",
        "max-events": "EventSource.max_events",
        "write": "SingleTelEventDisplay.write",
        "clean": "SingleTelEventDisplay.clean",
        "hillas": "SingleTelEventDisplay.hillas",
        "samples": "SingleTelEventDisplay.samples",
        "display": "SingleTelEventDisplay.display",
        "delay": "SingleTelEventDisplay.delay",
        "progress": "SingleTelEventDisplay.progress",
    })

    classes = [EventSource, CameraCalibrator]

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def setup(self):
        self.event_source = EventSource(parent=self)
        self.event_source.allowed_tels = {self.tel}

        self.calibrator = CameraCalibrator(parent=self,
                                           subarray=self.event_source.subarray)
        self.log.info(f"SELECTING EVENTS FROM TELESCOPE {self.tel}")

    def start(self):

        disp = None

        for event in tqdm(
                self.event_source,
                desc=f"Tel{self.tel}",
                total=self.event_source.max_events,
                disable=~self.progress,
        ):

            self.log.debug(event.trigger)
            self.log.debug(f"Energy: {event.simulation.shower.energy}")

            self.calibrator(event)

            if disp is None:
                geom = self.event_source.subarray.tel[self.tel].camera.geometry
                self.log.info(geom)
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                if self.display:
                    plt.show(block=False)

            # display the event
            disp.axes.set_title("CT{:03d} ({}), event {:06d}".format(
                self.tel, geom.camera_name, event.index.event_id))

            if self.samples:
                # display time-varying event
                data = event.dl0.tel[self.tel].waveform
                for ii in range(data.shape[1]):
                    disp.image = data[:, ii]
                    disp.set_limits_percent(70)
                    plt.suptitle(f"Sample {ii:03d}")
                    if self.display:
                        plt.pause(self.delay)
                    if self.write:
                        plt.savefig(
                            f"CT{self.tel:03d}_EV{event.index.event_id:10d}"
                            f"_S{ii:02d}.png")
            else:
                # display integrated event:
                im = event.dl1.tel[self.tel].image

                if self.clean:
                    mask = tailcuts_clean(geom,
                                          im,
                                          picture_thresh=10,
                                          boundary_thresh=7)
                    im[~mask] = 0.0

                disp.image = im

                if self.hillas:
                    try:
                        ellipses = disp.axes.findobj(Ellipse)
                        if len(ellipses) > 0:
                            ellipses[0].remove()

                        params = hillas_parameters(geom, image=im)
                        disp.overlay_moments(params,
                                             color="pink",
                                             lw=3,
                                             with_label=False)
                    except HillasParameterizationError:
                        pass

                if self.display:
                    plt.pause(self.delay)
                if self.write:
                    plt.savefig(
                        f"CT{self.tel:03d}_EV{event.index.event_id:010d}.png")

        self.log.info("FINISHED READING DATA FILE")

        if disp is None:
            self.log.warning(
                "No events for tel {} were found in {}. Try a "
                "different EventIO file or another telescope".format(
                    self.tel, self.infile))
コード例 #7
0
class SimpleEventWriter(Tool):
    name = "ctapipe-simple-event-writer"
    description = Unicode(__doc__)

    infile = Path(
        default_value=get_dataset_path(
            "lst_prod3_calibration_and_mcphotons.simtel.zst"),
        help="input file to read",
        directory_ok=False,
        exists=True,
    ).tag(config=True)
    outfile = Path(help="output file name",
                   directory_ok=False,
                   default_value="output.h5").tag(config=True)
    progress = Bool(help="display progress bar",
                    default_value=True).tag(config=True)

    aliases = Dict({
        "infile": "EventSource.input_url",
        "outfile": "SimpleEventWriter.outfile",
        "max-events": "EventSource.max_events",
        "progress": "SimpleEventWriter.progress",
    })
    classes = List([EventSource, CameraCalibrator])

    def setup(self):
        self.log.info("Configure EventSource...")

        self.event_source = self.add_component(
            EventSource.from_url(self.infile, parent=self))

        self.calibrator = self.add_component(
            CameraCalibrator(subarray=self.event_source.subarray, parent=self))

        self.writer = self.add_component(
            HDF5TableWriter(filename=self.outfile,
                            group_name="image_infos",
                            overwrite=True))

    def start(self):
        self.log.info("Loop on events...")

        for event in tqdm(
                self.event_source,
                desc="EventWriter",
                total=self.event_source.max_events,
                disable=~self.progress,
        ):

            self.calibrator(event)

            for tel_id in event.dl0.tels_with_data:

                geom = self.event_source.subarray.tel[tel_id].camera.geometry
                dl1_tel = event.dl1.tel[tel_id]

                # Image cleaning
                image = dl1_tel.image  # Waiting for automatic gain selection
                mask = tailcuts_clean(geom,
                                      image,
                                      picture_thresh=10,
                                      boundary_thresh=5)
                cleaned = image.copy()
                cleaned[~mask] = 0

                # Image parametrisation
                params = hillas_parameters(geom, cleaned)

                # Save Ids, MC infos and Hillas informations
                self.writer.write(geom.camera_name,
                                  [event.r0, event.mc, params])

    def finish(self):
        self.log.info("End of job.")
        self.writer.close()
コード例 #8
0
class SingleTelEventDisplay(Tool):
    name = "ctapipe-display-single-tel"
    description = Unicode(__doc__)

    infile = Unicode(help="input file to read", default='').tag(config=True)
    tel = Int(help='Telescope ID to display', default=0).tag(config=True)
    channel = Integer(
        help="channel number to display", min=0, max=1
    ).tag(config=True)
    write = Bool(
        help="Write out images to PNG files", default=False
    ).tag(config=True)
    clean = Bool(help="Apply image cleaning", default=False).tag(config=True)
    hillas = Bool(
        help="Apply and display Hillas parametrization", default=False
    ).tag(config=True)
    samples = Bool(help="Show each sample", default=False).tag(config=True)
    display = Bool(
        help="Display results in interactive window", default_value=True
    ).tag(config=True)
    delay = Float(
        help='delay between events in s', default_value=0.01, min=0.001
    ).tag(config=True)
    progress = Bool(
        help='display progress bar', default_value=True
    ).tag(config=True)

    aliases = Dict({
        'infile': 'EventSourceFactory.input_url',
        'tel': 'SingleTelEventDisplay.tel',
        'max-events': 'EventSourceFactory.max_events',
        'channel': 'SingleTelEventDisplay.channel',
        'write': 'SingleTelEventDisplay.write',
        'clean': 'SingleTelEventDisplay.clean',
        'hillas': 'SingleTelEventDisplay.hillas',
        'samples': 'SingleTelEventDisplay.samples',
        'display': 'SingleTelEventDisplay.display',
        'delay': 'SingleTelEventDisplay.delay',
        'progress': 'SingleTelEventDisplay.progress'
    })

    classes = List([EventSourceFactory, CameraCalibrator])

    def setup(self):

        self.event_source = EventSourceFactory.produce(
            config=self.config, tool=self
        )
        self.event_source.allowed_tels = [
            self.tel,
        ]

        self.calibrator = CameraCalibrator(
            config=self.config, tool=self, eventsource=self.event_source
        )

        self.log.info('SELECTING EVENTS FROM TELESCOPE {}'.format(self.tel))

    def start(self):

        disp = None

        for event in tqdm(
            self.event_source,
            desc='Tel{}'.format(self.tel),
            total=self.event_source.max_events,
            disable=~self.progress
        ):

            self.log.debug(event.trig)
            self.log.debug("Energy: {}".format(event.mc.energy))

            self.calibrator.calibrate(event)

            if disp is None:
                geom = event.inst.subarray.tel[self.tel].camera
                self.log.info(geom)
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                if self.display:
                    plt.show(block=False)

            # display the event
            disp.axes.set_title(
                'CT{:03d} ({}), event {:06d}'.format(
                    self.tel, geom.cam_id, event.r0.event_id
                )
            )

            if self.samples:
                # display time-varying event
                data = event.dl0.tel[self.tel].waveform[self.channel]
                for ii in range(data.shape[1]):
                    disp.image = data[:, ii]
                    disp.set_limits_percent(70)
                    plt.suptitle("Sample {:03d}".format(ii))
                    if self.display:
                        plt.pause(self.delay)
                    if self.write:
                        plt.savefig(
                            'CT{:03d}_EV{:10d}_S{:02d}.png'
                            .format(self.tel, event.r0.event_id, ii)
                        )
            else:
                # display integrated event:
                im = event.dl1.tel[self.tel].image[self.channel]

                if self.clean:
                    mask = tailcuts_clean(
                        geom, im, picture_thresh=10, boundary_thresh=7
                    )
                    im[~mask] = 0.0

                disp.image = im

                if self.hillas:
                    try:
                        ellipses = disp.axes.findobj(Ellipse)
                        if len(ellipses) > 0:
                            ellipses[0].remove()

                        params = hillas_parameters(geom, image=im)
                        disp.overlay_moments(
                            params, color='pink', lw=3, with_label=False
                        )
                    except HillasParameterizationError:
                        pass

                if self.display:
                    plt.pause(self.delay)
                if self.write:
                    plt.savefig(
                        'CT{:03d}_EV{:010d}.png'
                        .format(self.tel, event.r0.event_id)
                    )

        self.log.info("FINISHED READING DATA FILE")

        if disp is None:
            self.log.warning(
                'No events for tel {} were found in {}. Try a '
                'different EventIO file or another telescope'
                .format(self.tel, self.infile),
            )