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

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

            self.event_cutflow.count('no_sel')
            self.calibrator.calibrate(event)

            for tel_id in event.dl0.tels_with_data:
                self.image_cutflow.count('no_sel')

                camera = event.inst.subarray.tel[tel_id].camera
                dl1_tel = event.dl1.tel[tel_id]

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

                # Preselection cuts
                if self.image_cutflow.cut('n_pixel', cleaned):
                    continue
                if self.image_cutflow.cut('image_amplitude', np.sum(cleaned)):
                    continue

                # Image parametrisation
                params = hillas_parameters(camera, cleaned)

                # Save Ids, MC infos and Hillas informations
                self.writer.write(camera.cam_id, [event.r0, event.mc, params])
示例#2
0
    def start(self):
        self.log.info('Loop on events...')

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

            self.event_cutflow.count('no_sel')
            self.calibrator.calibrate(event)

            for tel_id in event.dl0.tels_with_data:
                self.image_cutflow.count('no_sel')

                camera = event.inst.subarray.tel[tel_id].camera
                dl1_tel = event.dl1.tel[tel_id]

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

                # Preselection cuts
                if self.image_cutflow.cut('n_pixel', cleaned):
                    continue
                if self.image_cutflow.cut('image_amplitude', np.sum(cleaned)):
                    continue

                # Image parametrisation
                params = hillas_parameters(camera, cleaned)

                # Save Ids, MC infos and Hillas informations
                self.writer.write(camera.cam_id, [event.r0, event.mc, params])
示例#3
0
def parametrize_image(image, peak_time, signal_pixels, camera_geometry,
                      focal_length, dl1_container):
    '''
    Calculate image parameters and fill them into ``dl1_container``
    '''

    geom_selected = camera_geometry[signal_pixels]
    image_selectecd = image[signal_pixels]
    hillas = hillas_parameters(geom_selected, image_selectecd)

    # Fill container
    dl1_container.fill_hillas(hillas)

    # convert ctapipe's width and length (in m) to deg:

    for key in ['width', 'width_uncertainty', 'length', 'length_uncertainty']:
        value = getattr(dl1_container, key)
        setattr(dl1_container, key,
                _camera_distance_to_angle(value, focal_length))

    dl1_container.wl = dl1_container.width / dl1_container.length

    dl1_container.set_timing_features(
        geom_selected,
        image_selectecd,
        peak_time[signal_pixels],
        hillas,
    )
    dl1_container.set_leakage(camera_geometry, image, signal_pixels)
    dl1_container.set_concentration(geom_selected, image_selectecd, hillas)
    dl1_container.log_intensity = np.log10(dl1_container.intensity)
示例#4
0
    def start(self):
        self.log.info("Loop on events...")

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

            self.calibrator(event)

            for tel_id in event.dl0.tel.keys():

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

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

                # Image parametrisation
                params = hillas_parameters(geom, cleaned)

                # Save Ids, MC infos and Hillas informations
                self.writer.write(geom.camera_name,
                                  [event.r0, event.simulation.shower, params])
示例#5
0
def main():
    std_config = get_standard_config()

    if args.config_file is not None:
        config = replace_config(std_config, read_configuration_file(args.config_file))
    else:
        config = std_config

    print(config['tailcut'])

    geom = CameraGeometry.from_name('LSTCam-002')
    foclen = OpticsDescription.from_name('LST').equivalent_focal_length
    dl1_container = DL1ParametersContainer()
    parameters_to_update = list(HillasParametersContainer().keys())
    parameters_to_update.extend(['wl', 'r', 'leakage', 'n_islands', 'intercept', 'time_gradient'])

    nodes_keys = get_dataset_keys(args.input_file)
    if args.noimage:
        nodes_keys.remove(dl1_images_lstcam_key)

    auto_merge_h5files([args.input_file], args.output_file, nodes_keys=nodes_keys)

    with tables.open_file(args.input_file, mode='r') as input:
        image_table = input.root[dl1_images_lstcam_key]
        with tables.open_file(args.output_file, mode='a') as output:

            params = output.root[dl1_params_lstcam_key].read()

            for ii, row in enumerate(image_table):
                if ii%10000 == 0:
                    print(ii)
                image = row['image']
                pulse_time = row['pulse_time']
                signal_pixels = tailcuts_clean(geom, image, **config['tailcut'])
                if image[signal_pixels].shape[0] > 0:
                    num_islands, island_labels = number_of_islands(geom, signal_pixels)
                    hillas = hillas_parameters(geom[signal_pixels], image[signal_pixels])

                    dl1_container.fill_hillas(hillas)
                    dl1_container.set_timing_features(geom[signal_pixels],
                                                      image[signal_pixels],
                                                      pulse_time[signal_pixels],
                                                      hillas)
                    dl1_container.set_leakage(geom, image, signal_pixels)
                    dl1_container.n_islands = num_islands
                    dl1_container.wl = dl1_container.width / dl1_container.length
                    width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
                    length = np.rad2deg(np.arctan2(dl1_container.length, foclen))
                    dl1_container.width = width.value
                    dl1_container.length = length.value
                    dl1_container.r = np.sqrt(dl1_container.x**2 + dl1_container.y**2)

                    for p in parameters_to_update:
                        params[ii][p] = Quantity(dl1_container[p]).value
                else:
                    for p in parameters_to_update:
                        params[ii][p] = 0

            output.root[dl1_params_lstcam_key][:] = params
示例#6
0
    def waveform_loop(self, file_reader):
        global N_EVENTS
        global LIVE_DATA
        global FREEZE_DATA

        # Open file
        # N_EVENTS = file_reader.num_events

        with tqdm() as pbar:
            source = file_reader.read()
            for event in source:
                #  TODO: Remove telid loop once hillas tested
                for telid in event.r0.tels_with_data:
                    pbar.update(1)

                    self.r1.calibrate(event)
                    self.dl0.reduce(event)
                    self.dl1.calibrate(event)

                    index = event.count
                    image = event.dl1.tel[telid].image[CHAN]
                    mask = tailcuts_clean(self.geom, image, 1, 8, 5)
                    cleaned = np.ma.masked_array(image, ~mask)
                    pos = event.inst.pixel_pos[telid]
                    try:
                        hillas = hillas_parameters(*pos, cleaned)
                        # hillas = hillas_parameters_2(*pos, cleaned)
                    except HillasParameterizationError:
                        print('HillasParameterizationError')
                        continue

                    # print(hillas[0].length)

                    live_d = dict(index=index, image=intensity_to_hex(cleaned))
                    live_d = dict(index=index, image=intensity_to_hex(image))
                    LIVE_DATA = live_d

                    freeze_d = dict(index=index, event=copy.deepcopy(event))
                    FREEZE_DATA = freeze_d

                    width = hillas.width
                    length = hillas.length
                    size = hillas.size
                    phi = hillas.phi
                    miss = hillas.miss
                    r = hillas.r

                    HILLAS['width'] += \
                        np.histogram(width, bins=100, range=[0, 1])[0]
                    HILLAS['length'] += \
                        np.histogram(length, bins=100, range=[0, 1])[0]
                    HILLAS['size'] += \
                        np.histogram(size, bins=100, range=[0, 1000])[0]
                    HILLAS['phi'] += \
                        np.histogram(phi, bins=100, range=[0, 4])[0]
                    HILLAS['miss'] += \
                        np.histogram(miss, bins=100, range=[0, 1])[0]
                    HILLAS['r'] += \
                        np.histogram(r, bins=100, range=[0, 1])[0]
