예제 #1
0
class CameraDemo(Tool):

    name = u"ctapipe-camdemo"
    description = "Display fake events in a demo camera"

    delay = traits.Int(50, help="Frame delay in ms", min=20).tag(config=True)
    cleanframes = traits.Int(100,
                             help="Number of frames between turning on "
                             "cleaning",
                             min=0).tag(config=True)
    autoscale = traits.Bool(False, help='scale each frame to max if '
                            'True').tag(config=True)
    blit = traits.Bool(False,
                       help='use blit operation to draw on screen ('
                       'much faster but may cause some draw '
                       'artifacts)').tag(config=True)
    camera = traits.CaselessStrEnum(
        CameraGeometry.get_known_camera_names(),
        default_value='NectarCam',
        help='Name of camera to display').tag(config=True)

    optics = traits.CaselessStrEnum(
        OpticsDescription.get_known_optics_names(),
        default_value='MST',
        help='Telescope optics description name').tag(config=True)

    aliases = traits.Dict({
        'delay': 'CameraDemo.delay',
        'cleanframes': 'CameraDemo.cleanframes',
        'autoscale': 'CameraDemo.autoscale',
        'blit': 'CameraDemo.blit',
        'camera': 'CameraDemo.camera',
        'optics': 'CameraDemo.optics',
    })

    def __init__(self):
        super().__init__()
        self._counter = 0
        self.imclean = False

    def start(self):
        self.log.info("Starting CameraDisplay for {}".format(self.camera))
        self._display_camera_animation()

    def _display_camera_animation(self):
        # plt.style.use("ggplot")
        fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7))
        ax = plt.subplot(111)

        # load the camera
        tel = TelescopeDescription.from_name(optics_name=self.optics,
                                             camera_name=self.camera)
        geom = tel.camera

        # poor-man's coordinate transform from telscope to camera frame (it's
        # better to use ctapipe.coordiantes when they are stable)
        scale = tel.optics.effective_focal_length.to(geom.pix_x.unit).value
        fov = np.deg2rad(4.0)
        maxwid = np.deg2rad(0.01)
        maxlen = np.deg2rad(0.03)

        disp = CameraDisplay(geom,
                             ax=ax,
                             autoupdate=True,
                             title="{}, f={}".format(
                                 tel, tel.optics.effective_focal_length))
        disp.cmap = plt.cm.terrain

        def update(frame):

            centroid = np.random.uniform(-fov, fov, size=2) * scale
            width = np.random.uniform(0, maxwid) * scale
            length = np.random.uniform(0, maxlen) * scale + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 50
            model = toymodel.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            image, sig, bg = toymodel.make_toymodel_shower_image(
                geom, model.pdf, intensity=intens, nsb_level_pe=5000)

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes * 2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image / 80.0)
                for ii in range(3):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels

            self.log.debug("count = {}, image sum={} max={}".format(
                self._counter, image.sum(), image.max()))
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-100, 4000)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [
                ax,
            ]

        self.anim = FuncAnimation(fig,
                                  update,
                                  interval=self.delay,
                                  blit=self.blit)
        plt.show()
