def image_cleaning_filter(reader, images, **opts):
    """
    Filter images according to a cleaning operation.

    Parameters
    ----------
    reader: `DL1DataReader`
    images
    options for image cleaning

    Returns
    -------
    mask (Array of bool)
    """

    try:
        from ctapipe.image import cleaning
    except ImportError:
        raise ImportError(
            "The `ctapipe.image.cleaning` python module is required to perform cleaning operation"
        )
    try:
        from ctapipe.instrument.camera import CameraGeometry
    except ImportError:
        raise ImportError(
            "The `ctapipe.instrument.CameraGeometry` python module is required to perform cleaning operation"
        )

    geom = CameraGeometry.from_name(reader.tel_type.split("_")[-1])

    def clean(img):
        return cleaning.tailcuts_clean(geom, img, **opts)

    clean_mask = np.apply_along_axis(clean, 1, images)
    return clean_mask.any(axis=1)
def leakage_filter(reader,
                   images,
                   leakage_value=1.0,
                   leakage_number=2,
                   **opts):
    """
    Filter images on leakage
    Comment: An image cleaning filter is applied by default.

    Parameters
    ----------
    reader: `DL1DataReader`
    images
    options for image cleaning
    leakage_value
    leakage_number

    Returns
    -------
    mask (Array of bool)
    """

    try:
        from ctapipe.image import cleaning, leakage
    except ImportError:
        raise ImportError(
            "The `ctapipe.image.cleaning` and/or `ctapipe.image.leakage` python module is required to perform leakage operation"
        )
    try:
        from ctapipe.instrument.camera import CameraGeometry
    except ImportError:
        raise ImportError(
            "The `ctapipe.instrument.CameraGeometry` python module is required to perform leakage operation"
        )

    if leakage_number not in [1, 2]:
        raise ValueError(
            "The leakage_number is {}. Valid options are 1 or 2.".format(
                leakage_number))

    geom = CameraGeometry.from_name(reader.tel_type.split("_")[-1])

    def leak(img):
        cleanmask = cleaning.tailcuts_clean(geom, img, **opts)
        mask = False
        if any(cleanmask):
            leakage_values = leakage(geom, img, cleanmask)
            if hasattr(leakage_values,
                       "leakage{}_intensity".format(leakage_number)):
                mask = (leakage_values["leakage{}_intensity".format(
                    leakage_number)] <= leakage_value)
            elif hasattr(leakage_values,
                         "intensity_width_{}".format(leakage_number)):
                mask = (
                    leakage_values["intensity_width_{}".format(leakage_number)]
                    <= leakage_value)
        return mask

    leakage_mask = np.apply_along_axis(leak, 1, images)
    return leakage_mask
示例#3
0
def test_psi_20():
    from ctapipe.image import timing_parameters

    # Then try a different rotation angle
    grad = 2
    intercept = 1
    deviation = 0.1

    geom = CameraGeometry.from_name("LSTCam")
    psi = 20 * u.deg
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=psi)

    random = np.random.RandomState(1)
    peak_time = intercept + grad * (np.cos(psi) * geom.pix_x.value
                                     + np.sin(psi) * geom.pix_y.value)
    peak_time += random.normal(0, deviation, geom.n_pixels)

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peak_time=peak_time,
        hillas_parameters=hillas,
        cleaning_mask=np.ones(geom.n_pixels, dtype=bool)
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit, rtol=1e-2)
    assert_allclose(timing.intercept, intercept, rtol=1e-2)
    assert_allclose(timing.deviation, deviation, rtol=1e-2)
示例#4
0
def test_ignore_negative():
    from ctapipe.image import timing_parameters
    grad = 2.0
    intercept = 1.0
    deviation = 0.1

    geom = CameraGeometry.from_name("LSTCam")
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=0 * u.deg)

    random = np.random.RandomState(1)
    peak_time = intercept + grad * geom.pix_x.value
    peak_time += random.normal(0, deviation, geom.n_pixels)

    image = np.ones(geom.n_pixels)
    image[5:10] = -1.0

    cleaning_mask = image >= 0

    timing = timing_parameters(
        geom,
        image,
        peak_time=peak_time,
        hillas_parameters=hillas,
        cleaning_mask=cleaning_mask,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit, rtol=1e-2)
    assert_allclose(timing.intercept, intercept, rtol=1e-2)
    assert_allclose(timing.deviation, deviation, rtol=1e-2)