示例#7
0
def get_dl1(calibrated_event,
            telescope_id,
            dl1_container=None,
            custom_config={}):
    """
    Return a DL1ParametersContainer of extracted features from a calibrated event.
    The DL1ParametersContainer can be passed to be filled if created outside the function
    (faster for multiple event processing)

    Parameters
    ----------
    event: ctapipe event container
    telescope_id: int
    dl1_container: DL1ParametersContainer
    config_file: path to a configuration file
        configuration used for tailcut cleaning
        superseeds the standard configuration

    Returns
    -------
    DL1ParametersContainer
    """

    config = replace_config(standard_config, custom_config)
    cleaning_parameters = config["tailcut"]

    dl1_container = DL1ParametersContainer(
    ) if dl1_container is None else dl1_container

    tel = calibrated_event.inst.subarray.tels[telescope_id]
    dl1 = calibrated_event.dl1.tel[telescope_id]
    camera = tel.camera

    image = dl1.image
    pulse_time = dl1.pulse_time

    signal_pixels = cleaning_method(camera, image, **cleaning_parameters)

    if image[signal_pixels].sum() > 0:
        hillas = hillas_parameters(camera[signal_pixels], image[signal_pixels])
        # Fill container
        dl1_container.fill_mc(calibrated_event)
        dl1_container.fill_hillas(hillas)
        dl1_container.fill_event_info(calibrated_event)
        dl1_container.set_mc_core_distance(calibrated_event, telescope_id)
        dl1_container.set_mc_type(calibrated_event)
        dl1_container.set_timing_features(camera, image, pulse_time, hillas)
        dl1_container.set_leakage(camera, image, signal_pixels)
        dl1_container.set_n_islands(camera, signal_pixels)
        dl1_container.set_source_camera_position(calibrated_event,
                                                 telescope_id)
        dl1_container.set_disp([dl1_container.src_x, dl1_container.src_y],
                               hillas)
        dl1_container.set_telescope_info(calibrated_event, telescope_id)

        return dl1_container

    else:
        return None
示例#8
0
def process_event(event, dl1, infos_save):
    Keylist = [
        "size", "cen_x", "cen_y", "length", "width", "r", "phi", "psi", "miss",
        "skewness", "kurtosis", "Reinheit", "Effizienz", "Genauigkeit"
    ]
    calibration(event, r1, dl0, dl1)

    eins_drinne = {}

    err = False
    image = event.dl1.tel[tel_id].image[0]
    geom = event.inst.subarray.tel[tel_id].camera

    for i in infos_save.keys():
        for j in infos_save[i].keys():
            if i not in eins_drinne.keys():
                eins_drinne[i] = {}
            if j not in eins_drinne[i].keys():
                eins_drinne[i][j] = False
            if i == "o":
                event_info = {}
                event_info = set_mc(event_info, event, tel_id)
                infos_save[i][j].append(event_info)
                eins_drinne[i][j] = True
                continue

            cleaning_mask = tailcuts_clean(geom,
                                           image,
                                           picture_thresh=i,
                                           boundary_thresh=j)
            if len(image[cleaning_mask]) == 0:
                continue
            clean = image.copy()
            clean[~cleaning_mask] = 0.0
            event_info = {}
            hillas = hillas_parameters(geom, image=clean)
            event_info = set_hillas(event_info, hillas)
            event_info = set_mc(event_info, event, tel_id)
            event_info = set_tp(event_info, cleaning_mask,
                                event.mc.tel[tel_id].photo_electron_image)
            for key in Keylist:
                if key not in event_info:
                    err = True
                else:
                    drinne = False
                    wert = event_info[key][0]
                    if wert >= 0:
                        drinne = True
                    elif wert < 0:
                        drinne = True
                    if drinne is False:
                        err = True
            if err:
                continue
            infos_save[i][j].append(event_info)
            eins_drinne[i][j] = True

    return infos_save
示例#9
0
def get_observation_parameters(charge: np.array,
                               peak: np.array,
                               cam_name: str,
                               cutflow: CutFlow,
                               boundary_threshold: float = None,
                               picture_threshold: float = None,
                               min_neighbours: float = None,
                               plot: bool = False,
                               cut: bool = True):
    """
    :param charge: Charge image
    :param peak: Peak time image
    :param cam_name: Camera name. e.g. FlashCam, ASTRICam, etc.
    :param cutflow: Cutflow for selection
    :param boundary_threshold: (Optional) Cleaning parameter: boundary threshold
    :param picture_threshold: (Optional) Cleaning parameter: picture threshold
    :param min_neighbours: (Optional) Cleaning parameter: minimum neighbours
    :param plot: If True, for each observation a plot will be shown (Default: False)
    :param cut: If true, tight else loose
    :return: hillas containers, leakage container, number of islands, island IDs, timing container, timing gradient
    """
    charge_biggest, mask = clean_charge(charge, cam_name, boundary_threshold,
                                        picture_threshold, min_neighbours)

    camera = get_camera(cam_name)
    geometry = camera.geometry
    charge_biggest, camera_biggest, n_islands = mask_from_biggest_island(
        charge, geometry, mask)
    if cut:
        if cutflow.cut(CFO_MIN_PIXEL, charge_biggest):
            return
        if cutflow.cut(CFO_MIN_CHARGE, np.sum(charge_biggest)):
            return
    if cutflow.cut(CFO_NEGATIVE_CHARGE, charge_biggest):
        return

    leakage_c = leakage(geometry, charge, mask)

    if plot:
        _, (ax1, ax2) = plt.subplots(nrows=1, ncols=2)
        CameraDisplay(geometry, charge, ax=ax1).add_colorbar()
        CameraDisplay(camera_biggest, charge_biggest, ax=ax2).add_colorbar()
        plt.show()

    moments = hillas_parameters(camera_biggest, charge_biggest)
    if cut:
        if cutflow.cut(CFO_CLOSE_EDGE, moments, camera.camera_name):
            return
        if cutflow.cut(CFO_BAD_ELLIP, moments):
            return

    if cutflow.cut(CFO_POOR_MOMENTS, moments):
        return

    timing_c = timing_parameters(geometry, charge, peak, moments, mask)
    time_gradient = timing_c.slope.value if geometry.camera_name != 'ASTRICam' else moments.skewness
    return moments, leakage_c, timing_c, time_gradient, n_islands
示例#10
0
def test_overlay_disp_vector():
    from ctapipe.image import hillas_parameters

    geom = CameraGeometry.from_name('LSTCam')
    image = np.random.rand(geom.n_pixels)
    display = CameraDisplay(geom, image)
    hillas = hillas_parameters(geom, image)
    disp = disp_parameters_event(hillas, 0.1 * u.m, 0.3 * u.m)
    overlay_disp_vector(display, disp, hillas)
示例#11
0
def get_dl1(calibrated_event, telescope_id, dl1_container=None):
    """
    Return a DL1ParametersContainer of extracted features from a calibrated event.
    The DL1ParametersContainer can be passed to be filled if created outside the function
    (faster for multiple event processing)

    Parameters
    ----------
    event: ctapipe event container
    telescope_id: int
    dl1_container: DL1ParametersContainer

    Returns
    -------
    DL1ParametersContainer
    """
    dl1_container = DL1ParametersContainer(
    ) if dl1_container is None else dl1_container

    tel = calibrated_event.inst.subarray.tels[telescope_id]
    dl1 = calibrated_event.dl1.tel[telescope_id]
    camera = tel.camera

    waveform = calibrated_event.r0.tel[telescope_id].waveform
    image = dl1.image
    pulse_time = dl1.pulse_time

    image, pulse_time = gain_selection(waveform, image, pulse_time,
                                       camera.cam_id, threshold)

    signal_pixels = cleaning_method(camera, image, **cleaning_parameters)
    image[~signal_pixels] = 0

    if image.sum() > 0:
        hillas = hillas_parameters(camera, image)
        # Fill container
        dl1_container.fill_mc(calibrated_event)
        dl1_container.fill_hillas(hillas)
        dl1_container.fill_event_info(calibrated_event)
        dl1_container.set_mc_core_distance(calibrated_event, telescope_id)
        dl1_container.set_mc_type(calibrated_event)
        dl1_container.set_timing_features(camera, image, pulse_time, hillas)
        dl1_container.set_leakage(camera, image, signal_pixels)
        dl1_container.set_n_islands(camera, signal_pixels)
        dl1_container.set_source_camera_position(calibrated_event,
                                                 telescope_id)
        dl1_container.set_disp([dl1_container.src_x, dl1_container.src_y],
                               hillas)
        dl1_container.set_telescope_info(calibrated_event, telescope_id)

        return dl1_container

    else:
        return None
示例#12
0
def compute_hillas_parameters(events, geom):
    for event in events:
        mask = event.data.cleaning_mask
        image = event.data.reconstructed_number_of_pe.copy()
        image[image < 0] = 0
        image[~mask] = 0
        try:
            hillas = hillas_parameters(geom, image)
            event.hillas = hillas
            yield event
        except HillasParameterizationError:
            continue
