def METHOD_NAME(grid, template=None, where="top", mode="depth", rfactor=1):
    """Private function for deriving a surface from a 3D grid.
    Note that rotated maps are currently not supported!
    .. versionadded:: 2.1
    """
    if where == "top":
        klayer = 1
        option = 0
    elif where == "base":
        klayer = grid.nlay
        option = 1
    else:
        klayer, what = where.split("_")
        klayer = int(klayer)
        if grid.nlay < klayer < 0:
            raise ValueError(f"Klayer out of range in where={where}")
        option = 0
        if what == "base":
            option = 1
    if rfactor < 0.5:
        raise KeyError("Refinefactor rfactor is too small, should be >= 0.5")
    args = _update_regsurf(template, grid, rfactor=float(rfactor))
    args["rotation"] = 0.0
    # call C function to make a map
    val = args["values"]
    val = val.ravel()
    val = ma.filled(val, fill_value=xtgeo.UNDEF)
    svalues = val * 0.0 + xtgeo.UNDEF
    ivalues = svalues.copy()
    jvalues = svalues.copy()
    grid._xtgformat1()
    _cxtgeo.surf_sample_grd3d_lay(
        grid.ncol,
        grid.nrow,
        grid.nlay,
        grid._coordsv,
        grid._zcornsv,
        grid._actnumsv,
        klayer,
        args["ncol"],
        args["nrow"],
        args["xori"],
        args["xinc"],
        args["yori"],
        args["yinc"],
        args["rotation"],
        svalues,
        ivalues,
        jvalues,
        option,
    )
    logger.info("Extracted surfaces from 3D grid...")
    svalues = np.ma.masked_greater(svalues, xtgeo.UNDEF_LIMIT)
    ivalues = np.ma.masked_greater(ivalues, xtgeo.UNDEF_LIMIT)
    jvalues = np.ma.masked_greater(jvalues, xtgeo.UNDEF_LIMIT)
    if mode == "i":
        ivalues = ivalues.reshape((args["ncol"], args["nrow"]))
        ivalues = ma.masked_invalid(ivalues)
        args["values"] = ivalues
        return args, None, None
    if mode == "j":
        jvalues = jvalues.reshape((args["ncol"], args["nrow"]))
        jvalues = ma.masked_invalid(jvalues)
        args["values"] = jvalues
        return args, None, None
    svalues = svalues.reshape((args["ncol"], args["nrow"]))
    svalues = ma.masked_invalid(svalues)
    args["values"] = svalues
    return args, ivalues, jvalues