예제 #2
0
class CameraDemo(Tool):

    name = u"ctapipe-camdemo"
    description = "Display fake events in a demo camera"

    delay = traits.Int(20, help="Frame delay in ms").tag(config=True)
    cleanframes = traits.Int(100, help="Number of frames between turning on "
                                      "cleaning").tag(config=True)
    autoscale = traits.Bool(False, help='scale each frame to max if '
                                        'True').tag(config=True)
    blit = traits.Bool(False, help='use blit operation to draw on screen ('
                                   'much faster but may cause some draw '
                                   'artifacts)').tag(config=True)

    aliases = traits.Dict({'delay': 'CameraDemo.delay',
                           'cleanframes': 'CameraDemo.cleanframes',
                           'autoscale' : 'CameraDemo.autoscale',
                           'blit': 'CameraDemo.blit'})


    def __init__(self):
        super().__init__()
        self._counter = 0
        self.imclean = False

    def start(self):
        self.log.info("Starting Camera Display")
        self._display_camera_animation()

    def _display_camera_animation(self):
        #plt.style.use("ggplot")
        fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7))
        ax = plt.subplot(111)

        # load the camera
        geom = io.CameraGeometry.from_name("hess", 1)
        disp = visualization.CameraDisplay(geom, ax=ax, autoupdate=True)
        disp.cmap = plt.cm.terrain

        def update(frame):

            centroid = np.random.uniform(-0.5, 0.5, size=2)
            width = np.random.uniform(0, 0.01)
            length = np.random.uniform(0, 0.03) + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 50
            model = toymodel.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            image, sig, bg = toymodel.make_toymodel_shower_image(geom, model.pdf,
                                                                 intensity=intens,
                                                                 nsb_level_pe=5000)

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes*2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0

            if self.imclean:
                cleanmask = cleaning.tailcuts_clean(geom, image, pedvars=80)
                for ii in range(3):
                    cleaning.dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels

            self.log.debug("count = {}, image sum={} max={}"
                .format(self._counter, image.sum(), image.max()))
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-100, 4000)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [ax,]

        self.anim = FuncAnimation(fig, update, interval=self.delay,
                                  blit=self.blit)
        plt.show()
예제 #3
0
class MuonDisplayerTool(Tool):
    name = 'ctapipe-display-muons'
    description = t.Unicode(__doc__)

    events = t.Unicode("",
                       help="input event data file").tag(config=True)

    outfile = t.Unicode("muons.hdf5", help='HDF5 output file name').tag(
        config=True)

    display = t.Bool(
        help='display the camera events', default=False
    ).tag(config=True)

    classes = t.List([
        CameraCalibrator, EventSource
    ])

    aliases = t.Dict({
        'input': 'MuonDisplayerTool.events',
        'outfile': 'MuonDisplayerTool.outfile',
        'display': 'MuonDisplayerTool.display',
        'max_events': 'EventSource.max_events',
        'allowed_tels': 'EventSource.allowed_tels',
    })

    def setup(self):
        if self.events == '':
            raise ToolConfigurationError("please specify --input <events file>")
        self.log.debug("input: %s", self.events)
        self.source = event_source(self.events)
        self.calib = CameraCalibrator(
            config=self.config, tool=self, eventsource=self.source
        )
        self.writer = HDF5TableWriter(self.outfile, "muons")

    def start(self):

        numev = 0
        self.num_muons_found = defaultdict(int)

        for event in tqdm(self.source, desc='detecting muons'):

            self.calib.calibrate(event)
            muon_evt = analyze_muon_event(event)

            if numev == 0:
                _exclude_some_columns(event.inst.subarray, self.writer)

            numev += 1

            if not muon_evt['MuonIntensityParams']:
                # No telescopes  contained a good muon
                continue
            else:
                if self.display:
                    plot_muon_event(event, muon_evt)

                for tel_id in muon_evt['TelIds']:
                    idx = muon_evt['TelIds'].index(tel_id)
                    intens_params = muon_evt['MuonIntensityParams'][idx]

                    if intens_params is not None:
                        ring_params = muon_evt['MuonRingParams'][idx]
                        cam_id = str(event.inst.subarray.tel[tel_id].camera)
                        self.num_muons_found[cam_id] += 1
                        self.log.debug("INTENSITY: %s", intens_params)
                        self.log.debug("RING: %s", ring_params)
                        self.writer.write(table_name=cam_id,
                                          containers=[intens_params,
                                                      ring_params])

                self.log.info(
                    "Event Number: %d, found %s muons",
                    numev, dict(self.num_muons_found)
                )

    def finish(self):
        Provenance().add_output_file(self.outfile,
                                     role='dl1.tel.evt.muon')
        self.writer.close()