示例#13
0
def get_dl1(calibrated_event, telescope_id):
    """
    Return a DL1ParametersContainer of extracted features from a calibrated event

    Parameters
    ----------
    event: ctapipe event container
    telescope_id:

    Returns
    -------
    DL1ParametersContainer
    """
    dl1_container = DL1ParametersContainer()

    tel = calibrated_event.inst.subarray.tels[telescope_id]
    dl1 = calibrated_event.dl1.tel[telescope_id]
    camera = tel.camera

    waveform = calibrated_event.r0.tel[telescope_id].waveform
    image = dl1.image
    peakpos = dl1.peakpos

    image, peakpos = gain_selection(waveform, image, peakpos, camera.cam_id,
                                    threshold)

    signal_pixels = cleaning_method(camera, image, **cleaning_parameters)
    image[~signal_pixels] = 0

    if image.sum() > 0:
        try:
            hillas = hillas_parameters(camera, image)
            ## Fill container ##
            dl1_container.fill_mc(calibrated_event)
            dl1_container.fill_hillas(hillas)
            dl1_container.fill_event_info(calibrated_event)
            dl1_container.set_mc_core_distance(calibrated_event, telescope_id)
            # dl1_container.mc_type = utils.guess_type(infile)
            dl1_container.set_timing_features(camera, image, peakpos, hillas)
            dl1_container.set_source_camera_position(calibrated_event,
                                                     telescope_id)
            dl1_container.set_disp([dl1_container.src_x, dl1_container.src_y],
                                   hillas)
            return dl1_container

        except:
            print("Bad event")
            return None

    else:
        return None
示例#14
0
def draw_several_cams(geom, ncams=4):

    cmaps = ["jet", "afmhot", "terrain", "autumn"]
    fig, axs = plt.subplots(
        1,
        ncams,
        figsize=(15, 4),
    )

    for ii in range(ncams):
        disp = CameraDisplay(
            geom,
            ax=axs[ii],
            title="CT{}".format(ii + 1),
        )
        disp.cmap = cmaps[ii]

        model = toymodel.Gaussian(
            x=(0.2 - ii * 0.1) * u.m,
            y=(-ii * 0.05) * u.m,
            width=(0.05 + 0.001 * ii) * u.m,
            length=(0.15 + 0.05 * ii) * u.m,
            psi=ii * 20 * u.deg,
        )

        image, _, _ = model.generate_image(
            geom,
            intensity=1500,
            nsb_level_pe=5,
        )

        mask = tailcuts_clean(
            geom,
            image,
            picture_thresh=6 * image.mean(),
            boundary_thresh=4 * image.mean(),
        )
        cleaned = image.copy()
        cleaned[~mask] = 0

        hillas = hillas_parameters(geom, cleaned)

        disp.image = image
        disp.add_colorbar(ax=axs[ii])

        disp.set_limits_percent(95)
        disp.overlay_moments(hillas, linewidth=3, color="blue")
示例#15
0
def draw_several_cams(geom, ncams=4):

    cmaps = ['jet', 'afmhot', 'terrain', 'autumn']
    fig, axs = plt.subplots(
        1, ncams, figsize=(15, 4), sharey=True, sharex=True
    )

    for ii in range(ncams):
        disp = CameraDisplay(
            geom,
            ax=axs[ii],
            title="CT{}".format(ii + 1),
        )
        disp.cmap = cmaps[ii]

        model = toymodel.generate_2d_shower_model(
            centroid=(0.2 - ii * 0.1, -ii * 0.05),
            width=0.005 + 0.001 * ii,
            length=0.1 + 0.05 * ii,
            psi=ii * 20 * u.deg,
        )

        image, sig, bg = toymodel.make_toymodel_shower_image(
            geom,
            model.pdf,
            intensity=50,
            nsb_level_pe=1000,
        )

        mask = tailcuts_clean(
            geom,
            image,
            picture_thresh=6 * image.mean(),
            boundary_thresh=4 * image.mean()
        )
        cleaned = image.copy()
        cleaned[~mask] = 0

        hillas = hillas_parameters(geom, cleaned)

        disp.image = image
        disp.add_colorbar(ax=axs[ii])

        disp.set_limits_percent(95)
        disp.overlay_moments(hillas, linewidth=3, color='blue')
示例#16
0
def draw_several_cams(geom, ncams=4):

    cmaps = ['jet', 'afmhot', 'terrain', 'autumn']
    fig, axs = plt.subplots(
        1, ncams, figsize=(15, 4),
    )

    for ii in range(ncams):
        disp = CameraDisplay(
            geom,
            ax=axs[ii],
            title="CT{}".format(ii + 1),
        )
        disp.cmap = cmaps[ii]

        model = toymodel.generate_2d_shower_model(
            centroid=(0.2 - ii * 0.1, -ii * 0.05),
            width=0.05 + 0.001 * ii,
            length=0.15 + 0.05 * ii,
            psi=ii * 20 * u.deg,
        )

        image, sig, bg = toymodel.make_toymodel_shower_image(
            geom,
            model.pdf,
            intensity=1500,
            nsb_level_pe=5,
        )

        mask = tailcuts_clean(
            geom,
            image,
            picture_thresh=6 * image.mean(),
            boundary_thresh=4 * image.mean()
        )
        cleaned = image.copy()
        cleaned[~mask] = 0

        hillas = hillas_parameters(geom, cleaned)

        disp.image = image
        disp.add_colorbar(ax=axs[ii])

        disp.set_limits_percent(95)
        disp.overlay_moments(hillas, linewidth=3, color='blue')
示例#17
0
def compute_hillas_parameters(events, geom):

    for event in events:

        mask = event.data.cleaning_mask
        image = event.data.reconstructed_number_of_pe
        image = np.ma.masked_array(image, mask=~mask)

        try:

            hillas = hillas_parameters(geom, image)
            event.hillas = hillas

            yield event

        except HillasParameterizationError:

            continue
示例#18
0
def get_dl1b_tailcut(dl1a_img, dl1a_pulse, config_path, use_main_island=True):
    cleaning_method = tailcuts_clean
    config = read_configuration_file(config_path)
    cleaning_parameters = config["tailcut"]

    dl1_container = DL1ParametersContainer()

    image = dl1a_img
    pulse_time = dl1a_pulse
    signal_pixels = cleaning_method(camera_geometry, image,
                                    **cleaning_parameters)

    n_pixels = np.count_nonzero(signal_pixels)

    if n_pixels > 0:
        # check the number of islands
        num_islands, island_labels = number_of_islands(camera_geometry,
                                                       signal_pixels)

        if use_main_island:
            n_pixels_on_island = np.bincount(island_labels.astype(np.int))
            n_pixels_on_island[
                0] = 0  # first island is no-island and should not be considered
            max_island_label = np.argmax(n_pixels_on_island)
            signal_pixels[island_labels != max_island_label] = False

        hillas = hillas_parameters(camera_geometry[signal_pixels],
                                   image[signal_pixels])

        dl1_container.fill_hillas(hillas)
        dl1_container.set_timing_features(camera_geometry[signal_pixels],
                                          image[signal_pixels],
                                          pulse_time[signal_pixels], hillas)

        set_converted_hillas_param(dl1_container, dl1_container.width,
                                   dl1_container.length)
        set_image_param(dl1_container, image, signal_pixels, hillas, n_pixels,
                        num_islands)

    return dl1_container
示例#19
0
def find_nice_event():
    filename = datasets.get_dataset_path("gamma_test_large.simtel.gz")
    source = event_source(filename)
    calib = CameraCalibrator()
    
    for i, event in tqdm(enumerate(source)):
        # from IPython import embed; embed()
        # if i in [0, 1, 2, 3, 4, 39]:  # skip ugly events
        #     print(i, event.mc.energy)
        #     continue 
        subarray = event.inst.subarray
        calib(event)
        for tel_id in event.dl0.tels_with_data:
            # Camera Geometry required for hillas parametrization
            camgeom = subarray.tel[tel_id].camera
            # note the [0] is for channel 0 which is high-gain channel
            image = event.dl1.tel[tel_id].image
            # Cleaning  of the image
            cleaned_image = image.copy()
            # create a clean mask of pixels above the threshold
            cleanmask = tailcuts_clean(
                camgeom, image, picture_thresh=10, boundary_thresh=5, min_number_picture_neighbors=3
            )
            # set all rejected pixels to zero
            cleaned_image[~cleanmask] = 0

            # Calculate hillas parameters
            try:
                d = hillas_parameters(camgeom, cleaned_image)
            except HillasParameterizationError:
                pass  # skip failed parameterization (normally no signal)
            # from IPython import embed; embed()
            tel_name = event.inst.subarray.tel[tel_id].name
            if tel_name == 'LST' and d.r < 1 * u.m and d.intensity > 400:
                print(i, d.intensity, event.mc.energy)
                return tel_id, d, event, cleanmask
