def METHOD_NAME(focuser: "Actuator", zrange: Tuple[float, float], zstep: float) -> List[float]:
    """
    Calculates the zlevels for a zstack acquisition, using the zmax, zmin
    and zstep, as well as the current focus z position.
    :param focuser: Actuator component with a "z" axis, to control the focus.
    :param zrange: contains the zmin and zmax, respectively. It's relative to the
    current position of the focuser. If the range would go out of the actuator
    range, it's clipped (so there are less zlevels returned than expected).
    Error is raised if the order is not (zmin, zmax).
    :param zstep: distance between two successive zlevels. If negative,
    the order of the returned list of zlevels is reversed. The actual zstep in the
    returned list is adjusted to the closest value of the given zstep that divides
    the zrange. If zstep is too small, this will lead to too large number of zlevels.
    In that case IndexError is raised.
    :returns: list of zlevels, where each zlevel is absolute position for
    the focuser.
    """
    if zstep == 0:
        raise ZeroDivisionError("The step size 'zstep' can not be zero")
    if zrange[0] > zrange[1]:
        raise ValueError(f"The given range {zrange} is not correct. The first value should be smaller than the second one.")
    if "z" not in focuser.axes.keys():
        raise KeyError(f"The focus actuator {focuser} does not have z axis")
    focuser_pos = focuser.position.value["z"]
    zrange_abs = (zrange[0] + focuser_pos, zrange[1] + focuser_pos)
    # Get the range from the axis range + extra limit POS_ACTIVE_RANGE
    focuser_rng = focuser.axes["z"].range
    sw_rng = focuser.getMetadata().get(model.MD_POS_ACTIVE_RANGE)
    if sw_rng and "z" in sw_rng:
        focuser_rng = (max(focuser_rng[0], sw_rng["z"][0]),
                       min(focuser_rng[1], sw_rng["z"][1]))
    # clip the zMax and zMin to the actuator limits if necessary
    zrange_abs = (min(max(focuser_rng[0], zrange_abs[0]), focuser_rng[1]),
                  min(max(focuser_rng[0], zrange_abs[1]), focuser_rng[1]))
    if zrange_abs[0] == zrange_abs[1]:
        return focuser_pos + zrange[0]
    # find number of zlevels
    n = (zrange_abs[1] - zrange_abs[0]) / abs(zstep) + 1
    if n > MAX_ZLEVELS:
        raise IndexError(f"The number of zlevels, {n}, is too large. Reduce the zstep value to < {MAX_ZLEVELS}.")
    # zstep often doesn't exactly fit to have a round number of zlevels. So try
    # the floor and ceil values for the number of zlevels, and take the one that
    # give a step closest to the requested zstep.
    n_f = math.floor(n)
    n_c = math.ceil(n)
    if n_f <= 1:  # would cause a division by zero
        # => do the minimum amount of steps
        n = 2
    else:
        # errors
        ef = abs((zrange_abs[1] - zrange_abs[0]) / (n_f - 1) - abs(zstep))
        ec = abs((zrange_abs[1] - zrange_abs[0]) / (n_c - 1) - abs(zstep))
        n = n_f if ef < ec else n_c
    if zstep > 0:
        return numpy.linspace(zrange_abs[0], zrange_abs[1], n).tolist()
    elif zstep < 0:
        return numpy.linspace(zrange_abs[1], zrange_abs[0], n).tolist()