def bundle_of_tubes(shape: List[int], spacing: int):
    r"""
    Create a 3D image of a bundle of tubes, in the form of a rectangular
    plate with randomly sized holes through it.

    Parameters
    ----------
    shape : list
        The size the image, with the 3rd dimension indicating the plate
        thickness.  If the 3rd dimension is not given then a thickness of
        1 voxel is assumed.

    spacing : scalar
        The center to center distance of the holes.  The hole sizes will be
        randomly distributed between this values down to 3 voxels.

    Returns
    -------
    image : ND-array
        A boolean array with ``True`` values denoting the pore space
    """
    shape = sp.array(shape)
    if sp.size(shape) == 1:
        shape = sp.full((3, ), int(shape))
    if sp.size(shape) == 2:
        shape = sp.hstack((shape, [1]))
    temp = sp.zeros(shape=shape[:2])
    Xi = sp.ceil(sp.linspace(spacing/2,
                             shape[0]-(spacing/2)-1,
                             int(shape[0]/spacing)))
    Xi = sp.array(Xi, dtype=int)
    Yi = sp.ceil(sp.linspace(spacing/2,
                             shape[1]-(spacing/2)-1,
                             int(shape[1]/spacing)))
    Yi = sp.array(Yi, dtype=int)
    temp[tuple(sp.meshgrid(Xi, Yi))] = 1
    inds = sp.where(temp)
    for i in range(len(inds[0])):
        r = sp.random.randint(1, (spacing/2))
        try:
            s1 = slice(inds[0][i]-r, inds[0][i]+r+1)
            s2 = slice(inds[1][i]-r, inds[1][i]+r+1)
            temp[s1, s2] = ps_disk(r)
        except ValueError:
            odd_shape = sp.shape(temp[s1, s2])
            temp[s1, s2] = ps_disk(r)[:odd_shape[0], :odd_shape[1]]
    im = sp.broadcast_to(array=sp.atleast_3d(temp), shape=shape)
    return im
def bundle_of_tubes ( shape : List [ int ] , spacing : int ) : shape = sp . array ( shape ) if sp . size ( shape ) == 1 : shape = sp . full ( ( 3 , ) , int ( shape ) ) if sp . size ( shape ) == 2 : shape = sp . hstack ( ( shape , [ 1 ] ) ) temp = sp . zeros ( shape = shape [ : 2 ] ) Xi = sp . ceil ( sp . linspace ( spacing / 2 , shape [ 0 ] - ( spacing / 2 ) - 1 , int ( shape [ 0 ] / spacing ) ) ) Xi = sp . array ( Xi , dtype = int ) Yi = sp . ceil ( sp . linspace ( spacing / 2 , shape [ 1 ] - ( spacing / 2 ) - 1 , int ( shape [ 1 ] / spacing ) ) ) Yi = sp . array ( Yi , dtype = int ) temp [ tuple ( sp . meshgrid ( Xi , Yi ) ) ] = 1 inds = sp . where ( temp ) for i in range ( len ( inds [ 0 ] ) ) : r = sp . random . randint ( 1 , ( spacing / 2 ) ) try : s1 = slice ( inds [ 0 ] [ i ] - r , inds [ 0 ] [ i ] + r + 1 ) s2 = slice ( inds [ 1 ] [ i ] - r , inds [ 1 ] [ i ] + r + 1 ) temp [ s1 , s2 ] = ps_disk ( r ) except ValueError : odd_shape = sp . shape ( temp [ s1 , s2 ] ) temp [ s1 , s2 ] = ps_disk ( r ) [ : odd_shape [ 0 ] , : odd_shape [ 1 ] ] im = sp . broadcast_to ( array = sp . atleast_3d ( temp ) , shape = shape ) return im
r"""
    Create a 3D image of a bundle of tubes, in the form of a rectangular
    plate with randomly sized holes through it.

    Parameters
    ----------
    shape : list
        The size the image, with the 3rd dimension indicating the plate
        thickness.  If the 3rd dimension is not given then a thickness of
        1 voxel is assumed.

    spacing : scalar
        The center to center distance of the holes.  The hole sizes will be
        randomly distributed between this values down to 3 voxels.

    Returns
    -------
    image : ND-array
        A boolean array with ``True`` values denoting the pore space