예제 #4
0
class CameraDemo(Tool):
    name = "ctapipe-camdemo"
    description = "Display fake events in a demo camera"

    delay = traits.Int(50, help="Frame delay in ms", min=20).tag(config=True)
    cleanframes = traits.Int(20, help="Number of frames between turning on "
                                       "cleaning", min=0).tag(config=True)
    autoscale = traits.Bool(False, help='scale each frame to max if '
                                        'True').tag(config=True)
    blit = traits.Bool(False, help='use blit operation to draw on screen ('
                                   'much faster but may cause some draw '
                                   'artifacts)').tag(config=True)
    camera = traits.CaselessStrEnum(
        CameraDescription.get_known_camera_names(),
        default_value='NectarCam',
        help='Name of camera to display').tag(config=True)

    optics = traits.CaselessStrEnum(
        OpticsDescription.get_known_optics_names(),
        default_value='MST',
        help='Telescope optics description name'
    ).tag(config=True)

    num_events = traits.Int(0, help='events to show before exiting (0 for '
                                    'unlimited)').tag(config=True)

    display = traits.Bool(True, "enable or disable display (for "
                                "testing)").tag(config=True)

    aliases = traits.Dict({
        'delay': 'CameraDemo.delay',
        'cleanframes': 'CameraDemo.cleanframes',
        'autoscale': 'CameraDemo.autoscale',
        'blit': 'CameraDemo.blit',
        'camera': 'CameraDemo.camera',
        'optics': 'CameraDemo.optics',
        'num-events': 'CameraDemo.num_events'
    })

    def __init__(self):
        super().__init__()
        self._counter = 0
        self.imclean = False

    def start(self):
        self.log.info(f"Starting CameraDisplay for {self.camera}")
        self._display_camera_animation()

    def _display_camera_animation(self):
        # plt.style.use("ggplot")
        fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7))
        ax = plt.subplot(111)

        # load the camera
        tel = TelescopeDescription.from_name(optics_name=self.optics,
                                             camera_name=self.camera)
        geom = tel.camera.geometry

        # poor-man's coordinate transform from telscope to camera frame (it's
        # better to use ctapipe.coordiantes when they are stable)
        foclen = tel.optics.equivalent_focal_length.to(geom.pix_x.unit).value
        fov = np.deg2rad(4.0)
        scale = foclen
        minwid = np.deg2rad(0.1)
        maxwid = np.deg2rad(0.3)
        maxlen = np.deg2rad(0.5)

        self.log.debug(f"scale={scale} m, wid=({minwid}-{maxwid})")

        disp = CameraDisplay(
            geom, ax=ax, autoupdate=True,
            title=f"{tel}, f={tel.optics.equivalent_focal_length}"
        )
        disp.cmap = plt.cm.terrain

        def update(frame):
            x, y = np.random.uniform(-fov, fov, size=2) * scale
            width = np.random.uniform(0, maxwid - minwid) * scale + minwid
            length = np.random.uniform(0, maxlen) * scale + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 500
            model = toymodel.Gaussian(
                x=x * u.m,
                y=y * u.m,
                width=width * u.m,
                length=length * u.m,
                psi=angle * u.deg,
            )
            self.log.debug(
                "Frame=%d width=%03f length=%03f intens=%03d",
                frame, width, length, intens
            )

            image, _, _ = model.generate_image(
                geom,
                intensity=intens,
                nsb_level_pe=3,
            )

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes * 2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0
                disp.clear_overlays()

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image,
                                           picture_thresh=10.0,
                                           boundary_thresh=5.0)
                for ii in range(2):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels
                try:
                    hillas = hillas_parameters(geom, image)
                    disp.overlay_moments(hillas, with_label=False,
                                         color='red', alpha=0.7,
                                         linewidth=2, linestyle='dashed')
                except HillasParameterizationError:
                    disp.clear_overlays()
                    pass

            self.log.debug("Frame=%d  image_sum=%.3f max=%.3f",
                           self._counter, image.sum(), image.max())
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-5, 200)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [ax, ]

        frames = None if self.num_events == 0 else self.num_events
        repeat = True if self.num_events == 0 else False

        self.log.info(f"Running for {frames} frames")
        self.anim = FuncAnimation(fig, update,
                                  interval=self.delay,
                                  frames=frames,
                                  repeat=repeat,
                                  blit=self.blit)

        if self.display:
            plt.show()
