<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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: Use a smaller detector (improves efficiency):
 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