def initialize_forecast_exporter_netcdf(
    outpath,
    outfnprefix,
    startdate,
    timestep,
    n_timesteps,
    shape,
    metadata,
    n_ens_members=1,
    datatype=np.float32,
    incremental=None,
    fill_value=None,
    scale_factor=None,
    offset=None,
    **kwargs,
):
    """
    Initialize a netCDF forecast exporter. All outputs are written to a
    single file named as '<outfnprefix>_.nc'.

    Parameters
    ----------
    outpath: str
        Output path.
    outfnprefix: str
        Prefix for output file names.
    startdate: datetime.datetime
        Start date of the forecast.
    timestep: int
        Time step of the forecast (minutes).
    n_timesteps: int or list of integers
      Number of time steps to forecast or a list of time steps for which the
      forecasts are computed (relative to the input time step). The elements of
      the list are required to be in ascending order.
    shape: tuple of int
        Two-element tuple defining the shape (height,width) of the forecast
        grids.
    metadata: dict
        Metadata dictionary containing the projection, x1, x2, y1, y2,
        unit attributes (projection and variable units) described in the
        documentation of :py:mod:`pysteps.io.importers`.
    n_ens_members: int
        Number of ensemble members in the forecast. This argument is ignored if
        incremental is set to 'member'.
    datatype: np.dtype, optional
        The datatype of the output values. Defaults to np.float32.
    incremental: {None,'timestep','member'}, optional
        Allow incremental writing of datasets into the netCDF files.\n
        The available options are: 'timestep' = write a forecast or a forecast
        ensemble for  a given time step; 'member' = write a forecast sequence
        for a given ensemble member. If set to None, incremental writing is
        disabled.
    fill_value: int, optional
        Fill_value for missing data. Defaults to None, which means that the
        standard netCDF4 fill_value is used.
    scale_factor: float, optional
        The scale factor to scale the data as: store_value = scale_factor *
        precipitation_value + offset. Defaults to None. The scale_factor
        can be used to reduce data storage.
    offset: float, optional
        The offset to offset the data as: store_value = scale_factor *
        precipitation_value + offset. Defaults to None.

    Other Parameters
    ----------------
    institution: str
        The instute, company or community that has created the nowcast.
        Default: the pySTEPS community (https://pysteps.github.io)
    references: str
        Any references to be included in the netCDF file. Defaults to " ".
    comment: str
        Any comments about the data or storage protocol that should be
        included in the netCDF file. Defaults to " ".

    Returns
    -------
    exporter: dict
        The return value is a dictionary containing an exporter object. This c
        an be used with :py:func:`pysteps.io.exporters.export_forecast_dataset`
        to write datasets into the given file format.
    """

    if not NETCDF4_IMPORTED:
        raise MissingOptionalDependency(
            "netCDF4 package is required for netcdf "
            "exporters but it is not installed"
        )

    if not PYPROJ_IMPORTED:
        raise MissingOptionalDependency(
            "pyproj package is required for netcdf " "exporters but it is not installed"
        )

    if incremental not in [None, "timestep", "member"]:
        raise ValueError(
            f"unknown option {incremental}: incremental must be "
            + "'timestep' or 'member'"
        )

    n_timesteps_is_list = isinstance(n_timesteps, list)
    if n_timesteps_is_list:
        num_timesteps = len(n_timesteps)
    else:
        num_timesteps = n_timesteps

    if incremental == "timestep":
        num_timesteps = None
    elif incremental == "member":
        n_ens_members = None
    elif incremental is not None:
        raise ValueError(
            f"unknown argument value incremental='{str(incremental)}': "
            + "must be 'timestep' or 'member'"
        )

    n_ens_gt_one = False
    if n_ens_members is not None:
        if n_ens_members > 1:
            n_ens_gt_one = True

    # Kwargs to be used as description strings in the netCDF
    institution = kwargs.get(
        "institution", "the pySTEPS community (https://pysteps.github.io)"
    )
    references = kwargs.get("references", "")
    comment = kwargs.get("comment", "")

    exporter = {}

    outfn = os.path.join(outpath, outfnprefix + ".nc")
    ncf = netCDF4.Dataset(outfn, "w", format="NETCDF4")

    ncf.Conventions = "CF-1.7"
    ncf.title = "pysteps-generated nowcast"
    ncf.institution = institution
    ncf.source = "pysteps"  # TODO(exporters): Add pySTEPS version here
    ncf.history = ""
    ncf.references = references
    ncf.comment = comment

    h, w = shape

    ncf.createDimension("ens_number", size=n_ens_members)
    ncf.createDimension("time", size=num_timesteps)
    ncf.createDimension("y", size=h)
    ncf.createDimension("x", size=w)

    if metadata["unit"] == "mm/h":
        var_name = "precip_intensity"
        var_standard_name = None
        var_long_name = "instantaneous precipitation rate"
        var_unit = "mm h-1"
    elif metadata["unit"] == "mm":
        var_name = "precip_accum"
        var_standard_name = None
        var_long_name = "accumulated precipitation"
        var_unit = "mm"
    elif metadata["unit"] == "dBZ":
        var_name = "reflectivity"
        var_long_name = "equivalent reflectivity factor"
        var_standard_name = "equivalent_reflectivity_factor"
        var_unit = "dBZ"
    else:
        raise ValueError("unknown unit %s" % metadata["unit"])

    xr = np.linspace(metadata["x1"], metadata["x2"], w + 1)[:-1]
    xr += 0.5 * (xr[1] - xr[0])
    yr = np.linspace(metadata["y1"], metadata["y2"], h + 1)[:-1]
    yr += 0.5 * (yr[1] - yr[0])

    # flip yr vector if yorigin is upper
    if metadata["yorigin"] == "upper":
        yr = np.flip(yr)

    var_xc = ncf.createVariable("x", np.float32, dimensions=("x",))
    var_xc[:] = xr
    var_xc.axis = "X"
    var_xc.standard_name = "projection_x_coordinate"
    var_xc.long_name = "x-coordinate in Cartesian system"
    var_xc.units = metadata["cartesian_unit"]

    var_yc = ncf.createVariable("y", np.float32, dimensions=("y",))
    var_yc[:] = yr
    var_yc.axis = "Y"
    var_yc.standard_name = "projection_y_coordinate"
    var_yc.long_name = "y-coordinate in Cartesian system"
    var_yc.units = metadata["cartesian_unit"]

    x_2d, y_2d = np.meshgrid(xr, yr)
    pr = pyproj.Proj(metadata["projection"])
    lon, lat = pr(x_2d.flatten(), y_2d.flatten(), inverse=True)

    var_lon = ncf.createVariable("lon", float, dimensions=("y", "x"))
    var_lon[:] = lon.reshape(shape)
    var_lon.standard_name = "longitude"
    var_lon.long_name = "longitude coordinate"
    # TODO(exporters): Don't hard-code the unit.
    var_lon.units = "degrees_east"

    var_lat = ncf.createVariable("lat", float, dimensions=("y", "x"))
    var_lat[:] = lat.reshape(shape)
    var_lat.standard_name = "latitude"
    var_lat.long_name = "latitude coordinate"
    # TODO(exporters): Don't hard-code the unit.
    var_lat.units = "degrees_north"

    ncf.projection = metadata["projection"]

    (
        grid_mapping_var_name,
        grid_mapping_name,
        grid_mapping_params,
    ) = _convert_proj4_to_grid_mapping(metadata["projection"])
    # skip writing the grid mapping if a matching name was not found
    if grid_mapping_var_name is not None:
        var_gm = ncf.createVariable(grid_mapping_var_name, int, dimensions=())
        var_gm.grid_mapping_name = grid_mapping_name
        for i in grid_mapping_params.items():
            var_gm.setncattr(i[0], i[1])

    if incremental == "member" or n_ens_gt_one:
        var_ens_num = ncf.createVariable("ens_number", int, dimensions=("ens_number",))
        if incremental != "member":
            var_ens_num[:] = list(range(1, n_ens_members + 1))
        var_ens_num.long_name = "ensemble member"
        var_ens_num.standard_name = "realization"
        var_ens_num.units = ""

    var_time = ncf.createVariable("time", int, dimensions=("time",))
    if incremental != "timestep":
        if n_timesteps_is_list:
            var_time[:] = np.array(n_timesteps) * timestep * 60
        else:
            var_time[:] = [i * timestep * 60 for i in range(1, n_timesteps + 1)]
    var_time.long_name = "forecast time"
    startdate_str = datetime.strftime(startdate, "%Y-%m-%d %H:%M:%S")
    var_time.units = "seconds since %s" % startdate_str

    if incremental == "member" or n_ens_gt_one:
        var_f = ncf.createVariable(
            var_name,
            datatype=datatype,
            dimensions=("ens_number", "time", "y", "x"),
            compression="zlib",
            zlib=True,
            complevel=9,
            fill_value=fill_value,
        )
    else:
        var_f = ncf.createVariable(
            var_name,
            datatype=datatype,
            dimensions=("time", "y", "x"),
            compression="zlib",
            zlib=True,
            complevel=9,
            fill_value=fill_value,
        )

    if var_standard_name is not None:
        var_f.standard_name = var_standard_name
    var_f.long_name = var_long_name
    var_f.coordinates = "y x"
    var_f.units = var_unit
    if grid_mapping_var_name is not None:
        var_f.grid_mapping = grid_mapping_var_name
    # Add gain and offset
    if scale_factor is not None:
        var_f.scale_factor = scale_factor
    if offset is not None:
        var_f.add_offset = offset

    exporter["method"] = "netcdf"
    exporter["ncfile"] = ncf
    exporter["var_F"] = var_f
    if incremental == "member" or n_ens_gt_one:
        exporter["var_ens_num"] = var_ens_num
    exporter["var_time"] = var_time
    exporter["var_name"] = var_name
    exporter["startdate"] = startdate
    exporter["timestep"] = timestep
    exporter["metadata"] = metadata
    exporter["incremental"] = incremental
    exporter["num_timesteps"] = num_timesteps
    exporter["timesteps"] = n_timesteps
    exporter["num_ens_members"] = n_ens_members
    exporter["shape"] = shape

    return exporter
