def display_telescope(event, tel_id, display, geom_dict, pp, fig):
    fig.clear()

    cam_dimensions = (event.dl0.tel[tel_id].num_pixels,
                      event.meta.optical_foclen[tel_id])

    fig.suptitle("EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}".format(
        event.dl1.event_id, event.mc.energy, event.mc.alt, event.mc.az,
        np.sqrt(pow(event.mc.core_x, 2) + pow(event.mc.core_y, 2))))

    # Select number of pads to display (will depend on the integrator):
    # charge and/or time of maximum.
    # This last one is displayed only if the integrator calculates it
    npads = 1
    if not event.dl1.tel[tel_id].peakpos[0] is None:
        npads = 2
    # Only create two pads if there is timing information extracted
    # from the calibration
    ax1 = fig.add_subplot(1, npads, 1)

    # If the geometery has not already been added to geom_dict, it will
    # be added in CameraPlotter
    plotter = CameraPlotter(event, geom_dict)
    signals = event.dl1.tel[tel_id].pe_charge
    camera1 = plotter.draw_camera(tel_id, signals, ax1)
    cmaxmin = (max(signals) - min(signals))
    cmap_charge = colors.LinearSegmentedColormap.from_list(
        'cmap_c', [(0 / cmaxmin, 'darkblue'),
                   (np.abs(min(signals)) / cmaxmin, 'black'),
                   (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                   (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                   (1, 'yellow')])
    camera1.pixels.set_cmap(cmap_charge)
    camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
    ax1.set_title("CT {} ({}) - Mean pixel charge".format(
        tel_id, geom_dict[cam_dimensions].cam_id))
    if not event.dl1.tel[tel_id].peakpos[0] is None:
        ax2 = fig.add_subplot(1, npads, npads)
        times = event.dl1.tel[tel_id].peakpos
        camera2 = plotter.draw_camera(tel_id, times, ax2)
        tmaxmin = event.dl0.tel[tel_id].num_samples
        t_chargemax = times[signals.argmax()]
        if t_chargemax > 15:
            t_chargemax = 7
        cmap_time = colors.LinearSegmentedColormap.from_list(
            'cmap_t', [(0 / tmaxmin, 'darkgreen'),
                       (0.6 * t_chargemax / tmaxmin, 'green'),
                       (t_chargemax / tmaxmin, 'yellow'),
                       (1.4 * t_chargemax / tmaxmin, 'blue'), (1, 'darkblue')])
        camera2.pixels.set_cmap(cmap_time)
        camera2.add_colorbar(ax=ax2, label="[time slice]")
        ax2.set_title("CT {} ({}) - Pixel peak position".format(
            tel_id, geom_dict[cam_dimensions].cam_id))

    if display:
        plt.pause(0.1)
    if pp is not None:
        pp.savefig(fig)
Exemple #2
0
def test_eventplotter():
    dataset = get_dataset("gamma_test.simtel.gz")
    source = hessio_event_source(dataset, max_events=1)
    event = next(source)
    data = event.r0.tel[38].adc_samples[0]
    plotter = CameraPlotter(event)

    camera = plotter.draw_camera(38, data[:, 0])
    assert camera is not None
    np.testing.assert_array_equal(camera.image, data[:, 0])

    plotter.draw_camera_pixel_ids(38, [0, 1, 2])

    waveform = plotter.draw_waveform(data[0, :])
    assert waveform is not None
    np.testing.assert_array_equal(waveform.get_ydata(), data[0, :])

    line = plotter.draw_waveform_positionline(0)
    assert line is not None
    np.testing.assert_array_equal(line.get_xdata(), [0, 0])
Exemple #3
0
def test_eventplotter():
    dataset = get_dataset_path("gamma_test_large.simtel.gz")
    with event_source(dataset, max_events=1) as source:
        event = next(iter(source))

        telid = list(event.r0.tels_with_data)[0]

        data = event.r0.tel[telid].waveform[0]
        plotter = CameraPlotter(event)

        camera = plotter.draw_camera(telid, data[:, 0])
        assert camera is not None
        np.testing.assert_array_equal(camera.image, data[:, 0])

        plotter.draw_camera_pixel_ids(telid, [0, 1, 2])

        waveform = plotter.draw_waveform(data[0, :])
        assert waveform is not None
        np.testing.assert_array_equal(waveform.get_ydata(), data[0, :])

        line = plotter.draw_waveform_positionline(0)
        assert line is not None
        np.testing.assert_array_equal(line.get_xdata(), [0, 0])
Exemple #4
0
def plot_muon_event(event, muonparams, args=None):

    if muonparams['MuonRingParams'] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))

        colorbar = None
        colorbar2 = None

        #for tel_id in event.dl0.tels_with_data:
        for tel_id in muonparams['TelIds']:
            idx = muonparams['TelIds'].index(tel_id)

            if not muonparams['MuonRingParams'][idx]:
                continue

            #otherwise...
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event)
            image = event.dl1.tel[tel_id].image[0]
            geom = event.inst.subarray.tel[tel_id].camera

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            clean_mask = tailcuts_clean(geom,
                                        image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(
                muonparams['MuonRingParams'][idx].ring_center_x**2. +
                muonparams['MuonRingParams'][idx].ring_center_y**2.)

            muon_phi = np.arctan(
                muonparams['MuonRingParams'][idx].ring_center_y /
                muonparams['MuonRingParams'][idx].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(
                x=muonparams['MuonRingParams'][idx].ring_center_x,
                y=muonparams['MuonRingParams'][idx].ring_center_y,
                array_direction=altaz,
                pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(
                CameraFrame(pointing_direction=altaz,
                            focal_length=event.inst.optical_foclen[tel_id],
                            rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams['MuonRingParams'][idx].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px,
                                       y=py,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz, pointing_direction=altaz))

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(
                np.power(px -
                         muonparams['MuonRingParams'][idx].ring_center_x, 2) +
                np.power(py -
                         muonparams['MuonRingParams'][idx].ring_center_y, 2))
            ring_dist = np.abs(dist -
                               muonparams['MuonRingParams'][idx].ring_radius)
            pixRmask = ring_dist < muonparams['MuonRingParams'][
                idx].ring_radius * 0.4

            #if muonparams[1] is not None:
            if muonparams['MuonIntensityParams'][idx] is not None:
                signals *= muonparams['MuonIntensityParams'][idx].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            cmin = min(signals)
            if not cmin:
                cmin = 1.
            if not cmaxmin:
                cmaxmin = 1.

            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(cmin) / cmaxmin, 'black'),
                           (2.0 * np.abs(cmin) / cmaxmin, 'blue'),
                           (2.5 * np.abs(cmin) / cmaxmin, 'green'),
                           (1, 'yellow')])
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid,
                                ringrad_camcoord.value,
                                ringrad_camcoord.value,
                                0.,
                                0.,
                                color="red")

            if muonparams['MuonIntensityParams'][idx] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)

                ringwidthfrac = muonparams['MuonIntensityParams'][
                    idx].ring_width / muonparams['MuonRingParams'][
                        idx].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid,
                                    ringrad_inner.value,
                                    ringrad_inner.value,
                                    0.,
                                    0.,
                                    color="magenta")
                camera1.add_ellipse(centroid,
                                    ringrad_outer.value,
                                    ringrad_outer.value,
                                    0.,
                                    0.,
                                    color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams['MuonIntensityParams'][idx].prediction

                if len(pred) != np.sum(
                        muonparams['MuonIntensityParams'][idx].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=",
                          np.sum(muonparams['MuonIntensityParams'][idx].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams['MuonIntensityParams'][idx].mask ==
                         True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                if np.isnan(max(plotpred)) or np.isnan(min(plotpred)):
                    print("nan prediction, skipping...")
                    continue

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.

                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c',
                    [(0 / c2maxmin, 'darkblue'),
                     (np.abs(min(plotpred)) / c2maxmin, 'black'),
                     (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                     (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                     (1, 'yellow')])
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            #fig.savefig(str(args.output_path) + "_" +
            #            str(event.dl0.event_id) + '.png')

            plt.close()
def plot_muon_event(event, muonparams, geom_dict=None, args=None):

    if muonparams[0] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))
        # if args.display:
        #    plt.show(block=False)
        #pp = PdfPages(args.output_path) if args.output_path is not None else None
        # pp = None #For now, need to correct this

        colorbar = None
        colorbar2 = None

        for tel_id in event.dl0.tels_with_data:
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event, geom_dict)
            #image = event.dl1.tel[tel_id].calibrated_image
            image = event.dl1.tel[tel_id].image[0]
            # Get geometry
            geom = None
            if geom_dict is not None and tel_id in geom_dict:
                geom = geom_dict[tel_id]
            else:
                #log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.inst.pixel_pos[tel_id],
                                            event.inst.optical_foclen[tel_id])
                #log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[tel_id] = geom

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            #print("Using Tail Cuts:",tailcuts)
            clean_mask = tailcuts_clean(geom, image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(muonparams[0].ring_center_x**2. +
                                muonparams[0].ring_center_y**2.)

            muon_phi = np.arctan(muonparams[0].ring_center_y /
                                 muonparams[0].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(x=muonparams[0].ring_center_x,
                                        y=muonparams[0].ring_center_y,
                                        array_direction=altaz,
                                        pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(CameraFrame(
                pointing_direction=altaz,
                focal_length=event.inst.optical_foclen[tel_id],
                rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams[0].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            #rot_angle = 0.*u.deg
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and event.dl0.tel[tel_id].num_pixels != 1764:
            #rot_angle = -100.14*u.deg

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px, y=py,
                                       z=np.zeros(px.shape) * u.m,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz,
                             pointing_direction=altaz)
            )
            #,focal_length = event.inst.optical_foclen[tel_id])) # tel['TelescopeTable_VersionFeb2016'][tel['TelescopeTable_VersionFeb2016']['TelID']==telid]['FL'][0]*u.m))

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(np.power( px - muonparams[0].ring_center_x, 2)
                           + np.power(py - muonparams[0].ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams[0].ring_radius)
            pixRmask = ring_dist < muonparams[0].ring_radius * 0.4

            if muonparams[1] is not None:
                signals *= muonparams[1].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            if not cmaxmin:
                cmaxmin = 1.
            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(min(signals)) / cmaxmin, 'black'),
                           (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                           (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                           (1, 'yellow')]
            )
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid, ringrad_camcoord.value,
                                ringrad_camcoord.value, 0., 0., color="red")

#            ax1.set_title("CT {} ({}) - Mean pixel charge"
#                          .format(tel_id, geom_dict[tel_id].cam_id))

            if muonparams[1] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)
                ringwidthfrac = muonparams[
                    1].ring_width / muonparams[0].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid, ringrad_inner.value,
                                     ringrad_inner.value, 0., 0.,
                                     color="magenta")
                camera1.add_ellipse(centroid, ringrad_outer.value,
                                    ringrad_outer.value, 0., 0., color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams[1].prediction

                if len(pred) != np.sum(muonparams[1].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=", np.sum(muonparams[1].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams[1].mask == True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.
                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c', [(0 / c2maxmin, 'darkblue'),
                                (np.abs(min(plotpred)) / c2maxmin, 'black'),
                                (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                                (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                                (1, 'yellow')]
                )
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            fig.savefig(str(args.output_path) + "_" +
                        str(event.dl0.event_id) + '.png')

            plt.close()
    def run(self, inputs):
        self.log.debug("--- PrepareDisplayStep RUN ---")
        calibrated_event, geom_dict = inputs
        for tel_id in calibrated_event.dl0.tels_with_data:
            self.fig.clear()
            cam_dimensions = (calibrated_event.inst.num_pixels[tel_id],
                              calibrated_event.inst.optical_foclen[tel_id])
            self.fig.suptitle(
                "EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}".format(
                    calibrated_event.dl1.event_id, calibrated_event.mc.energy,
                    calibrated_event.mc.alt, calibrated_event.mc.az,
                    np.sqrt(
                        pow(calibrated_event.mc.core_x, 2) +
                        pow(calibrated_event.mc.core_y, 2))))
            # Select number of pads to display (will depend on the integrator):
            # charge and/or time of maximum.
            # This last one is displayed only if the integrator calculates it
            npads = 1
            if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None:
                npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = self.fig.add_subplot(1, npads, 1)
            # If the geometery has not already been added to geom_dict, it will
            # be added in CameraPlotter
            plotter = CameraPlotter(calibrated_event, geom_dict)

            signals = calibrated_event.dl1.tel[tel_id].calibrated_image
            camera1 = plotter.draw_camera(tel_id, signals, ax1)
            cmaxmin = (max(signals) - min(signals))
            color_list = [(0 / cmaxmin, 'darkblue'),
                          (np.abs(min(signals)) / cmaxmin, 'black'),
                          (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                          (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                          (1, 'yellow')]
            try:
                cmap_charge = colors.LinearSegmentedColormap.from_list(
                    'cmap_c', color_list)
                camera1.pixels.set_cmap(cmap_charge)
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
            except:
                camera1.pixels.set_cmap('jet')
            ax1.set_title("CT {} ({}) - Mean pixel charge".format(
                tel_id, geom_dict[tel_id].cam_id))
            if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None:
                ax2 = self.fig.add_subplot(1, npads, npads)
                times = calibrated_event.dl1.tel[tel_id].peakpos
                camera2 = plotter.draw_camera(tel_id, times, ax2)
                tmaxmin = calibrated_event.dl0.tel[tel_id].num_samples
                t_chargemax = times[signals.argmax()]
                if t_chargemax > 15:
                    t_chargemax = 7
                cmap_time = colors.LinearSegmentedColormap.from_list(
                    'cmap_t', [(0 / tmaxmin, 'darkgreen'),
                               (0.6 * t_chargemax / tmaxmin, 'green'),
                               (t_chargemax / tmaxmin, 'yellow'),
                               (1.4 * t_chargemax / tmaxmin, 'blue'),
                               (1, 'darkblue')])
                try:
                    camera2.pixels.set_cmap(cmap_time)
                    camera2.add_colorbar(ax=ax2, label="[time slice]")
                except:
                    camera2.pixels.set_cmap('jet')
                ax2.set_title("CT {} ({}) - Pixel peak position".format(
                    tel_id, geom_dict[tel_id].cam_id))
            yield self.fig
        self.log.debug("--- PrepareDisplayStep END ---")
def plot_muon_event(event, muonparams):
    if muonparams['MuonRingParams'] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))

        colorbar = None
        colorbar2 = None

        subarray = event.inst.subarray

        # for tel_id in event.dl0.tels_with_data:
        for tel_id in muonparams['TelIds']:
            idx = muonparams['TelIds'].index(tel_id)

            if not muonparams['MuonRingParams'][idx]:
                continue

            # otherwise...
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event)
            image = event.dl1.tel[tel_id].image[0]
            geom = event.inst.subarray.tel[tel_id].camera

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            clean_mask = tailcuts_clean(geom, image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            rotr_angle = geom.pix_rotation
# The following two lines have been commented out to avoid a rotation error.
#            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':

#                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = SkyCoord(
                delta_az=muonparams['MuonRingParams'][idx].ring_center_x,
                delta_alt=muonparams['MuonRingParams'][idx].ring_center_y,
                frame=NominalFrame(origin=altaz)
            )

            flen = subarray.tel[tel_id].optics.equivalent_focal_length
            ring_camcoord = ring_nominal.transform_to(CameraFrame(
                pointing_direction=altaz,
                focal_length=flen,
                rotation=rotr_angle))

            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            radius = muonparams['MuonRingParams'][idx].ring_radius
            ringrad_camcoord = 2 * radius.to(u.rad) * flen  # But not FC?

            px = subarray.tel[tel_id].camera.pix_x
            py = subarray.tel[tel_id].camera.pix_y
            camera_coord = SkyCoord(
                x=px,
                y=py,
                frame=CameraFrame(
                    focal_length=flen,
                    rotation=geom.pix_rotation,
                )
            )

            nom_coord = camera_coord.transform_to(
                NominalFrame(origin=altaz)
            )

            px = nom_coord.delta_az.to(u.deg)
            py = nom_coord.delta_alt.to(u.deg)
            dist = np.sqrt(np.power(px - muonparams['MuonRingParams'][idx].ring_center_x,
                                    2) + np.power(py - muonparams['MuonRingParams'][idx].
                                                  ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams['MuonRingParams'][idx].ring_radius)
            pix_rmask = ring_dist < muonparams['MuonRingParams'][idx].ring_radius * 0.4

            if muonparams['MuonIntensityParams'][idx] is not None:
                signals *= muonparams['MuonIntensityParams'][idx].mask
            elif muonparams['MuonIntensityParams'][idx] is None:
                signals *= pix_rmask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            cmin = min(signals)
            if not cmin:
                cmin = 1.
            if not cmaxmin:
                cmaxmin = 1.

            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(cmin) / cmaxmin, 'black'),
                           (2.0 * np.abs(cmin) / cmaxmin, 'blue'),
                           (2.5 * np.abs(cmin) / cmaxmin, 'green'),
                           (1, 'yellow')]
            )
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid, ringrad_camcoord.value,
                                ringrad_camcoord.value, 0., 0., color="red")

            if muonparams['MuonIntensityParams'][idx] is not None:

                ringwidthfrac = muonparams['MuonIntensityParams'][idx].ring_width / \
                    muonparams['MuonRingParams'][idx].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid, ringrad_inner.value,
                                    ringrad_inner.value, 0., 0.,
                                    color="magenta")
                camera1.add_ellipse(centroid, ringrad_outer.value,
                                    ringrad_outer.value, 0., 0.,
                                    color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams['MuonIntensityParams'][idx].prediction

                if len(pred) != np.sum(
                        muonparams['MuonIntensityParams'][idx].mask):
                    logger.warning("Lengths do not match...len(pred)=%s len("
                                   "mask)=", len(pred),
                                   np.sum(muonparams['MuonIntensityParams'][idx].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                truelocs = np.where(muonparams['MuonIntensityParams'][idx].mask == True)
                plotpred[truelocs] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                if np.isnan(max(plotpred)) or np.isnan(min(plotpred)):
                    logger.debug("nan prediction, skipping...")
                    continue

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.

                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c', [(0 / c2maxmin, 'darkblue'),
                                (np.abs(min(plotpred)) / c2maxmin, 'black'),
                                (
                                2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                                (2.5 * np.abs(min(plotpred)) / c2maxmin,
                                 'green'),
                                (1, 'yellow')]
                )
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            # fig.savefig(str(args.output_path) + "_" +
            #            str(event.dl0.event_id) + '.png')


            plt.close()
def plot_muon_event(event, muonparams):
    if muonparams['MuonRingParams'] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))

        colorbar = None
        colorbar2 = None

        subarray = event.inst.subarray

        # for tel_id in event.dl0.tels_with_data:
        for tel_id in muonparams['TelIds']:
            idx = muonparams['TelIds'].index(tel_id)

            if not muonparams['MuonRingParams'][idx]:
                continue

            # otherwise...
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event)
            image = event.dl1.tel[tel_id].image
            geom = event.inst.subarray.tel[tel_id].camera

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            clean_mask = tailcuts_clean(geom,
                                        image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            rotr_angle = geom.pix_rotation
            # The following two lines have been commented out to avoid a rotation error.
            #            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':

            #                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = AltAz(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = SkyCoord(
                delta_az=muonparams['MuonRingParams'][idx].ring_center_x,
                delta_alt=muonparams['MuonRingParams'][idx].ring_center_y,
                frame=NominalFrame(origin=altaz))

            flen = subarray.tel[tel_id].optics.equivalent_focal_length
            ring_camcoord = ring_nominal.transform_to(
                CameraFrame(pointing_direction=altaz,
                            focal_length=flen,
                            rotation=rotr_angle))

            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            radius = muonparams['MuonRingParams'][idx].ring_radius
            ringrad_camcoord = 2 * radius.to(u.rad) * flen  # But not FC?

            px = subarray.tel[tel_id].camera.pix_x
            py = subarray.tel[tel_id].camera.pix_y
            camera_coord = SkyCoord(x=px,
                                    y=py,
                                    frame=CameraFrame(
                                        focal_length=flen,
                                        rotation=geom.pix_rotation,
                                    ))

            nom_coord = camera_coord.transform_to(NominalFrame(origin=altaz))

            px = nom_coord.delta_az.to(u.deg)
            py = nom_coord.delta_alt.to(u.deg)
            dist = np.sqrt(
                np.power(px -
                         muonparams['MuonRingParams'][idx].ring_center_x, 2) +
                np.power(py -
                         muonparams['MuonRingParams'][idx].ring_center_y, 2))
            ring_dist = np.abs(dist -
                               muonparams['MuonRingParams'][idx].ring_radius)
            pix_rmask = ring_dist < muonparams['MuonRingParams'][
                idx].ring_radius * 0.4

            if muonparams['MuonIntensityParams'][idx] is not None:
                signals *= muonparams['MuonIntensityParams'][idx].mask
            elif muonparams['MuonIntensityParams'][idx] is None:
                signals *= pix_rmask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            cmin = min(signals)
            if not cmin:
                cmin = 1.
            if not cmaxmin:
                cmaxmin = 1.

            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(cmin) / cmaxmin, 'black'),
                           (2.0 * np.abs(cmin) / cmaxmin, 'blue'),
                           (2.5 * np.abs(cmin) / cmaxmin, 'green'),
                           (1, 'yellow')])
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid,
                                ringrad_camcoord.value,
                                ringrad_camcoord.value,
                                0.,
                                0.,
                                color="red")

            if muonparams['MuonIntensityParams'][idx] is not None:

                ringwidthfrac = muonparams['MuonIntensityParams'][idx].ring_width / \
                    muonparams['MuonRingParams'][idx].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid,
                                    ringrad_inner.value,
                                    ringrad_inner.value,
                                    0.,
                                    0.,
                                    color="magenta")
                camera1.add_ellipse(centroid,
                                    ringrad_outer.value,
                                    ringrad_outer.value,
                                    0.,
                                    0.,
                                    color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams['MuonIntensityParams'][idx].prediction

                if len(pred) != np.sum(
                        muonparams['MuonIntensityParams'][idx].mask):
                    logger.warning(
                        "Lengths do not match...len(pred)=%s len("
                        "mask)=", len(pred),
                        np.sum(muonparams['MuonIntensityParams'][idx].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                truelocs = np.where(
                    muonparams['MuonIntensityParams'][idx].mask == True)
                plotpred[truelocs] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                if np.isnan(max(plotpred)) or np.isnan(min(plotpred)):
                    logger.debug("nan prediction, skipping...")
                    continue

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.

                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c',
                    [(0 / c2maxmin, 'darkblue'),
                     (np.abs(min(plotpred)) / c2maxmin, 'black'),
                     (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                     (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                     (1, 'yellow')])
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            # fig.savefig(str(args.output_path) + "_" +
            #            str(event.dl0.event_id) + '.png')

            plt.close()
    def run(self,inputs):
        self.log.debug("--- PrepareDisplayStep RUN ---")
        calibrated_event,  geom_dict = inputs
        for tel_id in calibrated_event.dl0.tels_with_data:
            self.fig.clear()
            cam_dimensions = (calibrated_event.inst.num_pixels[tel_id],
                              calibrated_event.inst.optical_foclen[tel_id])
            self.fig.suptitle("EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}"
                         .format(calibrated_event.dl1.event_id, calibrated_event.mc.energy,
                                 calibrated_event.mc.alt,
                                 calibrated_event.mc.az,
                                 np.sqrt(pow(calibrated_event.mc.core_x, 2) +
                                         pow(calibrated_event.mc.core_y, 2))))
            # Select number of pads to display (will depend on the integrator):
            # charge and/or time of maximum.
            # This last one is displayed only if the integrator calculates it
            npads = 1
            if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None:
                npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = self.fig.add_subplot(1, npads, 1)
            # If the geometery has not already been added to geom_dict, it will
            # be added in CameraPlotter
            plotter = CameraPlotter(calibrated_event, geom_dict)

            signals = calibrated_event.dl1.tel[tel_id].calibrated_image
            camera1 = plotter.draw_camera(tel_id, signals, ax1)
            cmaxmin = (max(signals) - min(signals))
            color_list = [(0 / cmaxmin, 'darkblue'),
                       (np.abs(min(signals)) / cmaxmin, 'black'),
                       (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                       (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                       (1, 'yellow')]
            try:
                cmap_charge = colors.LinearSegmentedColormap.from_list('cmap_c',
                    color_list)
                camera1.pixels.set_cmap(cmap_charge)
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
            except:
                camera1.pixels.set_cmap('jet')
            ax1.set_title("CT {} ({}) - Mean pixel charge"
                          .format(tel_id, geom_dict[tel_id].cam_id))
            if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None:
                ax2 = self.fig.add_subplot(1, npads, npads)
                times = calibrated_event.dl1.tel[tel_id].peakpos
                camera2 = plotter.draw_camera(tel_id, times, ax2)
                tmaxmin = calibrated_event.dl0.tel[tel_id].num_samples
                t_chargemax = times[signals.argmax()]
                if t_chargemax > 15:
                    t_chargemax = 7
                cmap_time = colors.LinearSegmentedColormap.from_list(
                    'cmap_t', [(0 / tmaxmin, 'darkgreen'),
                               (0.6 * t_chargemax / tmaxmin, 'green'),
                               (t_chargemax / tmaxmin, 'yellow'),
                               (1.4 * t_chargemax / tmaxmin, 'blue'),
                               (1, 'darkblue')])
                try:
                    camera2.pixels.set_cmap(cmap_time)
                    camera2.add_colorbar(ax=ax2, label="[time slice]")
                except:
                    camera2.pixels.set_cmap('jet')
                ax2.set_title("CT {} ({}) - Pixel peak position"
                              .format(tel_id, geom_dict[tel_id].cam_id))
            yield self.fig
        self.log.debug("--- PrepareDisplayStep END ---")
def main():
    script = os.path.splitext(os.path.basename(__file__))[0]
    log.info("[SCRIPT] {}".format(script))

    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('-f',
                        '--file',
                        dest='input_path',
                        action='store',
                        default=get_path('gamma_test.simtel.gz'),
                        help='path to the input file')
    parser.add_argument('-O',
                        '--origin',
                        dest='origin',
                        action='store',
                        choices=InputFile.origin_list(),
                        default='hessio',
                        help='origin of the file')
    parser.add_argument('-o',
                        '--output',
                        dest='output_dir',
                        action='store',
                        default=None,
                        help='path of the output directory to store the '
                        'images (default = input file directory)')
    parser.add_argument('-e',
                        '--event',
                        dest='event_req',
                        action='store',
                        default=0,
                        type=int,
                        help='event index to plot (not id!)')
    parser.add_argument('--id',
                        dest='event_id_f',
                        action='store_true',
                        default=False,
                        help='-e will specify event_id instead '
                        'of index')
    parser.add_argument('-t',
                        '--telescope',
                        dest='tel',
                        action='store',
                        type=int,
                        default=None,
                        help='telecope to view')
    parser.add_argument('-c',
                        '--channel',
                        dest='chan',
                        action='store',
                        type=int,
                        default=0,
                        help='channel to view (default = 0 (HG))')
    parser.add_argument('--calib-help',
                        dest='calib_help',
                        action='store_true',
                        default=False,
                        help='display the arguments used for the camera '
                        'calibration')

    logger_detail = parser.add_mutually_exclusive_group()
    logger_detail.add_argument('-q',
                               '--quiet',
                               dest='quiet',
                               action='store_true',
                               default=False,
                               help='Quiet mode')
    logger_detail.add_argument('-v',
                               '--verbose',
                               dest='verbose',
                               action='store_true',
                               default=False,
                               help='Verbose mode')
    logger_detail.add_argument('-d',
                               '--debug',
                               dest='debug',
                               action='store_true',
                               default=False,
                               help='Debug mode')

    args, excess_args = parser.parse_known_args()

    if args.quiet:
        log.setLevel(40)
    if args.verbose:
        log.setLevel(20)
    if args.debug:
        log.setLevel(10)

    telid = args.tel
    chan = args.chan

    log.debug("[file] Reading file")
    input_file = InputFile(args.input_path, args.origin)
    event = input_file.get_event(args.event_req, args.event_id_f)

    # Print event/args values
    log.info("[event_index] {}".format(event.count))
    log.info("[event_id] {}".format(event.dl0.event_id))
    log.info("[telescope] {}".format(telid))
    log.info("[channel] {}".format(chan))

    params, unknown_args = calibration_parameters(excess_args, args.origin,
                                                  args.calib_help)

    if unknown_args:
        parser.print_help()
        calibration_parameters(unknown_args, args.origin, True)
        msg = 'unrecognized arguments: %s'
        parser.error(msg % ' '.join(unknown_args))

    # Create a dictionary to store any geoms in
    geom = CameraGeometry.guess(*event.meta.pixel_pos[telid],
                                event.meta.optical_foclen[telid])
    geom_dict = {telid: geom}
    calibrated_event = calibrate_event(event, params, geom_dict)

    # Select telescope
    tels = list(calibrated_event.dl0.tels_with_data)
    if telid is None or telid not in tels:
        log.error("[event] please specify one of the following telescopes "
                  "for this event: {}".format(tels))
        exit()

    # Extract required images
    data_ped = calibrated_event.dl1.tel[telid].pedestal_subtracted_adc[chan]
    true_pe = calibrated_event.mc.tel[telid].photo_electrons
    measured_pe = calibrated_event.dl1.tel[telid].pe_charge
    max_time = np.unravel_index(np.argmax(data_ped), data_ped.shape)[1]
    max_charges = np.max(data_ped, axis=1)
    max_pixel = int(np.argmax(max_charges))
    min_pixel = int(np.argmin(max_charges))

    # Get Neighbours
    max_pixel_nei = geom.neighbors[max_pixel]
    min_pixel_nei = geom.neighbors[min_pixel]

    # Get Windows
    windows = calibrated_event.dl1.tel[telid].integration_window[chan]
    length = np.sum(windows, axis=1)
    start = np.argmax(windows, axis=1)
    end = start + length - 1

    # Draw figures
    ax_max_nei = {}
    ax_min_nei = {}
    fig_waveforms = plt.figure(figsize=(18, 9))
    fig_waveforms.subplots_adjust(hspace=.5)
    fig_camera = plt.figure(figsize=(15, 12))

    ax_max_pix = fig_waveforms.add_subplot(4, 2, 1)
    ax_min_pix = fig_waveforms.add_subplot(4, 2, 2)
    ax_max_nei[0] = fig_waveforms.add_subplot(4, 2, 3)
    ax_min_nei[0] = fig_waveforms.add_subplot(4, 2, 4)
    ax_max_nei[1] = fig_waveforms.add_subplot(4, 2, 5)
    ax_min_nei[1] = fig_waveforms.add_subplot(4, 2, 6)
    ax_max_nei[2] = fig_waveforms.add_subplot(4, 2, 7)
    ax_min_nei[2] = fig_waveforms.add_subplot(4, 2, 8)

    ax_img_nei = fig_camera.add_subplot(2, 2, 1)
    ax_img_max = fig_camera.add_subplot(2, 2, 2)
    ax_img_true = fig_camera.add_subplot(2, 2, 3)
    ax_img_cal = fig_camera.add_subplot(2, 2, 4)

    plotter = CameraPlotter(event, geom_dict)

    # Draw max pixel traces
    plotter.draw_waveform(data_ped[max_pixel], ax_max_pix)
    ax_max_pix.set_title("(Max) Pixel: {}, "
                         "True: {}, "
                         "Measured = {:.3f}".format(max_pixel,
                                                    true_pe[max_pixel],
                                                    measured_pe[max_pixel]))
    ax_max_pix.set_ylabel("Amplitude-Ped (ADC)")
    max_ylim = ax_max_pix.get_ylim()
    plotter.draw_waveform_positionline(start[max_pixel], ax_max_pix)
    plotter.draw_waveform_positionline(end[max_pixel], ax_max_pix)
    for i, ax in ax_max_nei.items():
        if len(max_pixel_nei) > i:
            pix = max_pixel_nei[i]
            plotter.draw_waveform(data_ped[pix], ax)
            ax.set_title("(Max Nei) Pixel: {}, "
                         "True: {}, "
                         "Measured = {:.3f}".format(pix, true_pe[pix],
                                                    measured_pe[pix]))
            ax.set_ylabel("Amplitude-Ped (ADC)")
            ax.set_ylim(max_ylim)
            plotter.draw_waveform_positionline(start[pix], ax)
            plotter.draw_waveform_positionline(end[pix], ax)

    # Draw min pixel traces
    plotter.draw_waveform(data_ped[min_pixel], ax_min_pix)
    ax_min_pix.set_title("(Min) Pixel: {}, "
                         "True: {}, "
                         "Measured = {:.3f}".format(min_pixel,
                                                    true_pe[min_pixel],
                                                    measured_pe[min_pixel]))
    ax_min_pix.set_ylabel("Amplitude-Ped (ADC)")
    ax_min_pix.set_ylim(max_ylim)
    plotter.draw_waveform_positionline(start[min_pixel], ax_min_pix)
    plotter.draw_waveform_positionline(end[min_pixel], ax_min_pix)
    for i, ax in ax_min_nei.items():
        if len(min_pixel_nei) > i:
            pix = min_pixel_nei[i]
            plotter.draw_waveform(data_ped[pix], ax)
            ax.set_title("(Min Nei) Pixel: {}, "
                         "True: {}, "
                         "Measured = {:.3f}".format(pix, true_pe[pix],
                                                    measured_pe[pix]))
            ax.set_ylabel("Amplitude-Ped (ADC)")
            ax.set_ylim(max_ylim)
            plotter.draw_waveform_positionline(start[pix], ax)
            plotter.draw_waveform_positionline(end[pix], ax)

    # Draw cameras
    nei_camera = np.zeros_like(max_charges, dtype=np.int)
    nei_camera[min_pixel_nei] = 2
    nei_camera[min_pixel] = 1
    nei_camera[max_pixel_nei] = 3
    nei_camera[max_pixel] = 4
    camera = plotter.draw_camera(telid, nei_camera, ax_img_nei)
    camera.cmap = plt.cm.viridis
    ax_img_nei.set_title("Neighbour Map")
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_nei)

    camera = plotter.draw_camera(telid, data_ped[:, max_time], ax_img_max)
    camera.add_colorbar(ax=ax_img_max, label="Amplitude-Ped (ADC)")
    ax_img_max.set_title("Max Timeslice (T = {})".format(max_time))
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_max)

    camera = plotter.draw_camera(telid, true_pe, ax_img_true)
    camera.add_colorbar(ax=ax_img_true, label="True Charge (Photo-electrons)")
    ax_img_true.set_title("True Charge")
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_true)

    int_dict, inverted = integrator_dict()
    integrator_name = '' if 'integrator' not in params else \
        params['integrator']

    camera = plotter.draw_camera(telid, measured_pe, ax_img_cal)
    camera.add_colorbar(ax=ax_img_cal, label="Calib Charge (Photo-electrons)")
    ax_img_cal.set_title("Charge (integrator={})".format(integrator_name))
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_cal)

    fig_waveforms.suptitle("Integrator = {}".format(integrator_name))
    fig_camera.suptitle("Camera = {}".format(geom.cam_id))

    waveform_output_name = "{}_e{}_t{}_c{}_integrator{}_waveform.pdf"\
        .format(input_file.filename, event.count, telid, chan,
                inverted[params['integrator']])
    camera_output_name = "{}_e{}_t{}_c{}_integrator{}_camera.pdf"\
        .format(input_file.filename, event.count, telid, chan,
                inverted[params['integrator']])
    output_dir = args.output_dir if args.output_dir is not None else \
        input_file.output_directory
    output_dir = os.path.join(output_dir, script)
    if not os.path.exists(output_dir):
        log.info("[output] Creating directory: {}".format(output_dir))
        os.makedirs(output_dir)

    waveform_output_path = os.path.join(output_dir, waveform_output_name)
    log.info("[output] {}".format(waveform_output_path))
    fig_waveforms.savefig(waveform_output_path,
                          format='pdf',
                          bbox_inches='tight')

    camera_output_path = os.path.join(output_dir, camera_output_name)
    log.info("[output] {}".format(camera_output_path))
    fig_camera.savefig(camera_output_path, format='pdf', bbox_inches='tight')

    log.info("[COMPLETE]")
def plot_muon_event(event, muonparams, args=None):

    if muonparams['MuonRingParams'] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))

        colorbar = None
        colorbar2 = None

        #for tel_id in event.dl0.tels_with_data:
        for tel_id in muonparams['TelIds']:
            idx = muonparams['TelIds'].index(tel_id)

            if not muonparams['MuonRingParams'][idx]:
                continue

            #otherwise...
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event)
            image = event.dl1.tel[tel_id].image[0]
            geom = event.inst.subarray.tel[tel_id].camera

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            clean_mask = tailcuts_clean(geom, image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(muonparams['MuonRingParams'][idx].ring_center_x**2. +
                                muonparams['MuonRingParams'][idx].ring_center_y**2.)

            muon_phi = np.arctan(muonparams['MuonRingParams'][idx].ring_center_y /
                                 muonparams['MuonRingParams'][idx].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(x=muonparams['MuonRingParams'][idx].ring_center_x,
                                        y=muonparams['MuonRingParams'][idx].ring_center_y,
                                        array_direction=altaz,
                                        pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(CameraFrame(
                pointing_direction=altaz,
                focal_length=event.inst.optical_foclen[tel_id],
                rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams['MuonRingParams'][idx].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px, y=py,
                                       z=np.zeros(px.shape) * u.m,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz,
                             pointing_direction=altaz)
            )

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(np.power( px - muonparams['MuonRingParams'][idx].ring_center_x, 2)
                           + np.power(py - muonparams['MuonRingParams'][idx].ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams['MuonRingParams'][idx].ring_radius)
            pixRmask = ring_dist < muonparams['MuonRingParams'][idx].ring_radius * 0.4

            #if muonparams[1] is not None:
            if muonparams['MuonIntensityParams'][idx] is not None:
                signals *= muonparams['MuonIntensityParams'][idx].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            cmin = min(signals)
            if not cmin:
                cmin = 1.
            if not cmaxmin:
                cmaxmin = 1.

            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(cmin) / cmaxmin, 'black'),
                           (2.0 * np.abs(cmin) / cmaxmin, 'blue'),
                           (2.5 * np.abs(cmin) / cmaxmin, 'green'),
                           (1, 'yellow')]
            )
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid, ringrad_camcoord.value,
                                ringrad_camcoord.value, 0., 0., color="red")


            if muonparams['MuonIntensityParams'][idx] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)

                ringwidthfrac = muonparams['MuonIntensityParams'][idx].ring_width / muonparams['MuonRingParams'][idx].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid, ringrad_inner.value,
                                     ringrad_inner.value, 0., 0.,
                                     color="magenta")
                camera1.add_ellipse(centroid, ringrad_outer.value,
                                    ringrad_outer.value, 0., 0., color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams['MuonIntensityParams'][idx].prediction


                if len(pred) != np.sum(muonparams['MuonIntensityParams'][idx].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=", np.sum(muonparams['MuonIntensityParams'][idx].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams['MuonIntensityParams'][idx].mask == True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                if np.isnan(max(plotpred)) or np.isnan(min(plotpred)):
                    print("nan prediction, skipping...")
                    continue

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.

                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c', [(0 / c2maxmin, 'darkblue'),
                                (np.abs(min(plotpred)) / c2maxmin, 'black'),
                                (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                                (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                                (1, 'yellow')]
                )
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter


            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            #fig.savefig(str(args.output_path) + "_" +
            #            str(event.dl0.event_id) + '.png')


            plt.close()
def display_telescope(event, tel_id, display, geom_dict, pp, fig):
    fig.clear()

    cam_dimensions = (event.dl0.tel[tel_id].num_pixels,
                      event.meta.optical_foclen[tel_id])

    fig.suptitle("EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}"
                 .format(event.dl1.event_id, event.mc.energy,
                         event.mc.alt,
                         event.mc.az,
                         np.sqrt(pow(event.mc.core_x, 2) +
                                 pow(event.mc.core_y, 2))))

    # Select number of pads to display (will depend on the integrator):
    # charge and/or time of maximum.
    # This last one is displayed only if the integrator calculates it
    npads = 1
    if not event.dl1.tel[tel_id].peakpos[0] is None:
        npads = 2
    # Only create two pads if there is timing information extracted
    # from the calibration
    ax1 = fig.add_subplot(1, npads, 1)

    # If the geometery has not already been added to geom_dict, it will
    # be added in CameraPlotter
    plotter = CameraPlotter(event, geom_dict)
    signals = event.dl1.tel[tel_id].pe_charge
    camera1 = plotter.draw_camera(tel_id, signals, ax1)
    cmaxmin = (max(signals) - min(signals))
    cmap_charge = colors.LinearSegmentedColormap.from_list(
        'cmap_c', [(0 / cmaxmin, 'darkblue'),
                   (np.abs(min(signals)) / cmaxmin, 'black'),
                   (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                   (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                   (1, 'yellow')])
    camera1.pixels.set_cmap(cmap_charge)
    camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
    ax1.set_title("CT {} ({}) - Mean pixel charge"
                  .format(tel_id, geom_dict[cam_dimensions].cam_id))
    if not event.dl1.tel[tel_id].peakpos[0] is None:
        ax2 = fig.add_subplot(1, npads, npads)
        times = event.dl1.tel[tel_id].peakpos
        camera2 = plotter.draw_camera(tel_id, times, ax2)
        tmaxmin = event.dl0.tel[tel_id].num_samples
        t_chargemax = times[signals.argmax()]
        if t_chargemax > 15:
            t_chargemax = 7
        cmap_time = colors.LinearSegmentedColormap.from_list(
            'cmap_t', [(0 / tmaxmin, 'darkgreen'),
                       (0.6 * t_chargemax / tmaxmin, 'green'),
                       (t_chargemax / tmaxmin, 'yellow'),
                       (1.4 * t_chargemax / tmaxmin, 'blue'),
                       (1, 'darkblue')])
        camera2.pixels.set_cmap(cmap_time)
        camera2.add_colorbar(ax=ax2, label="[time slice]")
        ax2.set_title("CT {} ({}) - Pixel peak position"
                      .format(tel_id, geom_dict[cam_dimensions].cam_id))

    if display:
        plt.pause(0.1)
    if pp is not None:
        pp.savefig(fig)
def main():
    script = os.path.splitext(os.path.basename(__file__))[0]
    log.info("[SCRIPT] {}".format(script))

    parser = argparse.ArgumentParser(description='Create a gif of an event')
    parser.add_argument('-f', '--file', dest='input_path', action='store',
                        required=True, help='path to the input file')
    parser.add_argument('-O', '--origin', dest='origin', action='store',
                        required=True, help='origin of the file: {}'
                        .format(origin_list()))
    parser.add_argument('-o', '--output', dest='output_dir', action='store',
                        default=None,
                        help='path of the output directory to store the '
                             'images (default = input file directory)')
    parser.add_argument('-e', '--event', dest='event_req', action='store',
                        required=True, type=int,
                        help='event index to plot (not id!)')
    parser.add_argument('--id', dest='event_id_f', action='store_true',
                        default=False, help='-e will specify event_id instead '
                                            'of index')
    parser.add_argument('-t', '--telescope', dest='tel', action='store',
                        type=int, default=None, help='telecope to view')
    parser.add_argument('-c', '--channel', dest='chan', action='store',
                        type=int, default=0,
                        help='channel to view (default = 0 (HG))')

    calibration_arguments(parser)

    logger_detail = parser.add_mutually_exclusive_group()
    logger_detail.add_argument('-q', '--quiet', dest='quiet',
                               action='store_true', default=False,
                               help='Quiet mode')
    logger_detail.add_argument('-v', '--verbose', dest='verbose',
                               action='store_true', default=False,
                               help='Verbose mode')
    logger_detail.add_argument('-d', '--debug', dest='debug',
                               action='store_true', default=False,
                               help='Debug mode')

    args = parser.parse_args()

    if args.quiet:
        log.setLevel(40)
    if args.verbose:
        log.setLevel(20)
    if args.debug:
        log.setLevel(10)

    telid = args.tel
    chan = args.chan

    log.debug("[file] Reading file")
    input_file = InputFile(args.input_path, args.origin)
    event = input_file.get_event(args.event_req, args.event_id_f)

    # Print event/args values
    log.info("[event_index] {}".format(event.count))
    log.info("[event_id] {}".format(event.dl0.event_id))
    log.info("[telescope] {}".format(telid))
    log.info("[channel] {}".format(chan))

    params = calibration_parameters(args)

    # Create a dictionary to store any geoms in
    geom = CameraGeometry.guess(*event.meta.pixel_pos[telid],
                                event.meta.optical_foclen[telid])
    geom_dict = {telid: geom}
    calibrated_event = calibrate_event(event, params, geom_dict)

    # Select telescope
    tels = list(calibrated_event.dl0.tels_with_data)
    if telid is None or telid not in tels:
        log.error("[event] please specify one of the following telescopes "
                  "for this event: {}".format(tels))
        exit()

    # Extract required images
    data_ped = calibrated_event.dl1.tel[telid].pedestal_subtracted_adc[chan]
    true_pe = calibrated_event.mc.tel[telid].photo_electrons
    measured_pe = calibrated_event.dl1.tel[telid].pe_charge
    max_time = np.unravel_index(np.argmax(data_ped), data_ped.shape)[1]
    max_charges = np.max(data_ped, axis=1)
    max_pixel = int(np.argmax(max_charges))
    min_pixel = int(np.argmin(max_charges))

    # Get Neighbours
    max_pixel_nei = geom.neighbors[max_pixel]
    min_pixel_nei = geom.neighbors[min_pixel]

    # Get Windows
    windows = calibrated_event.dl1.tel[telid].integration_window[chan]
    length = np.sum(windows, axis=1)
    start = np.argmax(windows, axis=1)
    end = start + length - 1

    # Draw figures
    ax_max_nei = {}
    ax_min_nei = {}
    fig_waveforms = plt.figure(figsize=(24, 10))
    fig_waveforms.subplots_adjust(hspace=.5)
    fig_camera = plt.figure(figsize=(30, 24))

    ax_max_pix = fig_waveforms.add_subplot(4, 2, 1)
    ax_min_pix = fig_waveforms.add_subplot(4, 2, 2)
    ax_max_nei[0] = fig_waveforms.add_subplot(4, 2, 3)
    ax_min_nei[0] = fig_waveforms.add_subplot(4, 2, 4)
    ax_max_nei[1] = fig_waveforms.add_subplot(4, 2, 5)
    ax_min_nei[1] = fig_waveforms.add_subplot(4, 2, 6)
    ax_max_nei[2] = fig_waveforms.add_subplot(4, 2, 7)
    ax_min_nei[2] = fig_waveforms.add_subplot(4, 2, 8)

    ax_img_nei = fig_camera.add_subplot(2, 2, 1)
    ax_img_max = fig_camera.add_subplot(2, 2, 2)
    ax_img_true = fig_camera.add_subplot(2, 2, 3)
    ax_img_cal = fig_camera.add_subplot(2, 2, 4)

    plotter = CameraPlotter(event, geom_dict)

    # Draw max pixel traces
    plotter.draw_waveform(data_ped[max_pixel], ax_max_pix)
    ax_max_pix.set_title("(Max) Pixel: {}, "
                         "True: {}, "
                         "Measured = {}".format(max_pixel, true_pe[max_pixel],
                                                measured_pe[max_pixel]))
    ax_max_pix.set_ylabel("Amplitude-Ped (ADC)")
    max_ylim = ax_max_pix.get_ylim()
    plotter.draw_waveform_positionline(start[max_pixel], ax_max_pix)
    plotter.draw_waveform_positionline(end[max_pixel], ax_max_pix)
    for i, ax in ax_max_nei.items():
        if len(max_pixel_nei) > i:
            pix = max_pixel_nei[i]
            plotter.draw_waveform(data_ped[pix], ax)
            ax.set_title("(Max Nei) Pixel: {}, "
                         "True: {}, "
                         "Measured = {}".format(pix, true_pe[pix],
                                                measured_pe[pix]))
            ax.set_ylabel("Amplitude-Ped (ADC)")
            ax.set_ylim(max_ylim)
            plotter.draw_waveform_positionline(start[pix], ax)
            plotter.draw_waveform_positionline(end[pix], ax)

    # Draw min pixel traces
    plotter.draw_waveform(data_ped[min_pixel], ax_min_pix)
    ax_min_pix.set_title("(Min) Pixel: {}, "
                         "True: {}, "
                         "Measured = {}".format(min_pixel, true_pe[min_pixel],
                                                measured_pe[min_pixel]))
    ax_min_pix.set_ylabel("Amplitude-Ped (ADC)")
    ax_min_pix.set_ylim(max_ylim)
    plotter.draw_waveform_positionline(start[min_pixel], ax_min_pix)
    plotter.draw_waveform_positionline(end[min_pixel], ax_min_pix)
    for i, ax in ax_min_nei.items():
        if len(min_pixel_nei) > i:
            pix = min_pixel_nei[i]
            plotter.draw_waveform(data_ped[pix], ax)
            ax.set_title("(Min Nei) Pixel: {}, "
                         "True: {}, "
                         "Measured = {}".format(pix, true_pe[pix],
                                                measured_pe[pix]))
            ax.set_ylabel("Amplitude-Ped (ADC)")
            ax.set_ylim(max_ylim)
            plotter.draw_waveform_positionline(start[pix], ax)
            plotter.draw_waveform_positionline(end[pix], ax)

    # Draw cameras
    nei_camera = np.zeros_like(max_charges, dtype=np.int)
    nei_camera[min_pixel_nei] = 2
    nei_camera[min_pixel] = 1
    nei_camera[max_pixel_nei] = 3
    nei_camera[max_pixel] = 4
    camera = plotter.draw_camera(telid, nei_camera, ax_img_nei)
    camera.cmap = plt.cm.viridis
    ax_img_nei.set_title("Neighbour Map")
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_nei)

    camera = plotter.draw_camera(telid, data_ped[:, max_time], ax_img_max)
    camera.add_colorbar(ax=ax_img_max, label="Amplitude-Ped (ADC)")
    ax_img_max.set_title("Max Timeslice (T = {})".format(max_time))
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_max)

    camera = plotter.draw_camera(telid, true_pe, ax_img_true)
    camera.add_colorbar(ax=ax_img_true, label="True Charge (Photo-electrons)")
    ax_img_true.set_title("True Charge")
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_true)

    camera = plotter.draw_camera(telid, measured_pe, ax_img_cal)
    camera.add_colorbar(ax=ax_img_cal, label="Calib Charge (Photo-electrons)")
    ax_img_cal.set_title("Charge (integrator={})".format(params['integrator']))
    plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel,
                                         ax_img_cal)

    fig_waveforms.suptitle("Integrator = {}".format(params['integrator']))
    fig_camera.suptitle("Camera = {}".format(geom.cam_id))

    # TODO: another figure of all waveforms that have non-zero true charge

    waveform_output_name = "{}_e{}_t{}_c{}_integrator{}_waveform.pdf"\
        .format(input_file.filename, event.count, telid, chan, args.integrator)
    camera_output_name = "{}_e{}_t{}_c{}_integrator{}_camera.pdf"\
        .format(input_file.filename, event.count, telid, chan, args.integrator)
    output_dir = args.output_dir if args.output_dir is not None else \
        input_file.output_directory
    output_dir = os.path.join(output_dir, script)
    if not os.path.exists(output_dir):
        log.info("[output] Creating directory: {}".format(output_dir))
        os.makedirs(output_dir)

    waveform_output_path = os.path.join(output_dir, waveform_output_name)
    log.info("[output] {}".format(waveform_output_path))
    fig_waveforms.savefig(waveform_output_path, format='pdf')

    camera_output_path = os.path.join(output_dir, camera_output_name)
    log.info("[output] {}".format(camera_output_path))
    fig_camera.savefig(camera_output_path, format='pdf')

    log.info("[COMPLETE]")