示例#5
0
def test_psi_0():
    from ctapipe.image import timing_parameters
    """
    Simple test that gradient fitting gives expected answers for perfect
    gradient
    """
    grad = 2.0
    intercept = 1.0
    deviation = 0.1

    geom = CameraGeometry.from_name("LSTCam")
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=0 * u.deg)

    random = np.random.RandomState(1)
    peak_time = intercept + grad * geom.pix_x.value
    peak_time += random.normal(0, deviation, geom.n_pixels)

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peak_time=peak_time,
        hillas_parameters=hillas,
        cleaning_mask=np.ones(geom.n_pixels, dtype=bool)
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit, rtol=1e-2)
    assert_allclose(timing.intercept, intercept, rtol=1e-2)
    assert_allclose(timing.deviation, deviation, rtol=1e-2)
示例#6
0
def generate_geometry_from_camera(camera,
                                  source_x=0. * u.mm,
                                  source_y=0. * u.mm):
    """
    Generate the SST-1M geometry from the CTS configuration
    :param camera: a CTS instance
    :param source_x:  x coord
    :param source_y:  y coord
    :return: the geometry for visualisation and the list of "good" pixels
    """
    pix_x = []
    pix_y = []
    pix_id = []

    for pix in camera.Pixels:
        pix_x.append(pix.center[0])
        pix_y.append(pix.center[1])
        pix_id.append(pix.ID)

    neighbors_pix = _find_neighbor_pixels(pix_x, pix_y, 30.)
    geom = CameraGeometry(0,
                          pix_id,
                          pix_x * u.mm - source_x,
                          pix_y * u.mm - source_y,
                          np.ones(1296) * 400.,
                          pix_type='hexagonal',
                          neighbors=neighbors_pix)

    return geom
示例#7
0
def test_leakage():
    from ctapipe.image.leakage import leakage

    geom = CameraGeometry.from_name('LSTCam')

    img = np.ones(geom.n_pixels)
    mask = np.ones(len(geom), dtype=bool)

    l = leakage(geom, img, mask)

    ratio1 = np.sum(geom.get_border_pixel_mask(1)) / geom.n_pixels
    ratio2 = np.sum(geom.get_border_pixel_mask(2)) / geom.n_pixels

    assert l.intensity_width_1 == ratio1
    assert l.intensity_width_2 == ratio2
    assert l.pixels_width_1 == ratio1
    assert l.pixels_width_2 == ratio2
示例#8
0
def test_leakage():
    from ctapipe.image.leakage import leakage

    geom = CameraGeometry.from_name('LSTCam')

    img = np.ones(geom.n_pixels)
    mask = np.ones(len(geom), dtype=bool)

    l = leakage(geom, img, mask)

    ratio1 = np.sum(geom.get_border_pixel_mask(1)) / geom.n_pixels
    ratio2 = np.sum(geom.get_border_pixel_mask(2)) / geom.n_pixels

    assert l.leakage1_intensity == ratio1
    assert l.leakage2_intensity == ratio2
    assert l.leakage1_pixel == ratio1
    assert l.leakage2_pixel == ratio2
def image_intensity_after_cleaning_filter(reader,
                                          images,
                                          i_min=-np.inf,
                                          i_max=np.inf,
                                          **opts):
    """
    Filter images on intensity (in pe) after cleaning

    Parameters
    ----------
    reader: `DL1DataReader`
    images
    options for image cleaning
    i_min
    i_max

    Returns
    -------
    mask (Array of bool)
    """

    try:
        from ctapipe.image import cleaning
    except ImportError:
        raise ImportError(
            "The `ctapipe.image.cleaning` python module is required to perform cleaning operation"
        )
    try:
        from ctapipe.instrument.camera import CameraGeometry
    except ImportError:
        raise ImportError(
            "The `ctapipe.instrument.CameraGeometry` python module is required to perform cleaning operation"
        )

    geom = CameraGeometry.from_name(reader.tel_type.split("_")[-1])

    def int_after_clean(img):
        cleanmask = cleaning.tailcuts_clean(geom, img, **opts)
        clean = img.copy()
        clean[~cleanmask] = 0.0
        amps = np.sum(clean)
        return (i_min < amps) & (amps < i_max)

    int_mask = np.apply_along_axis(int_after_clean, 1, images)
    return int_mask
示例#10
0
def test_hash():

    types = ["LST", "MST", "SST"]
    names = ["LST", "MST", "SST-1M"]
    cameras = ["LSTCam", "FlashCam", "DigiCam"]

    telescopes = []
    for name, type, camera in zip(names, types, cameras):
        for i in range(3):

            telescopes.append(
                TelescopeDescription(name=name,
                                     tel_type=type,
                                     optics=OpticsDescription.from_name(name),
                                     camera=CameraGeometry.from_name(camera)))

    assert len(telescopes) == 9
    assert len(set(telescopes)) == 3