예제 #5
0
class MuonDisplayerTool(Tool):
    name = 'ctapipe-display-muons'
    description = t.Unicode(__doc__)

    infile = t.Unicode(
        help='input file name',
        default=get_dataset('gamma_test_large.simtel.gz')
    ).tag(config=True)

    outfile = t.Unicode(help='output file name',
                        default=None).tag(config=True)

    display = t.Bool(
        help='display the camera events', default=False
    ).tag(config=True)

    classes = t.List([CameraCalibrator,])

    aliases = t.Dict({'infile': 'MuonDisplayerTool.infile',
                      'outfile': 'MuonDisplayerTool.outfile',
                      'display' : 'MuonDisplayerTool.display'
                      })


    def setup(self):
        self.calib = CameraCalibrator(config=self.config, tool=self)

    def start(self):

        output_parameters = {'MuonEff': [],
                             'ImpactP': [],
                             'RingWidth': []}

        numev = 0
        num_muons_found = 0

        for event in hessio_event_source(self.infile):
            self.log.info("Event Number: %d, found %d muons", numev, num_muons_found)

            self.calib.calibrate(event)
            muon_evt = analyze_muon_event(event)

            numev += 1

            if not muon_evt['MuonIntensityParams']:  # No telescopes contained a good muon
                continue
            else:
                if self.display:
                    plot_muon_event(event, muon_evt)

                for tid in muon_evt['TelIds']:
                    idx = muon_evt['TelIds'].index(tid)
                    if not muon_evt['MuonIntensityParams'][idx]:
                        continue

                    self.log.info("** Muon params: %s", muon_evt[idx])

                    output_parameters['MuonEff'].append(
                        muon_evt['MuonIntensityParams'][idx].optical_efficiency_muon
                    )
                    output_parameters['ImpactP'].append(
                        muon_evt['MuonIntensityParams'][idx].impact_parameter.value
                    )
                    output_parameters['RingWidth'].append(
                        muon_evt['MuonIntensityParams'][idx].ring_width.value
                    )

                    print_muon(muon_evt, printer=self.log.info)
                    num_muons_found += 1



        t = Table(output_parameters)
        t['ImpactP'].unit = 'm'
        t['RingWidth'].unit = 'deg'
        if self.outfile:
            t.write(self.outfile)