def plot_muon_event(event, muonparams, geom_dict=None, args=None):

    if muonparams[0] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))
        # if args.display:
        #    plt.show(block=False)
        #pp = PdfPages(args.output_path) if args.output_path is not None else None
        # pp = None #For now, need to correct this

        colorbar = None
        colorbar2 = None

        for tel_id in event.dl0.tels_with_data:
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event, geom_dict)
            #image = event.dl1.tel[tel_id].calibrated_image
            image = event.dl1.tel[tel_id].image[0]
            # Get geometry
            geom = None
            if geom_dict is not None and tel_id in geom_dict:
                geom = geom_dict[tel_id]
            else:
                #log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.inst.pixel_pos[tel_id],
                                            event.inst.optical_foclen[tel_id])
                #log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[tel_id] = geom

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            #print("Using Tail Cuts:",tailcuts)
            clean_mask = tailcuts_clean(geom,
                                        image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(muonparams[0].ring_center_x**2. +
                                muonparams[0].ring_center_y**2.)

            muon_phi = np.arctan(muonparams[0].ring_center_y /
                                 muonparams[0].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(x=muonparams[0].ring_center_x,
                                        y=muonparams[0].ring_center_y,
                                        array_direction=altaz,
                                        pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(
                CameraFrame(pointing_direction=altaz,
                            focal_length=event.inst.optical_foclen[tel_id],
                            rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams[0].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            #rot_angle = 0.*u.deg
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and event.dl0.tel[tel_id].num_pixels != 1764:
            #rot_angle = -100.14*u.deg

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px,
                                       y=py,
                                       z=np.zeros(px.shape) * u.m,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz, pointing_direction=altaz))
            #,focal_length = event.inst.optical_foclen[tel_id])) # tel['TelescopeTable_VersionFeb2016'][tel['TelescopeTable_VersionFeb2016']['TelID']==telid]['FL'][0]*u.m))

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(
                np.power(px - muonparams[0].ring_center_x, 2) +
                np.power(py - muonparams[0].ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams[0].ring_radius)
            pixRmask = ring_dist < muonparams[0].ring_radius * 0.4

            if muonparams[1] is not None:
                signals *= muonparams[1].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            if not cmaxmin:
                cmaxmin = 1.
            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(min(signals)) / cmaxmin, 'black'),
                           (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                           (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                           (1, 'yellow')])
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid,
                                ringrad_camcoord.value,
                                ringrad_camcoord.value,
                                0.,
                                0.,
                                color="red")

            #            ax1.set_title("CT {} ({}) - Mean pixel charge"
            #                          .format(tel_id, geom_dict[tel_id].cam_id))

            if muonparams[1] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)
                ringwidthfrac = muonparams[1].ring_width / muonparams[
                    0].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid,
                                    ringrad_inner.value,
                                    ringrad_inner.value,
                                    0.,
                                    0.,
                                    color="magenta")
                camera1.add_ellipse(centroid,
                                    ringrad_outer.value,
                                    ringrad_outer.value,
                                    0.,
                                    0.,
                                    color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams[1].prediction

                if len(pred) != np.sum(muonparams[1].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=", np.sum(muonparams[1].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams[1].mask == True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.
                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c',
                    [(0 / c2maxmin, 'darkblue'),
                     (np.abs(min(plotpred)) / c2maxmin, 'black'),
                     (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                     (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                     (1, 'yellow')])
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            fig.savefig(
                str(args.output_path) + "_" + str(event.dl0.event_id) + '.png')

            plt.close()