def main():
    std_config = get_standard_config()

    if args.config_file is not None:
        config = replace_config(std_config,
                                read_configuration_file(args.config_file))
    else:
        config = std_config

    print(config['tailcut'])

    foclen = OpticsDescription.from_name('LST').equivalent_focal_length
    cam_table = Table.read(args.input_file,
                           path="instrument/telescope/camera/LSTCam")
    camera_geom = CameraGeometry.from_table(cam_table)

    dl1_container = DL1ParametersContainer()
    parameters_to_update = list(HillasParametersContainer().keys())
    parameters_to_update.extend([
        'concentration_cog',
        'concentration_core',
        'concentration_pixel',
        'leakage_intensity_width_1',
        'leakage_intensity_width_2',
        'leakage_pixels_width_1',
        'leakage_pixels_width_2',
        'n_islands',
        'intercept',
        'time_gradient',
        'n_pixels',
        'wl',
        'r',
    ])

    nodes_keys = get_dataset_keys(args.input_file)
    if args.noimage:
        nodes_keys.remove(dl1_images_lstcam_key)

    auto_merge_h5files([args.input_file],
                       args.output_file,
                       nodes_keys=nodes_keys)

    with tables.open_file(args.input_file, mode='r') as input:
        image_table = input.root[dl1_images_lstcam_key]
        with tables.open_file(args.output_file, mode='a') as output:

            params = output.root[dl1_params_lstcam_key].read()

            for ii, row in enumerate(image_table):
                if ii % 10000 == 0:
                    print(ii)
                image = row['image']
                peak_time = row['peak_time']

                signal_pixels = tailcuts_clean(camera_geom, image,
                                               **config['tailcut'])
                n_pixels = np.count_nonzero(signal_pixels)
                if n_pixels > 0:
                    num_islands, island_labels = number_of_islands(
                        camera_geom, signal_pixels)
                    n_pixels_on_island = np.bincount(
                        island_labels.astype(np.int))
                    n_pixels_on_island[
                        0] = 0  # first island is no-island and should not be considered
                    max_island_label = np.argmax(n_pixels_on_island)
                    signal_pixels[island_labels != max_island_label] = False

                    hillas = hillas_parameters(camera_geom[signal_pixels],
                                               image[signal_pixels])

                    dl1_container.fill_hillas(hillas)
                    dl1_container.set_timing_features(
                        camera_geom[signal_pixels], image[signal_pixels],
                        peak_time[signal_pixels], hillas)

                    dl1_container.set_leakage(camera_geom, image,
                                              signal_pixels)
                    dl1_container.set_concentration(camera_geom, image, hillas)
                    dl1_container.n_islands = num_islands
                    dl1_container.wl = dl1_container.width / dl1_container.length
                    dl1_container.n_pixels = n_pixels
                    width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
                    length = np.rad2deg(
                        np.arctan2(dl1_container.length, foclen))
                    dl1_container.width = width
                    dl1_container.length = length
                    dl1_container.r = np.sqrt(dl1_container.x**2 +
                                              dl1_container.y**2)

                else:
                    # for consistency with r0_to_dl1.py:
                    for key in dl1_container.keys():
                        dl1_container[key] = \
                            u.Quantity(0, dl1_container.fields[key].unit)

                    dl1_container.width = u.Quantity(np.nan, u.m)
                    dl1_container.length = u.Quantity(np.nan, u.m)
                    dl1_container.wl = u.Quantity(np.nan, u.m)

            for p in parameters_to_update:
                params[ii][p] = u.Quantity(dl1_container[p]).value

            output.root[dl1_params_lstcam_key][:] = params
示例#21
0
            cleaned_image = image.copy()

            # create a clean mask of pixels above the threshold
            cleanmask = tailcuts_clean(camgeom,
                                       image,
                                       picture_thresh=10,
                                       boundary_thresh=5)
            if np.count_nonzero(cleanmask) < 10:
                continue

            # set all rejected pixels to zero
            cleaned_image[~cleanmask] = 0

            # Calculate hillas parameters
            try:
                hillas_dict[tel_id] = hillas_parameters(camgeom, cleaned_image)
            except HillasParameterizationError:
                continue  # skip failed parameterization (normally no signal)

            timing_dict[tel_id] = timing_parameters(camgeom, image, time,
                                                    hillas_dict[tel_id],
                                                    cleanmask).slope.value

        array_disp.set_vector_hillas(hillas_dict,
                                     500,
                                     timing_dict,
                                     angle_offset=0 * u.deg)

        plt.pause(0.1)  # allow matplotlib to redraw the display

        if len(hillas_dict) < 2:
示例#22
0
if __name__ == "__main__":

    # Load the camera
    geom = CameraGeometry.from_name("LSTCam")
    disp = CameraDisplay(geom)
    disp.add_colorbar()

    # Create a fake camera image to display:
    model = toymodel.Gaussian(
        x=0.2 * u.m, y=0.0 * u.m, width=0.05 * u.m, length=0.15 * u.m, psi="35d"
    )

    image, sig, bg = model.generate_image(geom, intensity=1500, nsb_level_pe=2)

    # Apply image cleaning
    cleanmask = tailcuts_clean(geom, image, picture_thresh=10, boundary_thresh=5)
    clean = image.copy()
    clean[~cleanmask] = 0.0

    # Calculate image parameters
    hillas = hillas_parameters(geom, clean)
    print(hillas)

    # Show the camera image and overlay Hillas ellipse and clean pixels
    disp.image = image
    disp.cmap = "inferno"
    disp.highlight_pixels(cleanmask, color="crimson")
    disp.overlay_moments(hillas, color="cyan", linewidth=1)

    plt.show()
示例#23
0
        # note the [0] is for channel 0 which is high-gain channel
        image = event.dl1.tel[tel_id].image

        # Cleaning  of the image
        cleaned_image = image
        # create a clean mask of pixels above the threshold
        cleanmask = tailcuts_clean(
            camgeom, image, picture_thresh=10, boundary_thresh=5
        )
        # set all rejected pixels to zero
        cleaned_image[~cleanmask] = 0

        # Calculate hillas parameters
        # It fails for empty pixels
        try:
            params = hillas_parameters(camgeom, cleaned_image)
        except:
            continue

        if params.width > 0:
            hillas_params[tel_id] = params



    array_pointing = SkyCoord(
        az=event.mcheader.run_array_direction[0],
        alt=event.mcheader.run_array_direction[1],
        frame=horizon_frame
    )

    if len(hillas_params) < 2:
示例#24
0
if __name__ == '__main__':

    # Load the camera
    geom = CameraGeometry.from_name("LSTCam")
    disp = CameraDisplay(geom)
    disp.add_colorbar()

    # Create a fake camera image to display:
    model = toymodel.generate_2d_shower_model(
        centroid=(0.2, 0.0), width=0.05, length=0.15, psi='35d'
    )

    image, sig, bg = toymodel.make_toymodel_shower_image(
        geom, model.pdf, intensity=1500, nsb_level_pe=3
    )

    # Apply image cleaning
    cleanmask = tailcuts_clean(
        geom, image, picture_thresh=10, boundary_thresh=5
    )

    # Calculate image parameters
    hillas = hillas_parameters(geom[cleanmask], image[cleanmask])

    # Show the camera image and overlay Hillas ellipse and clean pixels
    disp.image = image
    disp.highlight_pixels(cleanmask, color='crimson')
    disp.overlay_moments(hillas, color='cyan', linewidth=3)

    plt.show()