예제 #6
0
class MuonDisplayerTool(Tool):
    name = 'ctapipe-display-muons'
    description = t.Unicode(__doc__)

    infile = t.Unicode(
        help='input file name',
        default=get_dataset('gamma_test_large.simtel.gz')).tag(config=True)

    outfile = t.Unicode(help='output file name', default=None).tag(config=True)

    display = t.Bool(help='display the camera events',
                     default=False).tag(config=True)

    classes = t.List([
        CameraCalibrator,
    ])

    aliases = t.Dict({
        'infile': 'MuonDisplayerTool.infile',
        'outfile': 'MuonDisplayerTool.outfile',
        'display': 'MuonDisplayerTool.display'
    })

    def setup(self):
        self.calib = CameraCalibrator()

    def start(self):

        output_parameters = {
            'MuonEff': [],
            'ImpactP': [],
            'RingWidth': [],
            'RingCont': [],
            'RingComp': [],
            'RingPixComp': [],
            'Core_x': [],
            'Core_y': [],
            'Impact_x_arr': [],
            'Impact_y_arr': [],
            'MCImpactP': [],
            'ImpactDiff': [],
            'RingSize': [],
            'RingRadius': [],
            'NTels': []
        }

        numev = 0
        num_muons_found = 0

        for event in event_source(self.infile):
            self.log.info("Event Number: %d, found %d muons", numev,
                          num_muons_found)
            self.calib.calibrate(event)
            muon_evt = analyze_muon_event(event)

            numev += 1

            if not muon_evt[
                    'MuonIntensityParams']:  # No telescopes contained a good muon
                continue
            else:
                if self.display:
                    plot_muon_event(event, muon_evt)

                ntels = len(event.r0.tels_with_data)
                #if(len( event.r0.tels_with_data) <= 1):
                #continue
                #print("event.r0.tels_with_data", event.r0.tels_with_data)
                for tid in muon_evt['TelIds']:
                    idx = muon_evt['TelIds'].index(tid)
                    if muon_evt['MuonIntensityParams'][idx] is not None:
                        print("pos, tid", event.inst.subarray.positions[tid],
                              tid)
                        tel_x = event.inst.subarray.positions[tid][0]
                        tel_y = event.inst.subarray.positions[tid][1]
                        core_x = event.mc.core_x  # MC Core x
                        core_y = event.mc.core_y  # MC Core y
                        rec_impact_x = muon_evt['MuonIntensityParams'][
                            idx].impact_parameter_pos_x
                        rec_impact_y = muon_evt['MuonIntensityParams'][
                            idx].impact_parameter_pos_y
                        print("rec_impact_x, rec_impact_y", rec_impact_x,
                              rec_impact_y)
                        print("event.mc.core_x, event.mc.core_y",
                              event.mc.core_x, event.mc.core_y)
                        impact_mc = np.sqrt(
                            np.power(core_x - tel_x, 2) +
                            np.power(core_y - tel_y, 2))
                        print("simulated impact", impact_mc)
                        # Coordinate transformation to move the impact point to array coordinates
                        rec_impact_x_arr = tel_x + rec_impact_x
                        rec_impact_y_arr = tel_y + rec_impact_y
                        print("impact_x_arr, impact_y_arr", rec_impact_x_arr,
                              rec_impact_y_arr)
                        # Distance between core of the showe and impact parameter
                        impact_diff = np.sqrt(
                            np.power(core_x - rec_impact_x_arr, 2) +
                            np.power(core_y - rec_impact_y_arr, 2))
                        print("impact_diff ", impact_diff)
                        self.log.info("** Muon params: %s",
                                      muon_evt['MuonIntensityParams'][idx])

                        output_parameters['MuonEff'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].optical_efficiency_muon)
                        output_parameters['ImpactP'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].impact_parameter.value)
                        output_parameters['RingWidth'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].ring_width.value)
                        output_parameters['RingCont'].append(
                            muon_evt['MuonRingParams'][idx].ring_containment)
                        output_parameters['RingComp'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].ring_completeness)
                        output_parameters['RingPixComp'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].ring_pix_completeness)
                        output_parameters['Core_x'].append(
                            event.mc.core_x.value)
                        output_parameters['Core_y'].append(
                            event.mc.core_y.value)
                        output_parameters['Impact_x_arr'].append(
                            rec_impact_x_arr.value)
                        output_parameters['Impact_y_arr'].append(
                            rec_impact_y_arr.value)
                        output_parameters['MCImpactP'].append(impact_mc.value)
                        output_parameters['ImpactDiff'].append(
                            impact_diff.value)
                        output_parameters['RingSize'].append(
                            muon_evt['MuonIntensityParams'][idx].ring_size)
                        output_parameters['RingRadius'].append(
                            muon_evt['MuonRingParams'][idx].ring_radius.value)
                        output_parameters['NTels'].append(ntels)

                        print_muon(muon_evt, printer=self.log.info)
                        num_muons_found += 1

        t = Table(output_parameters)
        t['ImpactP'].unit = 'm'
        t['RingWidth'].unit = 'deg'
        #t['MCImpactP'].unit = 'm'
        if self.outfile:
            t.write(self.outfile)