示例#11
0
 def initialise_plots(self):
     # first load in a very nasty way the camera geometry
     pix_x, pix_y, pix_id = [], [], []
     pixels = self.cts.camera.Pixels
     pixelspresent = list(self.cts.pixel_to_led['DC'].keys())
     for pix in pixels:
         if pix.ID in pixelspresent:
             pix_x.append(pix.center[0])
             pix_y.append(pix.center[1])
             pix_id.append(pix.ID)
         else:
             pix_x.append(-200.)
             pix_y.append(-200.)
             pix_id.append(pix.ID)
     pix_x = list(pix_x)
     pix_y = list(pix_y)
     pix_id = list(pix_id)
     neighbors_pix = find_neighbor_pixels(pix_x, pix_y, 30.)
     geom = CameraGeometry(0,
                           pix_id,
                           pix_x * u.mm,
                           pix_y * u.mm,
                           np.ones((1296)) * 400.,
                           'hexagonal',
                           neighbors=neighbors_pix)
     plt.figure(0, figsize=(20, 6))
     self.plots = []
     plt.subplot(1, 2, 1)
     self.plots.append(
         visualization.CameraDisplay(geom,
                                     title='AC status',
                                     norm='lin',
                                     cmap='coolwarm'))
     self.plots[-1].add_colorbar()
     self.plots[-1].image = np.multiply(self.ac_status, self.ac_level)
     plt.subplot(1, 2, 2)
     self.plots.append(
         visualization.CameraDisplay(geom,
                                     title='DC status',
                                     norm='lin',
                                     cmap='coolwarm'))
     self.plots[-1].add_colorbar()
     self.plots[-1].image = np.multiply(self.dc_status, self.dc_level)
示例#12
0
def test_ignore_negative():
    grad = 2.0
    intercept = 1.0

    geom = CameraGeometry.from_name("LSTCam")
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=0 * u.deg)

    image = np.ones(geom.n_pixels)
    image[5:10] = -1.0

    timing = timing_parameters(
        geom,
        image,
        peakpos=intercept + grad * geom.pix_x.value,
        hillas_parameters=hillas,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit)
    assert_allclose(timing.intercept, intercept)
示例#13
0
def test_psi_20():

    # Then try a different rotation angle
    grad = 2
    intercept = 1

    geom = CameraGeometry.from_name("LSTCam")
    psi = 20 * u.deg
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=psi)

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peakpos=intercept + grad * (np.cos(psi) * geom.pix_x.value
                                    + np.sin(psi) * geom.pix_y.value),
        hillas_parameters=hillas,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit)
    assert_allclose(timing.intercept, intercept)
示例#14
0
def test_psi_0():
    """
    Simple test that gradient fitting gives expected answers for perfect
    gradient
    """
    grad = 2.0
    intercept = 1.0

    geom = CameraGeometry.from_name("LSTCam")
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=0 * u.deg)

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peakpos=intercept + grad * geom.pix_x.value,
        hillas_parameters=hillas,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit)
    assert_allclose(timing.intercept, intercept)
示例#15
0
def generate_geometry(camera):
    """
    Generate the SST-1M geometry from the CTS configuration
    :param cts: a CTS instance
    :param available_board:  which board per sector are available (dict)
    :return: the geometry for visualisation and the list of "good" pixels
    """
    pix_x = []
    pix_y = []
    pix_id = []

    for pix in camera.Pixels:
        pix_x.append(pix.center[0])
        pix_y.append(pix.center[1])
        pix_id.append(pix.ID)

    neighbors_pix = _find_neighbor_pixels(pix_x, pix_y, 30.)
    geom = CameraGeometry(cam_id=0, pix_id=pix_id, pix_x=pix_x * u.mm, pix_y=pix_y * u.mm,
                          pix_area=np.ones(1296) * 482.41, neighbors=neighbors_pix, pix_type='hexagonal')

    return geom, pix_id