示例#25
0
def get_dl1(
    calibrated_event,
    subarray,
    telescope_id,
    dl1_container=None,
    custom_config={},
):
    """
    Return a DL1ParametersContainer of extracted features from a calibrated event.
    The DL1ParametersContainer can be passed to be filled if created outside the function
    (faster for multiple event processing)

    Parameters
    ----------
    calibrated_event: ctapipe event container
    subarray: `ctapipe.instrument.subarray.SubarrayDescription`
    telescope_id: `int`
    dl1_container: DL1ParametersContainer
    custom_config: path to a configuration file
        configuration used for tailcut cleaning
        superseeds the standard configuration

    Returns
    -------
    DL1ParametersContainer
    """

    config = replace_config(standard_config, custom_config)
    cleaning_parameters = config["tailcut"]
    cleaning_parameters_for_tailcuts = cleaning_parameters.copy()
    use_main_island = True
    if "use_only_main_island" in cleaning_parameters.keys():
        use_main_island = cleaning_parameters["use_only_main_island"]

    # time constraint for image cleaning: require at least one neighbor
    # within delta_time:
    delta_time = None
    if "delta_time" in cleaning_parameters:
        delta_time = cleaning_parameters["delta_time"]

    # we use pop because ctapipe won't recognize that keyword in tailcuts
    cleaning_parameters_for_tailcuts.pop("delta_time")
    cleaning_parameters_for_tailcuts.pop("use_only_main_island")

    dl1_container = DL1ParametersContainer(
    ) if dl1_container is None else dl1_container

    dl1 = calibrated_event.dl1.tel[telescope_id]
    telescope = subarray.tel[telescope_id]
    camera_geometry = telescope.camera.geometry

    image = dl1.image
    peak_time = dl1.peak_time

    signal_pixels = cleaning_method(camera_geometry, image,
                                    **cleaning_parameters_for_tailcuts)
    n_pixels = np.count_nonzero(signal_pixels)

    if n_pixels > 0:
        # check the number of islands
        num_islands, island_labels = number_of_islands(camera_geometry,
                                                       signal_pixels)

        if use_main_island:
            n_pixels_on_island = np.bincount(island_labels)
            n_pixels_on_island[
                0] = 0  # first island is no-island and should not be considered
            max_island_label = np.argmax(n_pixels_on_island)
            signal_pixels[island_labels != max_island_label] = False

        if delta_time is not None:
            cleaned_pixel_times = peak_time
            # makes sure only signal pixels are used in the time
            # check:
            cleaned_pixel_times[~signal_pixels] = np.nan

            new_mask = apply_time_delta_cleaning(camera_geometry,
                                                 signal_pixels,
                                                 cleaned_pixel_times, 1,
                                                 delta_time)
            signal_pixels = new_mask

        # count surviving pixels
        n_pixels = np.count_nonzero(signal_pixels)

        if n_pixels > 0:
            hillas = hillas_parameters(camera_geometry[signal_pixels],
                                       image[signal_pixels])

            # Fill container
            dl1_container.fill_hillas(hillas)

            # convert ctapipe's width and length (in m) to deg:
            foclen = subarray.tel[telescope_id].optics.equivalent_focal_length
            width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
            length = np.rad2deg(np.arctan2(dl1_container.length, foclen))
            dl1_container.width = width
            dl1_container.length = length
            dl1_container.wl = dl1_container.width / dl1_container.length

            dl1_container.set_timing_features(camera_geometry[signal_pixels],
                                              image[signal_pixels],
                                              peak_time[signal_pixels], hillas)
            dl1_container.set_leakage(camera_geometry, image, signal_pixels)
            dl1_container.set_concentration(camera_geometry, image, hillas)
            dl1_container.n_pixels = n_pixels
            dl1_container.n_islands = num_islands
            dl1_container.log_intensity = np.log10(dl1_container.intensity)

    # We set other fields which still make sense for a non-parametrized
    # image:
    dl1_container.set_telescope_info(subarray, telescope_id)

    return dl1_container
示例#26
0
                                              width=0.01,
                                              length=0.1,
                                              psi='35d')

    image, sig, bg = toymodel.make_toymodel_shower_image(geom, model.pdf,
                                                         intensity=50,
                                                         nsb_level_pe=1000)

    # Apply image cleaning
    cleanmask = tailcuts_clean(geom, image, picture_thresh=200,
                               boundary_thresh=100)
    clean = image.copy()
    clean[~cleanmask] = 0.0

    # Calculate image parameters
    hillas = hillas_parameters(geom.pix_x, geom.pix_y, clean)
    print(hillas)

    # Show the camera image and overlay Hillas ellipse and clean pixels
    disp.image = image
    disp.cmap = 'PuOr'
    disp.highlight_pixels(cleanmask, color='black')
    disp.overlay_moments(hillas, color='cyan', linewidth=3)

    # Draw the neighbors of pixel 100 in red, and the neighbor-neighbors in
    # green
    for ii in geom.neighbors[130]:
        draw_neighbors(geom, ii, color='green')

    draw_neighbors(geom, 130, color='cyan', lw=2)