Initialize a netCDF forecast exporter. All outputs are written to a
single file named as '<outfnprefix>_.nc'.

Parameters
----------
outpath: str
Output path.
outfnprefix: str
Prefix for output file names.
startdate: datetime.datetime
Start date of the forecast.
timestep: int
Time step of the forecast (minutes).
n_timesteps: int or list of integers
Number of time steps to forecast or a list of time steps for which the
forecasts are computed (relative to the input time step). The elements of
the list are required to be in ascending order.
shape: tuple of int
Two-element tuple defining the shape (height,width) of the forecast
grids.
metadata: dict
Metadata dictionary containing the projection, x1, x2, y1, y2,
unit attributes (projection and variable units) described in the
documentation of :py:mod:`pysteps.io.importers`.
n_ens_members: int
Number of ensemble members in the forecast. This argument is ignored if
incremental is set to 'member'.
datatype: np.dtype, optional
The datatype of the output values. Defaults to np.float32.
incremental: {None,'timestep','member'}, optional
Allow incremental writing of datasets into the netCDF files.\n
The available options are: 'timestep' = write a forecast or a forecast
ensemble for  a given time step; 'member' = write a forecast sequence
for a given ensemble member. If set to None, incremental writing is
disabled.
fill_value: int, optional
Fill_value for missing data. Defaults to None, which means that the
standard netCDF4 fill_value is used.
scale_factor: float, optional
The scale factor to scale the data as: store_value = scale_factor *
precipitation_value + offset. Defaults to None. The scale_factor
can be used to reduce data storage.
offset: float, optional
The offset to offset the data as: store_value = scale_factor *
precipitation_value + offset. Defaults to None.

Other Parameters
----------------
institution: str
The instute, company or community that has created the nowcast.
Default: the pySTEPS community (https://pysteps.github.io)
references: str
Any references to be included in the netCDF file. Defaults to " ".
comment: str
Any comments about the data or storage protocol that should be
included in the netCDF file. Defaults to " ".

Returns
-------
exporter: dict
The return value is a dictionary containing an exporter object. This c
an be used with :py:func:`pysteps.io.exporters.export_forecast_dataset`
to write datasets into the given file format.
pysteps/io/exporters.py