def elekta_icon_geometry(sad=780.0, sdd=1000.0,
                         piercing_point=(390.0, 0.0),
                         angles=None, num_angles=None,
                         detector_shape=(780, 720)):
    """Tomographic geometry of the Elekta Icon CBCT system.

    See the [whitepaper]_ for specific descriptions of each parameter.

    All measurments are given in millimeters unless otherwise stated.

    Parameters
    ----------
    sad : float, optional
        Source to Axis distance.
    sdd : float, optional
        Source to Detector distance.
    piercing_point : sequence of foat, optional
        Position in the detector (in pixel coordinates) that a beam from the
        source, passing through the axis of rotation perpendicularly, hits.
    angles : array-like, optional
        List of angles given in radians that the projection images were taken
        at. Exclusive with num_angles.
        Default: np.linspace(1.2, 5.0, 332)
    num_angles : int, optional
        Number of angles. Exclusive with angles.
        Default: 332
    detector_shape : sequence of int, optional
        Shape of the detector (in pixels). Useful if a sub-sampled system
        should be studied.

    Returns
    -------
    elekta_icon_geometry : `ConeFlatGeometry`

    Examples
    --------
    Create default geometry:

    >>> from odl.contrib import tomo
    >>> geometry = tomo.elekta_icon_geometry()

    Use a smaller detector (improves efficiency):

    >>> small_geometry = tomo.elekta_icon_geometry(detector_shape=[100, 100])

    See Also
    --------
    elekta_icon_space : Default reconstruction space for the Elekta Icon CBCT.
    elekta_icon_fbp: Default reconstruction method for the Elekta Icon CBCT.

    References
    ----------
    .. [whitepaper] *Design and performance characteristics of a Cone Beam
       CT system for Leksell Gamma Knife Icon*
    """
    sad = float(sad)
    assert sad > 0
    sdd = float(sdd)
    assert sdd > sad
    piercing_point = np.array(piercing_point, dtype=float)
    assert piercing_point.shape == (2,)

    if angles is not None and num_angles is not None:
        raise ValueError('cannot provide both `angles` and `num_angles`')
    elif angles is not None:
        angles = odl.nonuniform_partition(angles)
        assert angles.ndim == 1
    elif num_angles is not None:
        angles = odl.uniform_partition(1.2, 5.0, num_angles)
    else:
        angles = odl.uniform_partition(1.2, 5.0, 332)

    detector_shape = np.array(detector_shape, dtype=int)

    # Constant system parameters
    pixel_size = 0.368
    det_extent_mm = np.array([287.04, 264.96])

    # Compute the detector partition
    piercing_point_mm = pixel_size * piercing_point
    det_min_pt = -piercing_point_mm
    det_max_pt = det_min_pt + det_extent_mm
    detector_partition = odl.uniform_partition(min_pt=det_min_pt,
                                               max_pt=det_max_pt,
                                               shape=detector_shape)

    # Create the geometry
    geometry = odl.tomo.ConeFlatGeometry(
        angles, detector_partition,
        src_radius=sad, det_radius=sdd - sad)

    return geometry
Tomographic geometry of the Elekta Icon CBCT system.

    See the [whitepaper]_ for specific descriptions of each parameter.

    All measurments are given in millimeters unless otherwise stated.

    Parameters
    ----------
    sad : float, optional
        Source to Axis distance.
    sdd : float, optional
        Source to Detector distance.
    piercing_point : sequence of foat, optional
        Position in the detector (in pixel coordinates) that a beam from the
        source, passing through the axis of rotation perpendicularly, hits.
    angles : array-like, optional
        List of angles given in radians that the projection images were taken
        at. Exclusive with num_angles.
        Default: np.linspace(1.2, 5.0, 332)
    num_angles : int, optional
        Number of angles. Exclusive with angles.
        Default: 332
    detector_shape : sequence of int, optional
        Shape of the detector (in pixels). Useful if a sub-sampled system
        should be studied.

    Returns
    -------
    elekta_icon_geometry : `ConeFlatGeometry`

    Examples
    --------
    Create default geometry:

    >>> from odl.contrib import tomo
    >>> geometry = tomo.elekta_icon_geometry()

    Use a smaller detector (improves efficiency):

    >>> small_geometry = tomo.elekta_icon_geometry(detector_shape=[100, 100])

    See Also
    --------
    elekta_icon_space : Default reconstruction space for the Elekta Icon CBCT.
    elekta_icon_fbp: Default reconstruction method for the Elekta Icon CBCT.

    References
    ----------
    .. [whitepaper] *Design and performance characteristics of a Cone Beam
       CT system for Leksell Gamma Knife Icon*