示例#27
0
        # note the [0] is for channel 0 which is high-gain channel
        image = event.dl1.tel[tel_id].image[0]

        # Cleaning  of the image
        cleaned_image = image
        # create a clean mask of pixels above the threshold
        cleanmask = tailcuts_clean(
            camgeom, image, picture_thresh=10, boundary_thresh=5
        )
        # set all rejected pixels to zero
        cleaned_image[~cleanmask] = 0

        # Calulate hillas parameters
        # It fails for empty pixels
        try:
            hillas_params[tel_id] = hillas_parameters(camgeom, cleaned_image)
        except:
            pass

    if len(hillas_params) < 2:
        continue

    reco_result = reco.predict(hillas_params, event.inst, point_altitude, point_azimuth)

    # get angular offset between reconstructed shower direction and MC
    # generated shower direction
    off_angle = angular_separation(
        event.mc.az,
        event.mc.alt,
        reco_result.az,
        reco_result.alt
示例#28
0
def func(paths, outpath, ro, rc, rn):

    # iterate on each proton file & concatenate charge arrays
    for n, f in enumerate(paths):
        # get the data from the file
        try:
            print("Opening file #{}...".format(n))
            data_p = tables.open_file(f)
            _, LST_event_index, LST_image_charge, LST_image_peak_times = get_LST_data(data_p)
            _, ei_alt, ei_az, ei_mc_energy = get_event_data(data_p)

            # Excluding the 0th element - it's the empty one!!
            LST_event_index = LST_event_index[1:]
            LST_image_charge = LST_image_charge[1:]
            LST_image_peak_times = LST_image_peak_times[1:]

            # get camera geometry & camera pixels coordinates
            camera = CameraGeometry.from_name("LSTCam")
            points = np.array([np.array(camera.pix_x / u.m), np.array(camera.pix_y / u.m)]).T

            # original choice by Nicola: 100x100 points in 2.5m x 2.5m
            #grid_x, grid_y = np.mgrid[-1.25:1.25:100j, -1.25:1.25:100j]
            # I choose instead 96x88 px in 2.40m x 2.20m: same spatial separation, less points
            grid_x, grid_y = np.mgrid[-1.20:1.20:96j, -1.10:1.10:88j]

            '''
            was probably useless and wrong even with the old simulations
            if alt_array > 90:
                alt_array = 90
            '''

            # LST coordinates (pointing position)
            #point = AltAz(alt=alt_array * u.deg, az=az_array * u.deg)


            lst_image_charge_interp = []
            lst_image_peak_times_interp = []
            # alt az of the array [deg]
            #az_array = 180.  # before was ai_run_array_direction[0][0], now it is hardcoded as it's not present in new files
            #alt_array = 70.  # ai_run_array_direction[0][1]
            #delta_az = []
            #delta_alt = []
            intensities = []
            intensities_width_2 = []
            acc_idxs = []  # accepted indexes    # in principle it can be removed when cuts (line AAA) are not used here

            cleaning_level = {'LSTCam': (3.5, 7.5, 2)}
            count = 0
            #rejected = open(f[:-3] + "_rejected.txt", "w")
            for i in trange(0, len(LST_image_charge), desc="Images interpolation"):

                image = LST_image_charge[i]
                time = LST_image_peak_times[i]

                boundary, picture, min_neighbors = cleaning_level['LSTCam']
                clean = tailcuts_clean(
                    camera,
                    image,
                    boundary_thresh=boundary,
                    picture_thresh=picture,
                    min_number_picture_neighbors=min_neighbors
                )

                if len(np.where(clean > 0)[0]) != 0:
                    hillas = hillas_parameters(camera[clean], image[clean])

                    intensity = hillas['intensity']

                    l = leakage(camera, image, clean)
                    # print(l)
                    leakage2_intensity = l['intensity_width_2']

                    # if intensity > 50 and leakage2_intensity < 0.2:  # ------>AAA --- CUT DIRECTLY DURING INTERP
                    # cubic interpolation
                    interp_img = griddata(points, image, (grid_x, grid_y), fill_value=0, method='cubic')
                    interp_time = griddata(points, time, (grid_x, grid_y), fill_value=0, method='cubic')

                    # delta az, delta alt computation
                    #az = ei_az[LST_event_index[i]]
                    #alt = ei_alt[LST_event_index[i]]
                    #src = AltAz(alt=alt * u.rad, az=az * u.rad)
                    #source_direction = src.transform_to(NominalFrame(origin=point))

                    # appending to arrays
                    lst_image_charge_interp.append(interp_img)
                    lst_image_peak_times_interp.append(interp_time)
                    #delta_az.append(source_direction.delta_az.deg)
                    #delta_alt.append(source_direction.delta_alt.deg)

                    intensities.append(intensity)
                    intensities_width_2.append(leakage2_intensity)

                    acc_idxs += [i]  # also this one can be removed when no cuts here

                else:
                    count += 1
                #    #rejected.write("{}.\tImage #{} rejected (no islands)!\n".format(count, i))
                #    print("No islands: image #{} rejected! (cumulative: {})\n".format(i, count), end='\r')
            # lst_image_charge_interp = np.array(lst_image_charge_interp)
            print("Number of rejected images: {} ({:.1f}%)".format(count, count / len(intensities) *100))
            data_p.close()
            #rejected.close()
            fpath = Path(f)
            newname = fpath.name[:-3] + '_interp.h5'
            filename = str(PurePath(outpath, newname))
            print("Writing file: " + filename + "\n")
            data_file = h5py.File(filename, 'w')
            data_file.create_dataset('Event_Info/ei_alt', data=np.array(ei_alt))
            data_file.create_dataset('Event_Info/ei_az', data=np.array(ei_az))
            data_file.create_dataset('Event_Info/ei_mc_energy', data=np.array(ei_mc_energy))

            data_file.create_dataset('LST/LST_event_index', data=np.array(LST_event_index)[acc_idxs])
            data_file.create_dataset('LST/LST_image_charge', data=np.array(LST_image_charge)[acc_idxs])
            data_file.create_dataset('LST/LST_image_peak_times', data=np.array(LST_image_peak_times)[acc_idxs])
            # data_file.create_dataset('LST/LST_event_index', data=np.array(LST_event_index))
            # data_file.create_dataset('LST/LST_image_charge', data=np.array(LST_image_charge))
            # data_file.create_dataset('LST/LST_image_peak_times', data=np.array(LST_image_peak_times))
            data_file.create_dataset('LST/LST_image_charge_interp', data=np.array(lst_image_charge_interp))
            data_file.create_dataset('LST/LST_image_peak_times_interp', data=np.array(lst_image_peak_times_interp))
            #data_file.create_dataset('LST/delta_alt', data=np.array(delta_alt))
            #data_file.create_dataset('LST/delta_az', data=np.array(delta_az))

            data_file.create_dataset('LST/intensities', data=np.array(intensities))
            data_file.create_dataset('LST/intensities_width_2', data=np.array(intensities_width_2))

            data_file.close()

            # in the interpolated files there will be all the original events
            # but for the LST only the ones actually see at least from one LST (as in the original files)
            # and that are above thresholds cuts

            if ro == '1':
                remove(f)
                print('Removing original file')

        except HDF5ExtError:

            print('\nUnable to open file' + f)

            if rc == '1':
                print('Removing it...')
                remove(f)

        except NoSuchNodeError:

            print('This file has a problem with the data structure: ' + f)

            if rn == '1':
                print('Removing it...')
                remove(f)
示例#29
0
def get_events(filename,
               storedata=False,
               concatenate=False,
               storeimg=False,
               outdir='./results/'):
    """
    Read a Simtelarray file, extract pixels charge, calculate image parameters and timing
    parameters and store the result in an hdf5 file. 
    
    Parameters:
    filename: str
    Name of the simtelarray file.

    storedata: boolean
    True: store extracted data in a hdf5 file

    concatenate: boolean
    True: store the extracted data at the end of an existing file

    storeimg: boolean
    True: store also pixel data
    
    outdir: srt
    Output directory
    
    
    
    """
    #Particle type:

    particle_type = guess_type(filename)

    #Create data frame where DL2 data will be stored:

    features = [
        'ObsID', 'EvID', 'mcEnergy', 'mcAlt', 'mcAz', 'mcCore_x', 'mcCore_y',
        'mcHfirst', 'mcType', 'GPStime', 'width', 'length', 'w/l', 'phi',
        'psi', 'r', 'x', 'y', 'intensity', 'skewness', 'kurtosis', 'mcAlttel',
        'mcAztel', 'impact', 'mcXmax', 'time_gradient', 'intercept', 'SrcX',
        'SrcY', 'disp', 'hadroness'
    ]
    output = pd.DataFrame(columns=features)

    #Read LST1 events:
    source = EventSourceFactory.produce(
        input_url=filename, allowed_tels={1})  #Open Simtelarray file

    #Cleaning levels:

    level1 = {'LSTCam': 6.}
    level2 = level1.copy()
    # We use as second cleaning level just half of the first cleaning level
    for key in level2:
        level2[key] *= 0.5

    log10pixelHGsignal = {}
    survived = {}

    imagedata = np.array([])

    for key in level1:

        log10pixelHGsignal[key] = []
        survived[key] = []
    i = 0
    for event in source:
        if i % 100 == 0:
            print("EVENT_ID: ", event.r0.event_id, "TELS: ",
                  event.r0.tels_with_data, "MC Energy:", event.mc.energy)
        i = i + 1
        ntels = len(event.r0.tels_with_data)
        '''
        if i > 100:   # for quick tests
            break
        '''
        for ii, tel_id in enumerate(event.r0.tels_with_data):

            geom = event.inst.subarray.tel[tel_id].camera  #Camera geometry
            tel_coords = event.inst.subarray.tel_coords[
                event.inst.subarray.tel_indices[tel_id]]
            data = event.r0.tel[tel_id].waveform
            ped = event.mc.tel[tel_id].pedestal
            # the pedestal is the average (for pedestal events) of the *sum* of all samples, from sim_telarray

            nsamples = data.shape[2]  # total number of samples
            pedcorrectedsamples = data - np.atleast_3d(
                ped
            ) / nsamples  # Subtract pedestal baseline. atleast_3d converts 2D to 3D matrix

            integrator = LocalPeakIntegrator(None, None)
            integration, peakpos, window = integrator.extract_charge(
                pedcorrectedsamples
            )  # these are 2D matrices num_gains * num_pixels

            chan = 0  # high gain used for now...
            signals = integration[chan].astype(float)

            dc2pe = event.mc.tel[tel_id].dc_to_pe  # numgains * numpixels
            signals *= dc2pe[chan]

            # Add all individual pixel signals to the numpy array of the corresponding camera inside the log10pixelsignal dictionary
            log10pixelHGsignal[str(geom)].extend(
                np.log10(signals)
            )  # This seems to be faster like this, with normal python lists

            # Apply image cleaning
            cleanmask = tailcuts_clean(geom,
                                       signals,
                                       picture_thresh=level1[str(geom)],
                                       boundary_thresh=level2[str(geom)],
                                       keep_isolated_pixels=False,
                                       min_number_picture_neighbors=1)
            survived[str(geom)].extend(
                cleanmask
            )  # This seems to be faster like this, with normal python lists

            clean = signals.copy()
            clean[
                ~cleanmask] = 0.0  # set to 0 pixels which did not survive cleaning
            if np.max(clean) < 1.e-6:  # skip images with no pixels
                continue

            # Calculate image parameters
            hillas = hillas_parameters(
                geom,
                clean)  # this one gives some warnings invalid value in sqrt
            foclen = event.inst.subarray.tel[
                tel_id].optics.equivalent_focal_length

            w = np.rad2deg(np.arctan2(hillas.width, foclen))
            l = np.rad2deg(np.arctan2(hillas.length, foclen))

            #Calculate Timing parameters

            peak_time = units.Quantity(peakpos[chan]) * units.Unit("ns")
            timepars = time.timing_parameters(geom.pix_x, geom.pix_y, clean,
                                              peak_time, hillas.psi)

            if w >= 0:

                if storeimg == True:
                    if imagedata.size == 0:
                        imagedata = clean
                    else:
                        imagedata = np.vstack([imagedata,
                                               clean])  #Pixel content

                width = w.value
                length = l.value
                phi = hillas.phi.value
                psi = hillas.psi.value
                r = hillas.r.value
                x = hillas.x.value
                y = hillas.y.value
                intensity = np.log10(hillas.intensity)
                skewness = hillas.skewness
                kurtosis = hillas.kurtosis

                #Store parameters from event and MC:
                ObsID = event.r0.obs_id
                EvID = event.r0.event_id

                mcEnergy = np.log10(event.mc.energy.value *
                                    1e3)  #Log10(Energy) in GeV
                mcAlt = event.mc.alt.value
                mcAz = event.mc.az.value
                mcCore_x = event.mc.core_x.value
                mcCore_y = event.mc.core_y.value
                mcHfirst = event.mc.h_first_int.value
                mcType = event.mc.shower_primary_id
                mcAztel = event.mcheader.run_array_direction[0].value
                mcAlttel = event.mcheader.run_array_direction[1].value
                mcXmax = event.mc.x_max.value
                GPStime = event.trig.gps_time.value

                impact = np.sqrt(
                    (tel_coords.x.value - event.mc.core_x.value)**2 +
                    (tel_coords.y.value - event.mc.core_y.value)**2)

                time_gradient = timepars[0].value
                intercept = timepars[1].value

                #Calculate Disp and Source position in camera coordinates
                tel = OpticsDescription.from_name(
                    'LST')  #Telescope description
                focal_length = tel.equivalent_focal_length.value
                sourcepos = transformations.calc_CamSourcePos(
                    mcAlt, mcAz, mcAlttel, mcAztel, focal_length)
                SrcX = sourcepos[0]
                SrcY = sourcepos[1]
                disp = transformations.calc_DISP(sourcepos[0], sourcepos[1], x,
                                                 y)

                hadroness = 0
                if particle_type == 'proton':
                    hadroness = 1

                eventdf = pd.DataFrame([[
                    ObsID, EvID, mcEnergy, mcAlt, mcAz, mcCore_x, mcCore_y,
                    mcHfirst, mcType, GPStime, width, length, width / length,
                    phi, psi, r, x, y, intensity, skewness, kurtosis, mcAlttel,
                    mcAztel, impact, mcXmax, time_gradient, intercept, SrcX,
                    SrcY, disp, hadroness
                ]],
                                       columns=features)

                output = output.append(eventdf, ignore_index=True)

    outfile = outdir + particle_type + '_events.hdf5'

    if storedata == True:

        if concatenate == False or (concatenate == True and
                                    np.DataSource().exists(outfile) == False):
            output.to_hdf(outfile, key=particle_type + "_events", mode="w")
            if storeimg == True:
                f = h5py.File(outfile, 'r+')
                f.create_dataset('images', data=imagedata)
                f.close()
        else:
            if storeimg == True:
                f = h5py.File(outfile, 'r')
                images = f['images']
                del f['images']
                images = np.vstack([images, imagedata])
                f.close()
                saved = pd.read_hdf(outfile, key=particle_type + '_events')
                output = saved.append(output, ignore_index=True)
                output.to_hdf(outfile, key=particle_type + "_events", mode="w")
                f = h5py.File(outfile, 'r+')
                f.create_dataset('images', data=images)
                f.close()
            else:
                saved = pd.read_hdf(outfile, key=particle_type + '_events')
                output = saved.append(output, ignore_index=True)
                output.to_hdf(outfile, key=particle_type + "_events", mode="w")
    del source
    return output
示例#30
0
    # Create a fake camera image to display:
    model = toymodel.Gaussian(
        x=0.2 * u.m, y=0.0 * u.m,
        width=0.05 * u.m, length=0.15 * u.m,
        psi='35d'
    )

    image, sig, bg = model.generate_image(
        geom, intensity=1500, nsb_level_pe=2
    )

    # Apply image cleaning
    cleanmask = tailcuts_clean(
        geom, image, picture_thresh=10, boundary_thresh=5
    )
    clean = image.copy()
    clean[~cleanmask] = 0.0

    # Calculate image parameters
    hillas = hillas_parameters(geom, clean)
    print(hillas)

    # Show the camera image and overlay Hillas ellipse and clean pixels
    disp.image = image
    disp.cmap = 'inferno'
    disp.highlight_pixels(cleanmask, color='crimson')
    disp.overlay_moments(hillas, color='cyan', linewidth=1)

    plt.show()
    def start(self):

        disp = None

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

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

            self.calibrator(event)

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

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

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

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

                disp.image = im

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

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

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

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

        if disp is None:
            self.log.warning(
                "No events for tel {} were found in {}. Try a "
                "different EventIO file or another telescope".format(
                    self.tel, self.infile))
示例#32
0
def main():
    std_config = get_standard_config()

    log.setLevel(logging.INFO)
    handler = logging.StreamHandler()
    logging.getLogger().addHandler(handler)

    if args.config_file is not None:
        config = replace_config(std_config, read_configuration_file(args.config_file))
    else:
        config = std_config

    log.info(f"Tailcut config used: {config['tailcut']}")

    foclen = OpticsDescription.from_name('LST').equivalent_focal_length
    cam_table = Table.read(args.input_file, path="instrument/telescope/camera/LSTCam")
    camera_geom = CameraGeometry.from_table(cam_table)

    dl1_container = DL1ParametersContainer()
    parameters_to_update = list(HillasParametersContainer().keys())
    parameters_to_update.extend([
        'concentration_cog',
        'concentration_core',
        'concentration_pixel',
        'leakage_intensity_width_1',
        'leakage_intensity_width_2',
        'leakage_pixels_width_1',
        'leakage_pixels_width_2',
        'n_islands',
        'intercept',
        'time_gradient',
        'n_pixels',
        'wl',
        'log_intensity'
    ])

    nodes_keys = get_dataset_keys(args.input_file)
    if args.noimage:
        nodes_keys.remove(dl1_images_lstcam_key)

    auto_merge_h5files([args.input_file], args.output_file, nodes_keys=nodes_keys)

    with tables.open_file(args.input_file, mode='r') as input:
        image_table = input.root[dl1_images_lstcam_key]
        dl1_params_input = input.root[dl1_params_lstcam_key].colnames
        disp_params = {'disp_dx', 'disp_dy', 'disp_norm', 'disp_angle', 'disp_sign'}
        if set(dl1_params_input).intersection(disp_params):
            parameters_to_update.extend(disp_params)

        with tables.open_file(args.output_file, mode='a') as output:
            params = output.root[dl1_params_lstcam_key].read()
            for ii, row in enumerate(image_table):

                dl1_container.reset()

                image = row['image']
                peak_time = row['peak_time']

                signal_pixels = tailcuts_clean(camera_geom, image, **config['tailcut'])

                n_pixels = np.count_nonzero(signal_pixels)
                if n_pixels > 0:
                    num_islands, island_labels = number_of_islands(camera_geom, signal_pixels)
                    n_pixels_on_island = np.bincount(island_labels.astype(np.int))
                    n_pixels_on_island[0] = 0  # first island is no-island and should not be considered
                    max_island_label = np.argmax(n_pixels_on_island)
                    signal_pixels[island_labels != max_island_label] = False

                    hillas = hillas_parameters(camera_geom[signal_pixels], image[signal_pixels])

                    dl1_container.fill_hillas(hillas)
                    dl1_container.set_timing_features(camera_geom[signal_pixels],
                                                      image[signal_pixels],
                                                      peak_time[signal_pixels],
                                                      hillas)

                    dl1_container.set_leakage(camera_geom, image, signal_pixels)
                    dl1_container.set_concentration(camera_geom, image, hillas)
                    dl1_container.n_islands = num_islands
                    dl1_container.wl = dl1_container.width / dl1_container.length
                    dl1_container.n_pixels = n_pixels
                    width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
                    length = np.rad2deg(np.arctan2(dl1_container.length, foclen))
                    dl1_container.width = width
                    dl1_container.length = length
                    dl1_container.log_intensity = np.log10(dl1_container.intensity)

                if set(dl1_params_input).intersection(disp_params):
                    disp_dx, disp_dy, disp_norm, disp_angle, disp_sign = disp(
                        dl1_container['x'].to_value(u.m),
                        dl1_container['y'].to_value(u.m),
                        params['src_x'][ii],
                        params['src_y'][ii]
                    )

                    dl1_container['disp_dx'] = disp_dx
                    dl1_container['disp_dy'] = disp_dy
                    dl1_container['disp_norm'] = disp_norm
                    dl1_container['disp_angle'] = disp_angle
                    dl1_container['disp_sign'] = disp_sign

                for p in parameters_to_update:
                    params[ii][p] = u.Quantity(dl1_container[p]).value

            output.root[dl1_params_lstcam_key][:] = params
示例#33
0
        def update(frame):


            centroid = 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.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            self.log.debug(
                "Frame=%d width=%03f length=%03f intens=%03d",
                frame, width, length, intens
            )

            image, sig, bg = toymodel.make_toymodel_shower_image(
                geom,
                model.pdf,
                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, ]
示例#34
0
        # cleaning
        boundary, picture, min_neighbors = cleaning_level[camera.cam_id]
        clean = tailcuts_clean(
            camera,
            image,
            boundary_thresh=boundary,
            picture_thresh=picture,
            min_number_picture_neighbors=min_neighbors
        )

        # ignore images with less than 5 pixels after cleaning
        if clean.sum() < 5:
            continue

        # image parameters
        hillas_c = hillas_parameters(camera[clean], image[clean])
        leakage_c = leakage(camera, image, clean)
        n_islands, island_ids = number_of_islands(camera, clean)

        timing_c = timing_parameters(
            camera[clean], image[clean], peakpos[clean], hillas_c
        )

        # store parameters for stereo reconstruction
        hillas_containers[telescope_id] = hillas_c
        pointing_azimuth[telescope_id] = event.mc.tel[telescope_id].azimuth_raw * u.rad
        pointing_altitude[telescope_id] = event.mc.tel[telescope_id].altitude_raw * u.rad

        # store timegradients for plotting
        # ASTRI has no timing in PROD3b, so we use skewness instead
        if camera.cam_id != 'ASTRICam':
def iterate_param(possible_cleaning_levels,
                  event,
                  camera,
                  image,
                  telescope_id,
                  quality_param_list,
                  hillas_containers,
                  index=0):
    """

    iteration of the possible cleaning levels and research of the optimal through quality parameters

    Parameters
    ----------

    possible_cleaning_levels:
        array with all the possible cleaning levels chosen

    event:
        calibrated event

    camera:
        Camera geometry information

    image:
        pixel array that has to be cleaned

    telescope_id:
        unique number for the identification of a telescope

    quality_param_list:
        list of all the quality parameters of a cleaned image for all the possible cleaning levels chosen

    hillas_containers:
        dictionary with telescope IDs as key and
        HillasParametersContainer instances as values

    index:
        index of the current cleaning level chosen for the comparision

    Returns
    -------

    new_param:
        the better parameters for the given image

    """
    while index < len(possible_cleaning_levels):

        picture, boundary, min_neighbors = possible_cleaning_levels[index]

        clean = tailcuts_clean(camera,
                               image,
                               boundary_thresh=boundary,
                               picture_thresh=picture,
                               min_number_picture_neighbors=min_neighbors)

        # if the size of the clean mask is too little, we can't have a good ellipse reconstruction
        flag = verify_size_clean_mask(clean, 6)
        if flag:
            break

        cleaned_image = event.dl1.tel[telescope_id].image.copy()
        cleaned_image[~clean] = 0.0

        hillas_c = hillas_parameters(camera[clean], image[clean])
        hillas_containers[telescope_id] = hillas_c

        closest_approach = closest_approach_distance(
            hillas_containers[telescope_id])

        likelihood = likelihood_function(event, cleaned_image, telescope_id)

        num_diff_pixels = numbers_of_different_pixels(camera, event,
                                                      cleaned_image,
                                                      telescope_id, picture,
                                                      boundary, min_neighbors)

        quality_param_list.append(
            [closest_approach, likelihood, num_diff_pixels])

        index_best_parameters = optimize_param(quality_param_list, index)

        index = index + 1

    new_param = possible_cleaning_levels[index_best_parameters]

    return new_param
    # get a single image
    for i, img in enumerate(source):
        # Pick a (random) good looking image
        if i > 147:
            break
    im = img.dl1.tel[0].image
    print(img)

    # Apply image cleaning
    cleanmask = tailcuts_clean(
        geom,
        im,
        picture_thresh=30,
        boundary_thresh=5,
        min_number_picture_neighbors=0,
    )

    if sum(cleanmask) == 0:
        pass
    else:
        # Calculate image parameters
        hillas = hillas_parameters(geom[cleanmask], im[cleanmask])

        # Show the camera image and overlay Hillas ellipse and clean pixels
        disp.image = im
        disp.highlight_pixels(cleanmask, color="crimson")
        disp.overlay_moments(hillas, color="red", linewidth=2)

        plt.savefig("build/hillas_example.png", dpi=200)
    def start(self):

        disp = None

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

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

            self.calibrator.calibrate(event)

            if disp is None:
                x, y = event.inst.pixel_pos[self.tel]
                focal_len = event.inst.optical_foclen[self.tel]
                geom = CameraGeometry.guess(x, y, focal_len)
                self.log.info(geom)
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                if self.display:
                    plt.show(block=False)

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

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

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

                disp.image = im

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

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

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

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

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

        pass
示例#38
0
def get_dl1(
    calibrated_event,
    subarray,
    telescope_id,
    dl1_container=None,
    custom_config={},
    use_main_island=True,
):
    """
    Return a DL1ParametersContainer of extracted features from a calibrated event.
    The DL1ParametersContainer can be passed to be filled if created outside the function
    (faster for multiple event processing)

    Parameters
    ----------
    calibrated_event: ctapipe event container
    subarray: `ctapipe.instrument.subarray.SubarrayDescription`
    telescope_id: `int`
    dl1_container: DL1ParametersContainer
    custom_config: path to a configuration file
        configuration used for tailcut cleaning
        superseeds the standard configuration
    use_main_island: `bool` Use only the main island
        to calculate DL1 parameters

    Returns
    -------
    DL1ParametersContainer
    """

    config = replace_config(standard_config, custom_config)
    cleaning_parameters = config["tailcut"]

    dl1_container = DL1ParametersContainer(
    ) if dl1_container is None else dl1_container

    dl1 = calibrated_event.dl1.tel[telescope_id]
    telescope = subarray.tel[telescope_id]
    camera_geometry = telescope.camera.geometry

    image = dl1.image
    peak_time = dl1.peak_time

    signal_pixels = cleaning_method(camera_geometry, image,
                                    **cleaning_parameters)
    n_pixels = np.count_nonzero(signal_pixels)

    if n_pixels > 0:
        # check the number of islands
        num_islands, island_labels = number_of_islands(camera_geometry,
                                                       signal_pixels)

        if use_main_island:
            n_pixels_on_island = np.bincount(island_labels.astype(np.int))
            n_pixels_on_island[
                0] = 0  # first island is no-island and should not be considered
            max_island_label = np.argmax(n_pixels_on_island)
            signal_pixels[island_labels != max_island_label] = False

        hillas = hillas_parameters(camera_geometry[signal_pixels],
                                   image[signal_pixels])

        # Fill container
        dl1_container.fill_hillas(hillas)

        # convert ctapipe's width and length (in m) to deg:
        foclen = subarray.tel[telescope_id].optics.equivalent_focal_length
        width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
        length = np.rad2deg(np.arctan2(dl1_container.length, foclen))
        dl1_container.width = width
        dl1_container.length = length
        dl1_container.wl = dl1_container.width / dl1_container.length

        dl1_container.set_timing_features(camera_geometry[signal_pixels],
                                          image[signal_pixels],
                                          peak_time[signal_pixels], hillas)
        dl1_container.set_leakage(camera_geometry, image, signal_pixels)
        dl1_container.set_concentration(camera_geometry, image, hillas)
        dl1_container.n_pixels = n_pixels
        dl1_container.n_islands = num_islands
        dl1_container.set_telescope_info(subarray, telescope_id)

        dl1_container.log_intensity = np.log10(dl1_container.intensity)

    else:
        # We set other fields which still make sense for a non-parametrized
        # image:
        dl1_container.set_telescope_info(subarray, telescope_id)

    return dl1_container