示例#16
0
def test_hash():
    from ctapipe.instrument.telescope import TelescopeDescription
    from ctapipe.instrument.optics import OpticsDescription
    from ctapipe.instrument.camera import CameraGeometry

    types = ['LST', 'MST', 'SST']
    names = ['LST', 'MST', 'SST-1M']
    cameras = ['LSTCam', 'FlashCam', 'DigiCam']

    telescopes = []
    for name, type, camera in zip(names, types, cameras):
        for i in range(3):

            telescopes.append(
                TelescopeDescription(name=name,
                                     type=type,
                                     optics=OpticsDescription.from_name(name),
                                     camera=CameraGeometry.from_name(camera)))

    assert len(telescopes) == 9
    assert len(set(telescopes)) == 3
    def _build_subarray_info(self, run):
        """
        constructs a SubarrayDescription object from the info in an
        MCRun

        Parameters
        ----------
        run: MCRun object

        Returns
        -------
        SubarrayDescription :
            instrumental information
        """
        subarray = SubarrayDescription("MonteCarloArray")
        runHeader = run.root.RunHeader

        tabFocalTel = runHeader.tabFocalTel.read()
        tabPosTelX = runHeader.tabPosTelX.read()
        tabPosTelY = runHeader.tabPosTelY.read()
        tabPosTelZ = runHeader.tabPosTelZ.read()

        tabPoslXYZ = np.ascontiguousarray(
            np.vstack((tabPosTelX, tabPosTelY, tabPosTelZ)).T)
        '''
        # Correspance HiPeData.Telscope.Type and camera name
        # 0  LSTCam, 1 NectarCam, 2 FlashCam, 3 SCTCam,
        # 4 ASTRICam, 5 DigiCam, 6 CHEC
        '''
        mapping_camera = {
            0: 'LSTCam',
            1: 'NectarCam',
            2: 'FlashCam',
            3: 'SCTCam',
            4: 'ASTRICam',
            5: 'DigiCam',
            6: 'CHEC'
        }

        mapping_telName = {
            0: 'LST',
            1: 'MST',
            2: 'MST',
            3: 'MST',
            4: 'SST-ASTRI',
            5: 'SST-1M',
            6: 'SST-2M'
        }

        for telNode in self.run.walk_nodes('/Tel', 'Group'):
            try:
                telType = uint64(telNode.telType.read())
                telIndex = uint64(telNode.telIndex.read())
                telId = uint64(telNode.telId.read())

                cameraName = mapping_camera[telType]
                telName = mapping_telName[telType]
                camera = CameraGeometry.from_name(cameraName)
                camera.cam_id = cameraName

                foclen = tabFocalTel[telIndex] * u.m

                tel_pos = tabPoslXYZ[telIndex] * u.m

                camera.pix_x = telNode.tabPixelX.read() * u.m
                camera.pix_y = telNode.tabPixelY.read() * u.m
                #camera.rotate(-90.0*u.deg)
                optic = OpticsDescription.from_name(telName)
                optic.equivalent_focal_length = foclen
                telescope_description = TelescopeDescription(telName,
                                                             telName,
                                                             optics=optic,
                                                             camera=camera)

                #tel.optics.mirror_area = mirror_area
                #tel.optics.num_mirror_tiles = num_tiles
                subarray.tels[telId] = telescope_description
                subarray.positions[telId] = tel_pos
            except tables.exceptions.NoSuchNodeError as e:
                pass

        return subarray
示例#18
0
    calib.calibrate(event)
    hillas_params = {}
    subarray = event.inst.subarray

    for tel_id in event.dl0.tels_with_data:

        # telescope pointing direction
        point_azimuth[tel_id] = event.mc.tel[tel_id].azimuth_raw * u.rad
        point_altitude[tel_id] = (np.pi / 2 - event.mc.tel[tel_id].altitude_raw) * u.rad
#        print(point_azimuth,point_altitude)

        # Camera Geometry required for hillas parametrization
        pix_x = subarray.tel[tel_id].camera.pix_x
        pix_y = subarray.tel[tel_id].camera.pix_y
        foclen = subarray.tel[tel_id].optics.equivalent_focal_length
        camgeom = CameraGeometry.guess(pix_x, pix_y, foclen)

        # 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)
示例#19
0
    cameras = ["LSTCam", "FlashCam", "DigiCam"]

    telescopes = []
    for name, type, camera in zip(names, types, cameras):
        for i in range(3):

            telescopes.append(
                TelescopeDescription(name=name,
                                     tel_type=type,
                                     optics=OpticsDescription.from_name(name),
                                     camera=CameraGeometry.from_name(camera)))

    assert len(telescopes) == 9
    assert len(set(telescopes)) == 3


OPTICS_NAMES = OpticsDescription.get_known_optics_names()
CAMERA_NAMES = CameraGeometry.get_known_camera_names()


@pytest.mark.parametrize("camera_name", CAMERA_NAMES)
@pytest.mark.parametrize("optics_name", OPTICS_NAMES)
def test_telescope_from_name(optics_name, camera_name):
    """ Check we can construct all telescopes from their names """
    tel = TelescopeDescription.from_name(optics_name, camera_name)
    assert optics_name in str(tel)
    assert camera_name in str(tel)
    assert tel.camera.pix_x.shape[0] > 0
    assert tel.optics.equivalent_focal_length.to("m") > 0
    assert tel.type in ["MST", "SST", "LST", "UNKNOWN"]