    Calculate sigma-clipped statistics on the provided data

    Parameters
    ----------
    data : array-like
    axis : int or sequence of int, default 0
        The axis or axes along which to sigma clip the data.
        If None, then the flattened data will be used.
    keepdims : bool, default False
        If this is set to True, the axes which are reduced are left
        in the result as dimensions with size one. With this option,
        the result will broadcast correctly against the input array.
    mask : array-like, default None
        A boolean mask associated with the values in data,
        where a True value indicates the corresponding element of data
        is masked. Masked pixels are excluded when computing the statistics.
    weights : array-like, default None
        array of weights associated with the values in data.
        If axis is specified as an int, this can be a 1D array with
        the same length as data along specified axis.
    reduce : {'mean','median'}, default 'mean'
        reduce method after clipping
    center : {'mean','median'}, default 'mean'
        derivation method of clipping center
    iters : int, default 3
        A number of sigmaclipping iterations
        If None, clip until convergence is achieved.
    width : float or int, default 3.0
        A clipping width in sigma units
    dtype : str or dtype, default 'float32'
        dtype of array used internally
        If None, use eclaire.common.default_dtype.
        If the input dtype is different, use a casted copy.

    Returns
    -------
    reduced : cupy.ndarray
        sigma-clipped mean or median
    stddev : cupy.ndarray
        sigma-clipped standard deviation
    mask : cupy.ndarrray
        an array which indicates the corresponding value
        of data is clipped or not.
        This array has the same shape as data, and is True where
        the value is clipped and False where not.

    Notes
    -----
    If the number of values along specified axis is greater than 2^64,
    this function does not work properly.
    This is becuase convergence of clipping is determined
    by comparing the number of remaining values before and after clipping
    and the number is stored as uint64.


    Combine images and optionally write to FITS file

    Parameters
    ----------
    data : 3D ndarray
        An array of images stacked along the 1st dimension (axis=0)
    name : str, default None
        A path of output FITS file
        If given, write the result to a FITS file.
        Whether path like object is supported depends on
        the version of Python and Astropy.
    list : array-like, default None
        Names of image to combine
        These are written to the header.
        If the string is path-like, only basename is used.
    header : astropy.io.fits.Header, default None
        The header associated with data.
        This is used only when the name is given or return_type is 'hdul'.
        If None, an appropriate header is created for the supplied data.
    weights : array-like, default None
        array of weights associated with the values in data.
        This must be a broadcastable array with data, or a 1D array.
        If 1D, the length of this must be the same as the number of images.
    mask : ndarray, default None
        A boolean mask associated with the values in data,
        where a True value indicates the corresponding element of data
        is masked. Masked pixels are excluded when computing the statistics.
    combine : {'mean', 'median'}, default 'mean'
        An algorithm to combine
    center : {'mean', 'median'}, default 'mean'
        An algorithm to get center value
    iters : int, default 3
        A number of sigmaclipping iterations
        If None, clip until convergence is achieved.
    width : int or float, default 3.0
        A clipping width in sigma units
    dtype : str or dtype, default 'float32'
        dtype of array used internally
        If None, use eclair.common.default_dtype.
        If the input dtype is different, use a casted copy.
    exthdus: sequence of astropy HDU instances, default []
        sequence of HDUs to be added to output HDUList.
    return_type : {'ndarray', 'hdul'}, default 'hdul'
        If 'ndarray' is selected, return combined image as 2D cupy.ndarray.
        If 'hdul', return as astropy.fits.HDUList.
    kwargs : keywards arguments
        Additional keywards arguments given to writeto method of HDU object

    Returns
    -------
    combined : 2D cupy.ndarray or astropy.fits.HDUList
        combined image.
        type is determined by return_type.

    See Also
    --------
    sigma_clipped_stats : Calculate sigma-clipped statistics


    Shift an image

    Parameters
    ----------
    data : 2D ndarray
        An array of image.
    shifts : array-like
        A relative position of shifted image in units of pixel.
        The 1st item is interpreted as the value of X,
        the 2nd item as the value of Y.
    interp : str, default 'spline3'
        Subpixel interpolation algorithm in subpixel image shift.
        The choices are: 'spline3' (bicubic spline),
        'poly3' (3rd order interior polynomial), 'linear' (bilinear),
        and 'neighbor' (nearest neighbor).
    boundary : str, default 'neighbor'
        The choices are: 'neighbor', 'constant'.
    dtype : str or dtype, default None
        dtype of array used internally.
        If None, use eclair.common.default_dtype.
        If the input dtype is different, use a casted copy.

    Returns
    -------
    shifted : 2D cupy.ndarray
        An array of the shifted image


    Stack the images with aligning their relative positions

    Parameters
    ----------
    data : 3D ndarray
        An array of images stacked along the 1st dimesion (axis=0).
    shifts : 2D ndarray
        An array of relative positions of images in units of pixel.
        Along the 1st axis, values of each images must be the same order
        as the 1st axis of "data".
        Along the 2nd axis, the 1st item is interpreted as
        the value of X, the 2nd item as the value of Y.
    interp : str, default 'spline3'
        Subpixel interpolation algorithm in subpixel image shift.
        The choices are: 'spline3' (bicubic spline),
        'poly3' (3rd order interior polynomial), 'linear' (bilinear),
        and 'neighbor' (nearest neighbor).
    boundary : str, default 'neighbor'
        The choices are: 'neighbor', 'constant'.
    trimimages : bool, default True
        If True, the output images will be trimmed to include only the region
        over which they all overlap.
    dtype : str or dtype, default None
        dtype of array used internally.
        If None, use eclair.common.default_dtype.
        If the input dtype is different, use a casted copy.

    Returns
    -------
    aligned : 3D cupy.ndarray
        An array of images aligned and stacked along the 1st axis


    This function is equal to the equation:
    out = (image - bias - dark) / flat, but needs less memory.
    Therefore, each inputs must be broadcastable shape.

    Parameters
    ----------
    image : ndarray
    bias : ndarray
    dark : ndarray
    flat : ndarray
    out : cupy.ndarray, default None
        Alternate output array in which to place the result. The default
        is ``None``; if provided, it must have the same shape as the
        expected output, but the type will be cast if necessary.
    dtype : str or dtype, default 'float32'
        dtype of array used internally
        If None, use eclair.common.default_dtype.
        If the input dtype is different, use a casted copy.

    Returns
    -------
    out : cupy.ndarray


    Reproject images to a given projection using the spline interpolation.

    Parameters
    ----------
    data : 3D array
        An array of images stacked along the 1st dimesion (axis=0).
    input_projections : sequence of astropy Header or WCS
        Projections of input images.
    output_projection : Header or WCS
        The output projection.
    shape : tuple, default None
        The shape of output images.
        If None, use the shape which output_projection contains.
    order : int, default 3
        The order of the spline interpolation.
    out : 3D cupy.ndarray, default None
        Alternate output array in which to place the result. The default
        is None; if provided, it must have the same shape as the
        expected output, but the type will be cast if necessary.
    dtype : str or dtype, default None
        dtype of array used internally.
        If None, use eclair.common.default_dtype.
        If the input dtype is different, use a casted copy.
    implement: {'eclaire', 'astropy'}, default 'eclaire'
        Implementation of coordinate transformation.
        * 'eclaire' - it is performed by functions implemented with GPU.
            It is fast and low-load, but supports limited coordinate systems.
        * 'astropy' - it is performed by methods of astropy.wcs.WCS object.
            It uses CPU multithreads to compensate for the slowness,
            and does frequent host-device data transfers.
            This results a heavy load on the hardware.

    Returns
    -------
    reprojected : 3D cupy.ndarray
        An array in which the reprojected images are stacked.
        An area outside of the input image footprint are filled with NaN.


    Description
    -----------

    Function made to read limb-darkening coefficients tables and create a linear interpolator.
    The idea is that, given a file with the limb-darkening coefficients with differents temperatures,
    logg, M/H and vturb, this function returns an interpolation function, that is, a function f(Teff,logg,M/H,vturb,law)
    that returns the linearly interpolated coefficients of a given law at a given Teff, logg, M/H, vturb.

    Inputs
    ------

	methods		Method from which limb darkening coefficients will be obtained. These values will then be interpolated.

    Outputs
    -------

	interpolator	A dictionary containing interpolator objects as well as upper and lower limits of those interpolations.


    Description
    -----------

    Function made to sample points given the 0.16, 0.5 and 0.84 quantiles of a parameter

    In the case of unequal variances, this algorithm assumes a skew-normal distribution and samples from it.
    If the variances are equal, it samples from a normal distribution.

    Inputs
    ------

          loc:           Location parameter (we hope it is the 0.5 quantile, i.e., the median).

       sigma1:           Upper error of the parameter (we hope loc+sigma1 is the 0.84 quantile, i.e., the "upper 1-sigma bound").

       sigma2:           Lower error of the parameter (we hope loc-sigma2 is the 0.16 quantile, i.e., the "lower 1-sigma bound").

            n:           Number of samples you want to generate from this.

      low_lim:           (Optional) Lower limits on the values of the samples*.

       up_lim:           (Optional) Upper limits on the values of the samples*.

    Outputs
    -------

        The output are n samples from the distribution that best-matches the quantiles.

    *The optional inputs (low_lim and up_lim) are lower and upper limits that the samples have to have; if any of the samples
    surpasses those limits, new samples are drawn until no samples do. Note that this changes the actual variances of the samples.


            This function fits a Skew Normal distribution given
            the median, upper error bars (sigma1) and lower error bar (sigma2).


                Note that we pass the square-root of the scale (sigma) and shape (alpha) parameters,
                in order to define the sign of the former to be positive and of the latter to be fixed given
                the values of sigma1 and sigma2:


            This function simply calculates the CDF at x given the parameters
            mu, sigma and alpha of a Skew-Normal distribution. It takes values or
            arrays as inputs.


            This function returns the value of the Skew Normal PDF at x, given
            mu, sigma and alpha


clip, map X linear / nonlinear  inplace


    Calculates a transit using less-correlated parameters, from which the other pars are
    determined
    ld_1 =  u_1*cos(40) - u_2*sin(40)
    ld_2 =  u_1*sin(40) + u_2*cos(40)

    delta, T, tau defined as in Carter et al 2008


    Calculates a transit using  standard parameters.
    Meant to be used with fixed inclination and t0 for out program

    ld_1 =  u_1*cos(40) - u_2*sin(40)
    ld_2 =  u_1*sin(40) + u_2*cos(40)


    Calculates transit light curve, normalized
    non-obvious pars:
    r_a=R_*/a
    p = R_p/R_*


    Calculates a transit using less-correlated parameters, from which the other pars are
    determined

    delta, T, tau defined as in Carter et al 2008


Return a boolean indicating whether a flag name is supported on
    the specified compiler.


Format a reaction (array) to a string with clicked species.


    Called by analyze() by passing numpy.array().
    ns,nr,nt --- number of species, reactions, time steps
    isp      --- index of species to be analyze [int]
    isp_map  --- index map of all species       [array(dtype='int')]
    ireac_map--- index map of all reactions     [array(dtype='int')]
    rc_t     --- rc as function of t (time)     [array(dtyle='float')]
                 rc --- reaction rate coefficient
    sp_numb  --- number density of all species  [array(dtype='float')]


Analysis tool (AT) message when some errors occur


Collect all information and do the analysis


To update the species when a clickable text is pressed.


The main code to run


Function for scipy.integrate.ode:


Jacobian Function for scipy.integrate.ode:


    *** PURPOSE:
        load existing ggchem model file.
        e.g.: TMC1=loadgg('out/TMC1.dat')
    *** INPUT:
        ggfile --- ggchem model file
        NAUTILUS --- if True, load model file with format of NAUTILUS.
    *** OUTPUT:
        ab --- model results in python dictionary.


    *** PURPOSE:
        make a species formula to Latex format:
        e.g. H3O+   =>   r'${\rm H_3O^+}$'
    *** INPUT:
        sp --- species in string. e.g. 'H2O'
    *** OUTPUT:
        xsp --- species in latex format


        ##show a summary:
        if iswitch.icollapse==0:
            coll_msg_nH = "nH = %10.3g"%(gas.nH)
        if iswitch.icollapse==1:
            coll_msg_nH = 'nH = %10.3g -> %10.3g; Av0=%10.3g'%(gas.nH0,gas.nH1,gas.Av0)
        summary = 'Name=%s \niSS=%d, \niNTD=%d, \nicollapse=%d \n%s'%(modelname,\
                   iswitch.iSS, iswitch.iNTD, iswitch.icollapse, coll_msg_nH)

        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        msg.setText(summary )
        msg.exec_()


shape tuple of this object's data.


        Return a copy of this model.

        Uses a deep copy so that all model attributes, including parameter
        values, are copied as well.


The distance from the origin to the point(s).


Returns `True` if the given object is iterable.


The unique hub ID.


Return a float representing the decimal change between old_val and new_val.


    Classify the file named by 'filename' and return the classification.
    If the file is classified as 'IT_Invalid' print an error message and exit
    the program.


Draw ticks on the bottom x-axis of a Lambert Conformal projection.


Draw ricks on the left y-axis of a Lamber Conformal projection.


Read region masks


Read IRR data


Sum some reactions and combine these together


load s5p data


Read S5P files


Integrate the NO2 profiles from psfc to ptropo


    Replace the a priori profile, recalculate AMF, and
        calculate the percent difference:
            (new_AMF - AMF_nolnox) / AMF_nolnox, units: %

    Finally, plot the percent difference on ax.

    Return the plot object.


Read generated S5P files


Read the region masks


Mask the data


Plot the NO2 profiles with different LNOx settings


Plot difference of LNOx profiles


Plot the O3 profiles


Get the mean IRR in the crop_region and from bottom to top


Convert IRR Dataset to DataArray and add coords


Save a figure to file.

    Parameters
    ----------
    basename: str
        The basename of the file.
    provenance: dict
        The provenance record for the figure.
    cfg: dict
        Dictionary with diagnostic configuration.
    figure: matplotlib.figure.Figure
        Figure to save.
    close: bool
        Close the figure after saving.
    **kwargs:
        Keyword arguments to pass to :obj:`matplotlib.figure.Figure.savefig`.

    See Also
    --------
    ProvenanceLogger: For an example provenance record that can be used
        with this function.


Save the data used to create a plot to file.

    Parameters
    ----------
    basename: str
        The basename of the file.
    provenance: dict
        The provenance record for the data.
    cfg: dict
        Dictionary with diagnostic configuration.
    cube: iris.cube.Cube
        Data cube to save.
    **kwargs:
        Extra keyword arguments to pass to :obj:`iris.save`.

    See Also
    --------
    ProvenanceLogger: For an example provenance record that can be used
        with this function.


Record provenance.

        Parameters
        ----------
        filename: str
            Name of the file containing the diagnostic data.
        record: dict
            Dictionary with the provenance information to be logged.

            Typical keys are:
                - ancestors
                - authors
                - caption
                - domain
                - plot_type
                - references
                - statistics

        Note
        ----
            See the provenance `documentation`_ for more information.

        .. _documentation: https://docs.esmvaltool.org/en/latest/community/diagnostic.html#recording-provenance


Save the provenance log to file.


Select specific metadata describing preprocessed data.

    Parameters
    ----------
    metadata : :obj:`list` of :obj:`dict`
        A list of metadata describing preprocessed data.
    **attributes :
        Keyword arguments specifying the required variable attributes and
        their values.
        Use the value '*' to select any variable that has the attribute.

    Returns
    -------
    :obj:`list` of :obj:`dict`
        A list of matching metadata.


Sort a list of metadata describing preprocessed data.

    Sorting is done on strings and is not case sensitive.

    Parameters
    ----------
    metadata : :obj:`list` of :obj:`dict`
        A list of metadata describing preprocessed data.
    sort : :obj:`str` or :obj:`list` of :obj:`str`
        One or more attributes to sort by.

    Returns
    -------
    :obj:`list` of :obj:`dict`
        The sorted list of variable metadata.


Sort grouped metadata.

    Sorting is done on strings and is not case sensitive.

    Parameters
    ----------
    metadata_groups : :obj:`dict` of :obj:`list` of :obj:`dict`
        Dictionary containing the groups of metadata.
    sort : :obj:`bool` or :obj:`str` or :obj:`list` of :obj:`str`
        One or more attributes to sort by or True to just sort the groups but
        not the lists.

    Returns
    -------
    :obj:`dict` of :obj:`list` of :obj:`dict`
        A dictionary containing the requested groups.


Extract basic variable information from configuration dictionary.

    Returns `short_name`, `standard_name`, `long_name` and `units` keys for
    each variable.

    Parameters
    ----------
    cfg : dict
        Diagnostic script configuration.
    as_iris : bool, optional
        Replace `short_name` by `var_name`, this can be used directly in
        :mod:`iris` classes.

    Returns
    -------
    dict
        Variable information in :obj:`dict`s (values) for each `short_name`
        (key).


Check if data from certain variables is available.

    Parameters
    ----------
    cfg : dict
        Diagnostic script configuration.
    short_names : list of str
        Variable `short_names` which should be checked.

    Returns
    -------
    bool
        `True` if all variables available, `False` if not.


Get a dictionary containing all data input files.


Run a Python diagnostic.

    This context manager is the main entry point for most Python diagnostics.

    Example
    -------
    See esmvaltool/diag_scripts/examples/diagnostic.py for an extensive
    example of how to start your diagnostic.

    Basic usage is as follows, add these lines at the bottom of your script::

        def main(cfg):
            # Your diagnostic code goes here.
            print(cfg)

        if __name__ == '__main__':
            with run_diagnostic() as cfg:
                main(cfg)

    The `cfg` dict passed to `main` contains the script configuration that
    can be used with the other functions in this module.


    Parameters
    ----------
    data_holder
    grid_dictionary

    Returns
    -------
    GMM fit for grid cell


Iterate over all grid cells and map to multiprocess function


Append given text as a new line at the end of file


    Parameters
    ----------
    input_dictionary
    cfg

    Returns
    -------
    This function unpack input dictionary and send regions dictionary to
    run with MP


    Organized metadata dictionary will have the following keys:
    Region -> Model -> Experiment-GWL
    i.e. MED -> HadGEM2-ES  -> historical
    i.e. MED -> HadGEM2-ES  -> ssp126-15


(int) Export request status.


 Decompress files at paths in filepaths

        Args:
            filepaths (list): List of paths to files to decompress
        Returns:
            list: List of paths to decompressed files


    Combine datasets which have different time resolutions
    Avoids having to resample data to the same resolution in order to add,
    subtract, multiply, or divide them

    Args
        data_1, data_2 (xarray.DataArray or xarray.Dataset)
            Data to combine
            Must have resolution of 1 hour, 1 day, 1 month, or 1 year
        method (str)
            Method by which to combine the datasets
            Can be:
                'add':      data_1 + data_2 (default)
                'subtract': data_1 - data_2
                'multiply': data_1 * data_2
                'divide':   data_1 / data_2

    Returns
        xarray.DataArray or xarray.Dataset
            has the same shape as resolved_data


Returns a dictionary deserialised from JSON.

    Args:
        filename: Name of JSON file
    Returns:
        dict: Dictionary created from JSON


    The domain_volume function extracts the volume (lat, lon, height) within a domain from a related footprint file.

    Args:
        domain (str) :
            Domain of interest (e.g. one of 'AUSTRALIA', 'CARIBBEAN','EASTASIA','EUROPE','NAMERICA','PACIFIC',
            'SOUTHAFRICA','SOUTHASIA','WESTUSA')
        fp_directory (str, optional) :
            fp_directory can be specified if files are not in the default directory.
            Must point to a directory which contains subfolders organized by domain.

    Returns:
        xarray.DataArray (3):
            Latitude, longitude, height


    Create an array covering a range from a set of bounds. Choose whether to include upper
    bound or not.

    Args:
        bounds (list) :
            Two item list containing the upper and lower bounds of the range
        step (int/float) :
            Step size for the range
        include_upper (bool, optional) :
            Whether to include the upper bound.
            Default = False
    Returns:
        np.array:
            Array created using np.arange of range between lower and upper bounds.


    Extract country name based on ISO3166 standard.
    Note: allows non-standard values based on Natural Earth and Marine Regions databases to be included if
    allow_non_standard is set to True.

    Args:
        code (str) :
            Can accept alpha2, alpha3 or numeric code to extract the country name.
        allow_non_standard (bool, optional) :
            Allow additional search for non-standard country names based on extra values
            specifically from the Natural Earth and Marine Regions databases.
            Default = True.
        supress_print (bool, optional) :
            Whether to supress printing of a warning message when unable to find a match.
            Default = False.
    Returns:
        str:
            Country name (based on ISO3166 standard)


    Extract country two-letter code based on ISO3166 standard.
    Note: allows non-standard values based on Natural Earth and Marine Regions databases
    to be included if allow_non_standard is set to True.

    Args:
        code (str) :
            Can accept alpha3, numeric code or country name.
        allow_non_standard (bool, optional) :
            Allow additional search for non-standard country names based on extra values
            specifically from the Natural Earth and Marine Regions databases.
            Default = True.
        supress_print (bool, optional) :
            Whether to supress printing of a warning message when unable to find a match.
            Default = False.

    Returns:
        str:
            Two-letter country code (based on ISO3166 standard)


    Additional country names with no equivalent within the ISO3166 standard but included (at the moment)
    within the Natural Earth database.

    e.g. Vatican, N. Cyprus, Kosovo, Somaliland

    Args:
        code (str) :
            Country name to check against list of additional accepted country names.

    Returns:
        str/None:
            returns the country name if it matches the list, None otherwise.


    Manages the country names containing a comma and assumes the string after the comma contains the
    descriptor of the country e.g. "Republic Of". In most cases it is assumed that this detail is not
    needed in the final country name. Exceptions are detailed below.

    Rules for commas are as follows:
     - If the country requires the designation after a comma the name will be rearranged. At the moment,
     this includes "congo" and "korea".
     e.g. "Korea, Republic of" becomes "Republic of Korea"
     e.g. "Korea, Democratic People's Republic of" becomes "Democratic People's Republic of Korea"
     - Otherwise, any designation specified after a comma will be removed.
     e.g. "Venezuela, Bolivarian Republic of" becomes "Venezuela"

    WARNING: Changes countries list in place

    Args:
        countries (list) :
            List of country names to manage.

    Returns:
        list:
            Country names altered as described above where appropriate.


    Extract mapping from the region number to the country name from the regionmask module.

    See manage_country_descriptor() function for how names containing commas are treated.

    Args:
        upper (bool, optional):
            Return country names all in upper case. Default = True.

    Returns:
        dict:
            Dictionary containing the mapping of the region number to the country name.


    Reset index within mask from numbers derived from region_mask module to incrementally increasing values.

    Args:
	    mask (xarray.DataArray) :
	    	DataArray containing grid (nlat x nlon)
	    regions (list/None, optional):
	    	List of region numbers. If not specified, this will be extracted from mask.
	    	Default = None.

    Returns:
	    xarray.DataArray:
	    	Mask with values renumbered from 0-nregions


    Creates a country mask for the latitude and longitude range. Derives country data from
    Natural Earth database (at 1:50m resolution).

    If write=True, writes out file of the form "country_DOMAIN.nc" e.g. country_SOUTHAMERICA.nc
    Note: Will not overwrite a pre-existing file.

    Args:
        domain (str) :
            Domain associated with lat and lon grid.
            If lat and lon arrays are not specified, domain will be used to extract latitude and
            longitude grids.
        lat (np.array, optional) :
            Latitude grid values.
            If not specified, will attempt to extract latitude values from domain footprint file.
        lon (np.array, optional) :
            Longitude grid values.
            If not specified, will attempt to extract longitdue values from domain footprint file.
        reset_index (bool, optional) :
            Reset index values within grid to 0 - num regions rather than retain their
            original values within the Natural Earth input (regionmask input).
            May be useful to not reset the index when needing to compare to other inputs.
            Should be set to True when writing to file to match with other ACRG code for looking at
            country totals.
            Default = True.
        ocean_label (bool, optional) :
            Add additional explicit ocean label as well as countries within domain.
            Default = True.
        use_domain_extent (bool, optional) :
            If lat and lon values are specified, still create region covering the domain area but
            mask out any values outside the lat, lon bounds (treat lat,lon as a sub-domain).
            Note: Only the lat and lon outer values will be used as the latitude and longnitude values
            in the grid must match the domain values.
        fp_directory (str, optional) :
            Base footprint directory to use to extract domain values. Uses footprint directory on data path
            by default and expects sub-directories of domain name. Only used if lat, lon are not specified.
        write (bool, optional) :
            Write produced dataset to file of the form "country_"DOMAIN".nc".
            Default = True.
        output_dir (str, optional) :
            Directory for writing output.

    Returns:
        xarray.Dataset:
            Dataset containing the country map

        If write:
            Writes the dataset to file.


    Creates a mask for all countries within the domain (or lat/lon bounds).
    Uses Natural Earth 10m land datasets and Admin_0_map_units datasets
    for specifiying country and ocean boundaries.
    Option to include EEZ (Exclusive Economic Zones e.g. marine
    territories) is True by default. Remaining areas are given a value of 0.

    Based on code written by Daniel Hoare and Rachel Tunnicliffe.

    Args:
        domain (str):
            The domain the mask should cover, e.g. 'EUROPE'. If lat and lon are not specified,
            will use the domain to extract the latitudes and longitudes.
        lat (numpy array) (optional):
            Latitudes to create mask over. If not specified, will extract lats from a domain.
        lon (numpy array) (optional):
            Longitudes to create mask over. If not specified, will extract lons from a domain.
        include_land_territories (bool):
            If True, include land territories for all countries in the
            country mask.
        include_ocean_territories (bool):
            If True, include areas within EEZ (marine territories) in the
            country mask.
        reset_index (bool):
            If True, start indexing countries from 1 (with ocean as 0).
            If False, uses the Natural Earth index values (as extracted by geopandas).
        fill_gaps (bool):
            Fills in gaps between the land and ocean masks that are missed and some
        fp_directory (str, optional) :
            Base footprint directory to use to extract domain values. Uses footprint directory on data path
            by default and expects sub-directories of domain name.
        lat_lon_mask (bool):
            If True, masks all cells outside sub_lats and sub_lons (gives them values of np.nan).
        sub_lats (list or array) (optional):
            Either a list of [min_lat,max_lat] or a numpy array of lats. Any cells beyond these limits are masked.
        sub_lons (list or array) (optional):
            Either a list of [min_lon,max_lon] or a numpy array of lons. Any cells beyond these limits are masked.
         out_path (str) (optional):
            Path and name to save mask to. If None, does not save dataset.
    Returns:
        ds (xarray dataset):
            Country mask dataset.


    This function extracts the molar mass of a species from the acrg_species_info.json file.
    Returns:
        float : Molar mass of species


Convert to a different prefix. Note there are probably libraries to do this.


Conversion between mol/mol to parts-per- units


    Convert longitude values onto a 0-360 range from -180-180 range. Uses floored division.

    Args:
        lons (arr):
            1D array of longitudes.
    Returns:
        array:
            Longitudes on 0-360 range.


    Parses all continuous distributions for pymc 3.8: https://docs.pymc.io/api/distributions/continuous.html
    This format requires updating when the pymc distributions update, but is safest for code execution

    Args:
        name (str):
            name of variable in the pymc model
        prior_params (dict):
            dict of parameters for the distribution, including 'pdf' for the distribution to use
        shape (array):
            shape of distribution to be created. Default shape = () is the same as used by pymc3


    Uses pym3 module for Bayesian inference for emissions field, boundary
    conditions and (currently) a single model error value.
    This uses a Normal likelihood but the (hyper)prior PDFs can selected by user.

    Args:
        Hx (array):
            Transpose of the sensitivity matrix to map emissions to measurement.
            This is the same as what is given from fp_data[site].H.values, where
            fp_data is the output from e.g. footprint_data_merge, but where it
            has been stacked for all sites.
        Hbc (array):
            Same as above but for boundary conditions
        Y (array):
            Measurement vector containing all measurements
        error (arrray):
            Measurement error vector, containg a value for each element of Y.
        siteindicator (array):
            Array of indexing integers that relate each measurement to a site
        sigma_freq_index (array):
            Array of integer indexes that converts time into periods
        xprior (dict):
            Dictionary containing information about the prior PDF for emissions.
            The entry "pdf" is the name of the analytical PDF used, see
            https://docs.pymc.io/api/distributions/continuous.html for PDFs
            built into pymc3, although they may have to be coded into the script.
            The other entries in the dictionary should correspond to the shape
            parameters describing that PDF as the online documentation,
            e.g. N(1,1**2) would be: xprior={pdf:"normal", "mu":1, "sd":1}.
            Note that the standard deviation should be used rather than the
            precision. Currently all variables are considered iid.
        bcprior (dict):
            Same as above but for boundary conditions.
        sigprior (dict):
            Same as above but for model error.
        offsetprior (dict):
            Same as above but for bias offset. Only used is addoffset=True.
        sigma_per_site (bool):
            Whether a model sigma value will be calculated for each site independantly (True) or all sites together (False).
            Default: True
        add_offset (bool):
            Add an offset (intercept) to all sites but the first in the site list. Default False.
        verbose:
            When True, prints progress bar

    Returns:
        outs (array):
            MCMC chain for emissions scaling factors for each basis function.
        bcouts (array):
            MCMC chain for boundary condition scaling factors.
        sigouts (array):
            MCMC chain for model error.
        Ytrace (array):
            MCMC chain for modelled obs.
        YBCtrace (array):
            MCMC chain for modelled boundary condition.
        convergence (str):
            Passed/Failed convergence test as to whether mutliple chains
            have a Gelman-Rubin diagnostic value <1.05
        step1 (str):
            Type of MCMC sampler for emissions and boundary condition updates.
            Currently it's hardwired to NUTS (probably wouldn't change this
            unless you're doing something obscure).
        step2 (str):
            Type of MCMC sampler for model error updates.
            Currently it's hardwired to a slice sampler. This parameter is low
            diensional and quite simple with a slice sampler, although could
            easily be changed.

    TO DO:
       - Allow non-iid variables


        Takes the output from inferpymc3 function, along with some other input
        information, and places it all in a netcdf output. This function also
        calculates the mean posterior emissions for the countries in the
        inversion domain and saves it to netcdf.
        Note that the uncertainties are defined by the highest posterior
        density (HPD) region and not percentiles (as the tdMCMC code).
        The HPD region is defined, for probability content (1-a), as:
            1) P(x \in R | y) = (1-a)
            2) for x1 \in R and x2 \notin R, P(x1|y)>=P(x2|y)

        Args:
            xouts (array):
                MCMC chain for emissions scaling factors for each basis function.
            bcouts (array):
                MCMC chain for boundary condition scaling factors.
            sigouts (array):
                MCMC chain for model error.
            convergence (str):
                Passed/Failed convergence test as to whether mutliple chains
                have a Gelman-Rubin diagnostic value <1.05
            Hx (array):
                Transpose of the sensitivity matrix to map emissions to measurement.
                This is the same as what is given from fp_data[site].H.values, where
                fp_data is the output from e.g. footprint_data_merge, but where it
                has been stacked for all sites.
            Hbc (array):
                Same as above but for boundary conditions
            Y (array):
                Measurement vector containing all measurements
            error (arrray):
                Measurement error vector, containg a value for each element of Y.
            Ytrace (array):
                Trace of modelled y values calculated from mcmc outputs and H matrices
            YBCtrace (array):
                Trace of modelled boundary condition values calculated from mcmc outputs and Hbc matrices
            step1 (str):
                Type of MCMC sampler for emissions and boundary condition updates.
            step2 (str):
                Type of MCMC sampler for model error updates.
            xprior (dict):
                Dictionary containing information about the prior PDF for emissions.
                The entry "pdf" is the name of the analytical PDF used, see
                https://docs.pymc.io/api/distributions/continuous.html for PDFs
                built into pymc3, although they may have to be coded into the script.
                The other entries in the dictionary should correspond to the shape
                parameters describing that PDF as the online documentation,
                e.g. N(1,1**2) would be: xprior={pdf:"normal", "mu":1, "sd":1}.
                Note that the standard deviation should be used rather than the
                precision. Currently all variables are considered iid.
            bcprior (dict):
                Same as above but for boundary conditions.
            sigprior (dict):
                Same as above but for model error.
            offsetprior (dict):
                Same as above but for bias offset. Only used is addoffset=True.
            Ytime (pandas datetime array):
                Time stamp of measurements as used by the inversion.
            siteindicator (array):
                Numerical indicator of which site the measurements belong to,
                same length at Y.
            sigma_freq_index (array):
                Array of integer indexes that converts time into periods
            domain (str):
                Inversion spatial domain.
            species (str):
                Species of interest
            sites (list):
                List of sites in inversion
            start_date (str):
                Start time of inversion "YYYY-mm-dd"
            end_date (str):
                End time of inversion "YYYY-mm-dd"
            outputname (str):
                Unique identifier for output/run name.
            outputpath (str):
                Path to where output should be saved.
            country_unit_prefix ('str', optional)
                A prefix for scaling the country emissions. Current options are:
                'T' will scale to Tg, 'G' to Gg, 'M' to Mg, 'P' to Pg.
                To add additional options add to acrg_convert.prefix
                Default is none and no scaling will be applied (output in g).
            burn (int):
                Number of iterations burned in MCMC
            tune (int):
                Number of iterations used to tune step size
            nchain (int):
                Number of independent chains run
            sigma_per_site (bool):
                Whether a model sigma value was be calculated for each site independantly (True)
                or all sites together (False).
            fp_data (dict, optional):
                Output from footprints_data_merge + sensitivies
            flux_directory (str, optional):
                Directory containing the emissions data if not default
            emissions_name (dict, optional):
                Allows emissions files with filenames that are longer than just the species name
                to be read in (e.g. co2-ff-mth_EUROPE_2014.nc). This should be a dictionary
                with {source_name: emissions_file_identifier} (e.g. {'anth':'co2-ff-mth'}). This way
                multiple sources can be read in simultaneously if they are added as separate entries to
                the emissions_name dictionary.
            basis_directory (str, optional):
                Directory containing basis function file
            country_file (str, optional):
                Path of country definition file
            add_offset (bool):
                Add an offset (intercept) to all sites but the first in the site list. Default False.
            rerun_file (xarray dataset, optional):
                An xarray dataset containing the ncdf output from a previous run of the MCMC code.

        Returns:
            netdf file containing results from inversion

        TO DO:
            - Look at compressability options for netcdf output
            - I'm sure the number of inputs can be cut down or found elsewhere.
            - Currently it can only work out the country total emissions if
              the a priori emissions are constant over the inversion period
              or else monthly (and inversion is for less than one calendar year).


    Define required parameters for acrg_hbmcmc.hcmcmc.fixedbasisMCMC() function.

    Expected parameters currently include:
        species, sites, meas_period, start_date, end_date, domain, outputpath, outputname

    Returns:
        list : required parameter names


    Find value which describes the MCMC function to use.
    Checks the input configuation file the "mcmc_type" keyword within the "MCMC.TYPE" section.
    If not present, the default is used.

    Args:
        config_file (str) :
            Configuration file name. Should be an .ini file.
        default (str) :
            ***

    Returns:
        str :
            Keyword for MCMC function to use


    Links mcmc_type name to function.

    Current options:
        mcmc_type (str) :
            "fixed_basis" : acrg_hbmcmc.hbmcmc.fixedbasisMCMC(...) function

    Returns:
        Function


    Extract parameters from input configuration file and associated MCMC function.
    Checks the mcmc_type to extract the required parameters.

    Args:
        config_file (str):
            Configuration file name. Should be an .ini file.
        mcmc_type (str, optional) :
            Keyword for MCMC function to use.
            Default = "fixed_basis" (only option at present)
        print_param (bool, optional) :
            Print out extracted parameter names.
            Default = True
        command_line :
            Any additional command line arguments to be added to the param dictionary or to superceed
            values contained within the config file.

    Returns:
        function,collections.OrderedDict :
            MCMC function to use, dictionary of parameter names and values which can be passed to MCMC function


    Open a netcdf dataset with xarray
    Args:
        fn (string)
            netcdf file to be opened
    Returns:
        xarray.Dataset:
            netcdf file as  dataset


    Adds the variablility within the averaging period to the mole fraction error.

    Args:
        fp_all (dict):
            Output from footprint_data_merge
        sites (list):
            List of site names
        species (str):
            Species of interest
        start_date (str):
            Start time of inversion "YYYY-mm-dd"
        end_date (str):
            End time of inversion "YYYY-mm-dd"
        meas_period (list):
            Averaging period of measurements
        inlet (str/list, optional):
            Specific inlet height for the site (must match number of sites).
        instrument (str/list, optional):
            Specific instrument for the site (must match number of sites).
        obs_directory (str, optional):
            Directory containing the obs data (with site codes as subdirectories)
            if not default.

    Returns:
        fp_all (dict):
            fp_all from input with averaging error added to the mole fraction
            error


    Creates a sensitivity matrix (H-matrix) for the boundary conditions, which
    will map monthly boundary condition scalings to the observations. This is
    for a single site.

    Args:
        start_date (str):
            Start time of inversion "YYYY-mm-dd"
        end_date (str):
            End time of inversion "YYYY-mm-dd"
        site (str):
            Site that you're creating it for
        fp_data (dict):
            Output from acrg_name.bc_sensitivity

    Returns:
        Hmbc (array):
            Sensitivity matrix by month for observations


    Creates a sensitivity matrix (H-matrix) for the boundary conditions, which
    will map boundary condition scalings to the observations. This is
    for a single site. The frequency that the boundary condition sensitivity
    is specifiec over must be specified in days. Currently only works
    for a boundary condition from each cardinal direction.

    Args:
        start_date (str):
            Start time of inversion "YYYY-mm-dd"
        end_date (str):
            End time of inversion "YYYY-mm-dd"
        site (str):
            Site that you're creating it for
        fp_data (dict):
            Output from acrg_name.bc_sensitivity
        freq (str):
            Length-scale over which boundary condition sensitivities are
            specified over. Specified as in pandas, e.g. "30D".

    Returns:
        Hmbc (array):
            Sensitivity matrix by for observations to boundary conditions


    Create an index that splits times into given periods

    Args:
        Ytime (array of datetime64):
            concatanted array of time values for observations
        sigma_freq (str):
            either "monthly", a pandas format string ("30D"), or None
            this is the period of time to divide the time array into

    Returns:
        output (array):
            index array that defines periods against time


    Set up a matrix that can be used to add an offset to each site.
    This will anchor to the first site (i.e. first site has no offset)


Check folder exists and create if not.


    Defining output filename to write to based on the format:
        'outputpath'/'species'_'domain'_'outputname'_'start_date''ext'
        e.g. /home/user/output/CH4_EUROPE_test_2014-01-01.nc


    Creating a copy of the inputs used to run MCMC code based on the input config file and any additional
    parameters specified on the command line.

    Values to create the output filename and location are either extracted from the config_file
    directly or from the input param dictionary if specified.

    Any additional command line arguments can be specified as keyword arguments.
    e.g. start_date="2018-01-01", end_date="2019-01-01"

    Args:
        config_file (str):
            Input configuration file name. Should be an .ini file.
        param (dict/None, optional) :
            Optional param dictionary used directly in input to MCMC code. Just included as a convenience
            so config_file doesn't have to be read twuce but should be the same inputs contained within
            the configuration file unless they have been superceeded by command line arguments.
        **command_line :
            Any additional keyword arguments from the command line input.

    Returns:
        None

        Writes output file to same location as MCMC output
        (output filename based on define_output_filename() function with '.ini' extension)


    This function extracts platform (if specified) for the site from site_info.json file.
    network can be specified if site is associated with more than one. If not specified, the first
    network will be used by default.
    Returns:
        str : Platform type (e.g. "site", "satellite", "aircraft")


    The define_stations function defines the latitude and longitude values for each site within
    a dataset.

    If sites is not specified, if the platform for the site is listed as "aircraft" or
    "satellite" in the site_info.json file then no values are included in the stations
    dictionary for this site.

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects dataset to contain:
                sitelons - Longitude values for each site. Dimension = len(sites)
                sitelats - Latitude values for each site. Dimension = len(sites)
                y_site       - Site identifier for each measurement. Dimension = nmeasure
        sites (list/None, optional) :
            List of sites to look for within dataset.
            If not specified, the sites will be extracted from the input dataset assuming a
            data variable "sites" is included within the dataset.
        use_site_info (bool, optional) :
            Use positions from site_info.json file rather than extract them from the tdmcmc dataset.
            Default = False.

    Returns:
        dict :
            Dictionary containing sitelats, sitelons for each site.


    The subplot_fmt function decides the placement of a grid of figures dependent on the number.
    The row_dims input determines which placement is preferable for the user.

    Args:
        num (int) :
            Number of figures to be placed
        row_dims (list, optional) :
            Row dimensions in order of preference.
            For the default row_dims=[3,2,4] the preferences of placement is as follows:
                - equal rows of 3
                - equal rows of 2
                - equal rows of 4
            If none of the above are possible the format will be num x number of columns if fill
            is True or the configuration suitable for num+1 if fill is False.
        fill (bool, optional) :
            All panels in subplot must be filled. If not, for uneven numbers an extra panel will
            be added which will be left blank when plotting.
            Default = False (i.e. allow an empty panel to be included within subplot)

    Returns:
        List (int): [row_num,col_num]
                    2 item list containing the row number and column number for the subplots.


    Calculate the normalisation of a diverging cbar around a given value
    Prevents bias due to asymetry in data affecting scale

    Args:
        data : numpy array of data to plot
        zero : the centre value of the cmap
        minValue : smallest value to use in calculation
        maxValue : largest value to use in calculation

    Returns:
        a normalization function to be fed into plot


    Plot 2d map of data
    e.g. scaling map of posterior x i.e. degree of scaling applied to prior emissions

    Args:
        data (numpy.array) :
            2D (lat,lon) array of whatever you want
        lon (numpy.array) :
            Longitude array matching to data grid
        lat (numpy.array) :
            Latitude array  matching to data grid
        clevels (numpy.array, optional) :
            Array of contour levels; defaults to np.arange(-2., 2.1, 0.1)
        divergeCentre (float/None, optional):
            Default is None, to replicate original clevels behaviour.
	        If given a float, this value is used to manually set the centre value of a diverging cmap,
	        while using the min and max values of clevels as the min and max values of the cmap.
        cmap (matplotlib.cm, optional) :
            Colormap object; defaults to Red Blue reverse
        borders (bool, optional) :
            Add country borders as well as coastlines. Default = True.
        label (str, optional) :
            Label to appear underneath the colorbar. Default = None
        smooth (bool, optional) :
            If True plot smooth contours; otherwise use pcolormesh. Default = False.
        out_filename (str, optional) :
            Output filename. If this is specified the plot will be written to file.
            Will be shown interactively otherwise (if show=True). Default = None.
        stations (dict, optional) :
            Default is None. If specified needs to be a dictionary containing the list of sites
            and site locations for each site. For example:
                {"sites": ['MHD', 'TAC'],
                 MHD_lon: -9.02,
                 MHD_lat: 55.2,
                 TAC_lon: etc...
        fignum (int, optional) :
            Figure number for created plot. Default = None
        title (str, optional) :
            Title for the plot or sub-plot. Default = None
        extend (str, optional) :
            Extend colorbar for out-of-range values.
            Options are [ 'neither' | 'both' | 'min' | 'max' ]
            Default = "both". Set to "neither" to not extend.
        figsize (tuple/None, optional) :
            Figure size tuple if creating a new fig object.
            Default = None.
        fig (matplotlib.pyplot.Figure, optional) :
            Figure object for plot. If not specified this will be created. Default = None
        ax (matplotlib.pyplot.Axes, optional) :
            Axes object for plot domain. If not specified this will be created. Default = None
        show (bool, optional) :
            Whether to plot immediately upon completion of plotting within this function.
            Note that out_filename supercedes this option and plot will be written to file even
            if this is set to True.
            Default = True.

    Returns:
        None

        If out_filename is None:
            Created plot is saved to file
        Else:
            Plot is displayed interactively


    Uses plot_map function to plot a set of maps either on a grid or as separate figures.
    If plotting on a grid the subplots are either determined automatically based on shape of
    input or using subplot input.

    Expect data_all to either be:
         - a numpy.array of the shape: nlat x nlon (x ngrid)
         - list of numpy.array objects each of shape nlat x nlon.
    Either the ngrid dimension or the len of the list is taken as the number of panels to
    include on the plot.

    Args:
        data_all (numpy.array/list) :
            Multiple lat-lon grids to be plotted on one figure as a set of sub-plots or as
            multiple figures.
            Can either be a list of grids or an array of dimension nlat x nlon (x ngrid).
        lon (numpy.array) :
            Longitude array matching to longitude points is each grid in grid_data.
        lat (numpy.array) :
            Latitude array matching to longitude points is each grid in grid_data.
        grid (bool, optional) :
            Whether to plot on a grid.
            Default = True.
        subplot (str/list, optional) :
            If grid is True, subplot grid to use. If this is set to "auto" this will be
            automatically determined based on the size of ngrid (see subplot_fmt() function).
            Otherwise, this should be a two item list of [nrows, ncols]
            Default = "auto".
        labels (str/list, optional) :
            Can specify either one label for all plots (str) or a different label for
            each plot as a list.
            If list is specified, it must match ngrid length.

        See plot_map() function for definition of remaining inputs.

    Returns:
        None

        If out_filename specified:
            Plot is written to file
        Otherwise:
            Plot is displayed interactively


    The plot_scale_map function plots 2D scaling map(s) of posterior x. This is the degree of
    scaling which has been applied to prior emissions.

    Args:
        ds_list (list) :
            List of xarray.Dataset objects. Each dataset is an output from run_tdmcmc()
            function (tdmcmc_inputs.py script).
            Expects each data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
        lat (data array):
            Data array of lat values to plot over - must match values in ds exactly
        lon (data array):
            Data array of lon values to plot over - must match values in ds exactly
        grid (bool, optional) :
            Whether to plot the posterior on one figure as a grid or on individual plots.
        labels (str/list, optional) :
            Can specify either one label for all plots (str) or a different label for
            each plot.
            If list is specified, it must match number of datasets in ds_list.
        plot_stations (bool, optional) :
            Plot site positions on the output map. Will not plot aircraft or satellite positions.
        use_site_info (bool, optional) :
            If plotting site positions, use positions from site_info.json file rather
            than extract them from the tdmcmc dataset.
            Default = False.

        See plot_map() function for definition of remaining inputs.

    Returns:
        None

        If out_filename specified:
            Plot is written to file
        Otherwise:
            Plot is displayed interactively


    The plot_abs_map function plots 2D map(s) of posterior x in g/m2/s.

    Args:
        ds_list (list) :
            List of xarray.Dataset objects. Each dataset is an output from run_tdmcmc()
            function (tdmcmc_inputs.py script).
            Expects each data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon
        lat (data array):
            Data array of lat values to plot over - must match values in ds exactly
        lon (data array):
            Data array of lon values to plot over - must match values in ds exactly
        species (str) :
            Species for the tdmcmc output.
        grid (bool, optional) :
            Whether to plot the posterior on one figure as a grid or on individual plots.
        labels (str/list) :
            Can specify either one label for all plots (str) or a different label for
            each plot.
            If list is specified, it must match number of datasets in ds_list.
        plot_stations (bool, optional) :
            Plot site positions on the output map. Will not plot aircraft or satellite positions.
        use_site_info (bool, optional) :
            If plotting site positions, use positions from site_info.json file rather
            than extract them from the tdmcmc dataset.
            Default = False.

        See plot_map() function for definition of remaining inputs.

    Returns:
        None

        If out_filename specified:
            Plot is written to file
        Otherwise:
            Plot is displayed interactively


    The plot_diff_map function plots 2D map(s) of the difference between the prior and
    posterior x in g/m2/s.

    Args:
        ds_list (list) :
            List of xarray.Dataset objects. Each dataset is an output from run_tdmcmc()
            function (tdmcmc_inputs.py script).
            Expects each data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon
        lat (data array):
            Data array of lat values to plot over - must match values in ds exactly
        lon (data array):
            Data array of lon values to plot over - must match values in ds exactly
        species (str) :
            Species for the tdmcmc output.
        grid (bool, optional) :
            Whether to plot the posterior on one figure as a grid or on individual plots.
        labels (str/list) :
            Can specify either one label for all plots (str) or a different label for
            each plot.
            If list is specified, it must match number of datasets in ds_list.
        plot_stations (bool, optional) :
            Plot site positions on the output map. Will not plot aircraft or satellite positions.
        use_site_info (bool, optional) :
            If plotting site positions, use positions from site_info.json file rather
            than extract them from the tdmcmc dataset.
            Default = False.

        See plot_map() function for definition of remaining inputs.

    Returns:
        None

        If out_filename specified:
            Plot is written to file
        Otherwise:
            Plot is displayed interactively


    Calculate country emissions across multiple datasets.
    See process.country_emissions() function for details of inputs
    Returns:
        cntry_mean_list: list of mean country totals
        cntry_68_list: list of 68 CI country totals
        cntry_95_list: list of 95 CI country totals


Plot  timeseries of country emissions


    Plot measurement timeseries of posterior and observed measurements
    Requires post_mcmc xray dataset
    For future: incorporate model & measurement uncertainty
    Plots separate subplots for each of the measurement sites - hopefully!

    Args:
        ds (xarray dataset) : dataset output from run_tdmcmc script
        fig_text (String) : e.g. "CH$_{4}$ mole fraction (ppb)"
        ylim (array) : y-axis limits [ymin,ymax]
        out_filename (string) : Filename to save file
        doplot (bool) : Plot to console? (optional)
        figsize (tuple) : Specify size of figure as a two-item tuple.
        plot_prior (bool) : Plot mole fraction prior.
        plot_bc_prior (bool) : Plot inner boundary conditions prior.
        lower_percentile (float) : Lower percentile of predicted time series
                                   uncertainty (default = 16)
        upper_percentile (float) : Upper percentile of predicted time series
                                   uncertainty (default = 84)

    Specify an out_filename to write to disk


Function efficiently opens xray datasets.


    Find hbmcmc output filenames based on naming convention:
        "directory"/"species"+"domain"+"runname"_"date".nc"
    Open as xarray.Dataset objects and return as a list.


    Calculates the Deviance information criterion (DIC) for an inversion.
    It does this using two different definitions:
    1) Spiegelhalter et al. (2002) https://doi.org/10.1111/1467-9868.00353
    2) Gelman et al. (2004) http://www.stat.columbia.edu/~gelman/research/published/waic_understand3.pdf

    The DIC is similar to metrics like AIC (Akaike Information Criterion) but
    better suited to hierarchical models and MCMC.
    What this is useful for is for testing things such as whether increasing the number of
    basis functions improves things, or is it just fitting to the noise and making uncertainty larger.
    The lower the DIC the better.
    It should be noted that this doesn't give a hard and fast description of the suitability of a
    statistical model but is the most useful indicator I can find.

    Args:
        ds (xarray dataset)      : dataset output from hbmcmc
        silence (bool, optional) : Set to True to not print to screen
    Returns:
        float : DIC using Spiegelhalter et al. (2002) definition
        float : DIC using Gelman et al. (2004) definition


    Script to run hierarchical Bayesian MCMC for inference of emissions using
    pymc3 to solve the inverse problem.

    Args:
        species (str):
            Species of interest
        sites (list):
            List of site names
        domain (str):
            Inversion spatial domain.
        meas_period (list):
            Averaging period of measurements
        start_date (str):
            Start time of inversion "YYYY-mm-dd"
        end_date (str):
            End time of inversion "YYYY-mm-dd"
        outputname (str):
            Unique identifier for output/run name.
        species_footprint (str, optional):
            species of the footprint to be imported, if different to the species
            of interest (e.g. import co2 footprints for HiTRes studies)
        HiTRes (bool)
            True if using HiTRes footprints
        outputpath (str):
            Path to where output should be saved.
        xprior (dict):
            Dictionary containing information about the prior PDF for emissions.
            The entry "pdf" is the name of the analytical PDF used, see
            https://docs.pymc.io/api/distributions/continuous.html for PDFs
            built into pymc3, although they may have to be coded into the script.
            The other entries in the dictionary should correspond to the shape
            parameters describing that PDF as the online documentation,
            e.g. N(1,1**2) would be: xprior={pdf:"normal", "mu":1, "sd":1}.
            Note that the standard deviation should be used rather than the
            precision. Currently all variables are considered iid.
        bcprior (dict):
            Same as above but for boundary conditions.
        sigprior (dict):
            Same as above but for model error.
        offsetprior (dict):
            Same as above but for bias offset. Only used is addoffset=True.
        nit (int):
            Number of iterations for MCMC
        burn (int):
            Number of iterations to burn in MCMC
        tune (int):
            Number of iterations to use to tune step size
        nchain (int):
            Number of independent chains to run (there is no way at all of
            knowing whether your distribution has converged by running only
            one chain)
        emissions_name (dict, optional):
            Allows emissions files with filenames that are longer than just the species name
            to be read in (e.g. co2-ff-mth_EUROPE_2014.nc). This should be a dictionary
            with {source_name: emissions_file_identifier} (e.g. {'anth':'co2-ff-mth'}). This way
            multiple sources can be read in simultaneously if they are added as separate entries to
            the emissions_name dictionary.
        inlet (str/list, optional):
            Specific inlet height for the site (must match number of sites)
        fpheight (dict, optional):
            Specific release height for the sites' footprints.
            E.g. fpheight={"TAC":"185m"}(must match number of sites).
        instrument (str/list, optional):
            Specific instrument for the site (must match number of sites).
        fp_basis_case (str, optional):
            Name of basis function to use for emissions.
        bc_basis_case (str, optional):
            Name of basis case type for boundary conditions (NOTE, I don't
            think that currently you can do anything apart from scaling NSEW
            boundary conditions if you want to scale these monthly.)
        obs_directory (str, optional):
            Directory containing the obs data (with site codes as subdirectories)
            if not default.
        fp_directory (str, optional):
            Directory containing the footprint data
            if not default.
        bc_directory (str, optional):
            Directory containing the boundary condition data
            if not default.
        flux_directory (str, optional):
            Directory containing the emissions data if not default
        basis_directory (str, optional):
            Directory containing the basis function
            if not default.
        country_file (str, optional):
            Path to the country definition file
        max_level (int, optional):
            The maximum level for a column measurement to be used for getting obs data
        quadtree_basis (bool, optional):
            Creates a basis function file for emissions on the fly using a
            quadtree algorithm based on the a priori contribution to the mole
            fraction if set to True.
        nbasis (int):
            Number of basis functions that you want if using quadtree derived
            basis function. This will optimise to closest value that fits with
            quadtree splitting algorithm, i.e. nbasis % 4 = 1.
        filters (list, optional):
            list of filters to apply from name.filtering. Defaults to empty list
        averagingerror (bool, optional):
            Adds the variability in the averaging period to the measurement
            error if set to True.
        bc_freq (str, optional):
            The perdiod over which the baseline is estimated. Set to "monthly"
            to estimate per calendar month; set to a number of days,
            as e.g. "30D" for 30 days; or set to None to estimate to have one
            scaling for the whole inversion period.
        sigma_freq (str, optional):
            as bc_freq, but for model sigma
        sigma_per_site (bool):
            Whether a model sigma value will be calculated for each site independantly (True) or all sites together (False).
            Default: True
        country_unit_prefix ('str', optional)
            A prefix for scaling the country emissions. Current options are:
            'T' will scale to Tg, 'G' to Gg, 'M' to Mg, 'P' to Pg.
            To add additional options add to acrg_convert.prefix
            Default is none and no scaling will be applied (output in g).
        add_offset (bool):
            Add an offset (intercept) to all sites but the first in the site list. Default False.

    Returns:
        Saves an output from the inversion code using inferpymc3_postprocessouts.

    TO DO:
        Add a wishlist...


    Rerun the MCMC code by taking the inputs from a previous output using this code
    and rewrite a new output. This allows reproducibility of results without the need
    to transfer all raw input files.

    Args:
        input_file (str):
            Full path to previously written ncdf file
        outputname (list):
            Unique identifier new for output/run name.
        outputpath (str):
            Path to where output should be saved.

    Returns:
        Saves an output from the inversion code using inferpymc3_postprocessouts.

    Note: At the moment fluxapriori in the output is the mean apriori flux over the
          inversion period and so will not be identical to the original a priori flux, if
          it varies over the inversion period.


 Read GC data

        Args:
            dotC_file (str): Filepath for .C data file
            scale (dict): Dictionary to hold scales for each species
            units (dict): Dictionary to hold units for each species
        Returns:
            tuple: Tuple of pandas.Dataframe, species list, units dict, species dict


    Process GC data per site and instrument
    Instruments can be:
        "GCMD": GC multi-detector (output will be labeled GC-FID or GC-ECD)
        "GCMS": GC ADS (output GC-ADS)
        "medusa": GC medusa (output GC-MEDUSA)

    Network is the network name for output file.


 Read CRDS data

        Args:
            data_file (str): Path to data file
        Returns:
            tuple: Tuple of xarray.Dataset and list of species


    Process CRDS data

    Args:
        site (str): Three letter site code
        network (str): Network string only for output
        input_directory (str, default=None): Directory holding input files
        output_directory (str, default=None): Directory for output files
        date_range (list, default=None): Start and end date for output. If you only want an end date,
                                        just put a very early start date (e.g. ["1900-01-01", "2010-01-01"])
        version (str, default=None): Version string for output filename


    Process Georgia Tech ALE or GAGE observations

    Args:
        site (str): ADR, RPB, ORG, SMO, CGO or MHD
        network (str): ALE or GAGE


    Run processing scripts through an array job:

    qsub -J 1-50 -k oe -j oe -Wsandbox=PRIVATE process_gcwerks_array.sh

    Note that will need to increase the max index to more than 40 if we add more stations/instruments

    Check job status using qstat -t <JOBID>[] (note the square brackets)


 Read site information from JSON

        Args:
            site (str): Three letter site code
            network (str): Network name
        Returns:
            dict: Dictionary containing site attributes


    This function writes attributes to an xarray.Dataset so that they conform with
    the CF Convention v1.6

    Attributes of the xarray DataSet are modified, and variable names are changed

    If the species is a standard mole fraction then either:
        - species name will used in lower case in the file and variable names
            but with any hyphens taken out
        - name will be changed according to the species_translator dictionary

    If the species is isotopic data or a non-standard variable (e.g. APO):
        - Isotopes species names should begin with a "D"
            (Annoyingly, the code currently picks up "Desflurane" too. I've
             fixed this for now, but if we get a lot of other "D" species, we
             should make this better)
        - I suggest naming for isotopologues should be d<species><isotope>, e.g.
            dCH4C13, or dCO2C14
        - Any non-standard variables should be listed in the species_translator
            dictionary

    Args:
        ds (xarray.Dataset): Should contain variables such as "ch4", "ch4 repeatability".
            Must have a "time" dimension.
        species (str): Species name. e.g. "CH4", "HFC-134a", "dCH4C13"
        site (string): Three-letter site code
        network (str, default=None): Network site is associated with
        global_attribuates (dict, default=None): Dictionary containing any info you want to
            add to the file header (e.g. {"Contact": "Matt Rigby"})
        units (str, default=None): This routine will try to guess the units
            unless this is specified. Options are in units_interpret
        scale (str, default=None): Calibration scale for species.
        sampling_period (int, default=None): Number of seconds for which air
            sample is taken. Only for time variable attribute
        date_range (list of two strings, optional): Start and end date for output
            If you only want an end date, just put a very early start date
            (e.g. ["1900-01-01", "2010-01-01"])


    Create an output filename in the format
    output_directory/site/network-instrument_site_YYYYMMDD_species[-inlet]-version.nc

    Also creates a site directory in output_directory, if one doesn't exist

    Args:

        inlet (string, optional): Label for inlet. If none supplied, assumes that there
            is only one inlet, and no inlet info is added to file name
        version (string, optional): Version number for file. If none supplied, will
            use YYYYMMDD for day processed


    Creates an SQLite database in obs folder detailing contents of each file

    Args:
        data_directory (pathlib.Path or str, optional) : Path to user-defined obs_folder


    Archive old versions of files in an archive folder within each site folder.
    Will keep the maxiumum version number for each NETWORK-INSTRUMENT, and move
    older ones to a zip file.

    Args:
        site (string): Measurement site

        version (string): Specify a version to archive. If None, will archive older versions


    Reads a generic delimited data file.
    Site needs to be added to site_info.json first (but not process_gcwerks_parameters.json)
    Example call:

    generic_data_read(site="GST",
                      network="COP26",
                      global_attributes={"data_owner": "Tim Arnold",
                                         "data_owner_email": "tim.arnold@npl.co.uk",
                                         "inlet_height_magl": 100.0,
                                         "comment": "Created from glasgow-picarro-1min.csv"},
                      inlet_filename=None,    # Use None if there is only one inlet at the site
                      instrument="picarro",
                      sampling_period=60,
                      input_file="/group/chemistry/acrg/obs_raw/GST/glasgow-picarro-1min.csv",
                      output_directory="/group/chemistry/acrg/obs/",
                      sep=",",
                      skipinitialspace=True,
                      datetime_var="time",
                      datetime_format="%Y-%m-%d %H:%M:%S",
                      time_offset_seconds=-30,    # Value added to timestamp to get left-labelled timestamps in output
                      variables={"co2_C": "co2",
                                 "co2_stdev": "co2_variability",
                                 "co2_N": "co2_number_of_observations",
                                 "ch4_C": "ch4",
                                 "ch4_stdev": "ch4_variability",
                                 "ch4_N": "ch4_number_of_observations",
                                 "co_C": "co",
                                 "co_stdev": "co_variability",
                                 "co_N": "co_number_of_observations"},
                      scales={"co2": "WMO-X2019",
                              "ch4": "WMO-X2004A",
                              "co": "WMO-X2014A"})


Read data from World Data Centre for Greenhouse Gases


Read NIES data files


    Examples of files that this will process:
        fname = "/data/shared/obs_raw/NIES/HAT/HAT_20170804_PFC-318.xlsx"
        species = "PFC-318"
        site = "HAT"

        fname = "/data/shared/obs_raw/NIES/HAT/HAT_20170628_CHCl3.txt"
        species = "CHCl3"
        site = "HAT"


N2O files from NIES


Observations from the SIO carbon cycle group


    Process Goethe Frankfurt University data files for Taunus

    Inputs are site code and species

    Assumes that file names start with a date, routine will pick the latest one


    Process Amazon Tall Tower Observatory data.

    Search string used is "*{version}*.dat" and currently reprocesses all matching files in
    folder.

    General notes:
       - For the period of 2013-06-01 to 2013-10-29 one of the two CRDS instruments (D9) was
       substituted and then replaced. Multiple files are created if this time period is covered.
       - CO2 was measured by two instruments (one of which was substituted) as described above,
       so multiple files for CO2 covering the same time period are generated.
       - Due to the buffer system and the length of the inlets, there is some time delay
       between the arrival of the air mass at the inlet and the time of the measurement. This
       has *not* been factored into the time points in the output.

    Example of input file (ATTO_Pic89_db30_v1_f201203_v1.dat) (line numbers added in [])
    [1]   60 1001
    [...]
    [57]  20120301	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1
    [58]	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999	9999
    [59]  [s]	[ppb]	[ppb]	[ppb]	[ppb]	[ppb]	[ppm]	[ppm]	[ppm]	[ppm]	[ppm]	[ppb]	[ppb]	[ppb]	[ppb]	[ppb]	[ppm]	[ppm]	[ppm]	[ppm]	[ppm]
    [60]  TimeUTC	D8CO1_1	D8CO1_3	D8CO1_4	D8CO1_5	D8CO1_6	D8CO2_1	D8CO2_3	D8CO2_4	D8CO2_5	D8CO2_6	D9CH4_1	D9CH4_3	D9CH4_4	D9CH4_5	D9CH4_6	D9CO2_1	D9CO2_3	D9CO2_4	D9CO2_5	D9CO2_6
    [61]  518400	117.39	113.91	118.48	120.00	123.70	399.57	397.99	402.17	430.73	431.23	1841.28	1841.43	1840.63	1839.96	1839.38	399.51	398.05	402.19	430.69	431.20
    [62]  520200	115.15	117.60	123.04	124.25	125.12	396.45	396.08	399.77	420.84	425.70	1839.65	1840.56	1841.10	1841.07	1841.22	396.42	396.14	399.87	420.83	425.62

    Args:
        species (str) :
            Options are:
                "CH4","CO2" and "CO".
        inlet (int) :
            5 different inlet heights are available corresponding to:
                1 - 79m
                3 - 53m
                4 - 38m
                5 - 24m
                6 - 4m
        version (str, optional) :
            Version of the data. At the moment only "v1" is available but other data may become
            available with new versions in future.

    TODO: There is a BUG that when splitting between the different instruments there is an
    overlap between the end date of the first file (2013-06-01) and the start date of the second
    file. Xarray selection here doesn't seem to be doing what we expect. May cause issues when
    using the data over this period.


Max Planck observations


    Process BAS Falkland Island data (may be a temporary raw file while CEDA archive is not allowing
    data to be downloaded).


Processing measurements taking from the BT Tower in London


    Process the London Thames Barrier Picarro data from Valerio Ferracci

    Returns
    -------
    None.


    Code to process raw Picarro data from the NPL Teddington campus roof
    Excel files must be pre-processed to csv manually first

    Returns
    -------
    None.


Data files from MOYA and ZWAMPS flights, site_name should be either "CONGO-FAAM" or "BOLIVIA-TWIN-OTTER"


    Code to process the various LICOR devices as part of the LGHG network

    Returns
    -------
    None.


    Check to see if there are other names that we should be using for
    a particular input. E.g. If CFC-11 or CFC11 was input, go on to use cfc-11,
    as this is used in species_info.json

    Args:
        search_string (str): Input string that you're trying to match
        info (dict): Dictionary whose keys are the "default" values, and an
             variable that contains other possible names
    Returns:
        corrected string


    Convert to a new calibration scale, based on conversions in obs_scale_convert.csv

    Args:
        ds (xarray Dataset): Must contain an mf variable (mole fraction), and scale must be in global attributes
        species (str): species name
        to_scale (str): Calibration scale to convert to


    Function for appending flux and country output to file

    Only use this function once file has already been created
    Create file first using write_netcdf function below


    Function for writing all flux and country output to file

    Only use this function for first set of variables
    Once file has been created, use append_netcdf function above


    This function extracts the molar mass of a species from the data/species_info.json file.
    Returns:
        float : Molar mass of species


    This function extracts platform (if specified) for the site from acrg_site_info.json file.
    network can be specified if site is associated with more than one. If not specified, the first
    network will be used by default.
    Returns:
        str : Platform type (e.g. "site", "satellite", "aircraft")


    The define_stations function defines the latitude and longitude values for each site within
    a dataset.

    If sites is not specified, if the platform for the site is listed as "aircraft" or
    "satellite" in the acrg_site_info.json file then no values are included in the stations
    dictionary for this site.

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects dataset to contain:
                release_lons - Longitude values for each site. Dimension = len(sites)
                release_lats - Latitude values for each site. Dimension = len(sites)
                y_site       - Site identifier for each measurement. Dimension = nmeasure
        sites (list/None, optional) :
            List of sites to look for within dataset.
            If not specified, the sites will be extracted from the input dataset assuming a
            data variable "sites" is included within the dataset.
        use_site_info (bool, optional) :
            Use positions from acrg_site_info.json file rather than extract them from the tdmcmc dataset.
            Default = False.

    Returns:
        dict :
            Dictionary containing "site"_lat, "site"_lon values for each site.


    The x_post_mean function extracts the posterior values for all iterations and calculates
    the mean. This is reshaped onto a latitude x longitude grid.

    Expects latitude and longitude coords within dataset to be named "lat" and "lon".

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)

    Returns:
        numpy.array (nlat x nlon):
            Array containing mean posterior emissions values on a latitude x longitude grid.


    The x_post_percentile function extracts the posterior values for all iterations and calculates
    a set of percentiles. This is reshaped onto latitude x longitude grid.

    Expects latitude and longitude coords within dataset to be named "lat" and "lon".

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)

    Returns:
        numpy.array (nlat x nlon x npercentiles):
            Array containing posterior values for each percentile on a latitude
            x longitude grid.


    The flux_iterations function calculates the posterior flux values for each saved iteration
    within the tdmcmc output.

    Expects latitude, longitude and nIt coords within dataset to be named "lat", "lon" and "nIt".

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon
    Returns:
        numpy.array (nlat x nlon x nIt):
            Array containing posterior flux values for each saved iteration within tdmcmc.


    The flux_mean function calculates the mean flux based on the prior emissions and posterior
    scaling.

    Expects latitude and longitude coords within dataset to be named "lat" and "lon".

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects data set to contain:
                x_post_vit - posterior scaling for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon
    Returns:
        numpy.array (nlat x nlon):
                Array containing posterior flux values on a latitude x longitude grid.


    The flux_percentile function calculates the flux values for a set of percentiles.

    Expects latitude and longitude coords within dataset to be named "lat" and "lon".

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon

    Returns:
        numpy.array (nlat x nlon x npercentiles):
            Array containing posterior flux values for each percentile on a latitude x longitude
            grid.


    The flux_diff function calculates the flux difference between the prior and the posterior.

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon
    Returns:
        numpy.array (nlat x nlon):
            Array containing flux difference values on a latitude x longitude grid.


    The k_mean_percentile function calculates the mean number of regions (k) and a set of percentiles
    within the saved iterations.

    Expects nIt coord within dataset to be named "nIt".

    Args:
        ds (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script).
            Expects data set to contain:
                k_it - number of regions for each iteration. Dimensions = nIt
    Returns:
        if percentiles are specified:
            float, np.array (npercentiles) :
                Mean and percentile array for number of regions within saved iterations.
        if percentiles are not specified:
            float :
                Mean number of regions within saved iterations


    Calculate the normalisation of a diverging cbar around a given value
    Prevents bias due to asymetry in data affectin scale

    Args:
        data : numpy array of data to plot
        zero : the centre value of the cmap
        minValue : smallest value to use in calculation
        maxValue : largest value to use in calculation

    Returns:
        a normalization function to be fed into plot


    The plot_scale_map function plots 2D scaling map(s) of posterior x. This is the degree of
    scaling which has been applied to prior emissions.

    Args:
        ds_list (list) :
            List of xarray.Dataset objects. Each dataset is an output from run_tdmcmc()
            function (tdmcmc_inputs.py script).
            Expects each data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
        grid (bool, optional) :
            Whether to plot the posterior on one figure as a grid or on individual plots.
        labels (str/list, optional) :
            Can specify either one label for all plots (str) or a different label for
            each plot.
            If list is specified, it must match number of datasets in ds_list.
        plot_stations (bool, optional) :
            Plot site positions on the output map. Will not plot aircraft or satellite positions.
        use_site_info (bool, optional) :
            If plotting site positions, use positions from acrg_site_info.json file rather
            than extract them from the tdmcmc dataset.
            Default = False.

        See plot_map() function for definition of remaining inputs.

    Returns:
        None

        If out_filename specified:
            Plot is written to file
        Otherwise:
            Plot is displayed interactively


    The plot_abs_map function plots 2D map(s) of posterior x in g/m2/s.

    Args:
        ds_list (list) :
            List of xarray.Dataset objects. Each dataset is an output from run_tdmcmc()
            function (tdmcmc_inputs.py script).
            Expects each data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon
        species (str) :
            Species for the tdmcmc output.
        grid (bool, optional) :
            Whether to plot the posterior on one figure as a grid or on individual plots.
        labels (str/list) :
            Can specify either one label for all plots (str) or a different label for
            each plot.
            If list is specified, it must match number of datasets in ds_list.
        plot_stations (bool, optional) :
            Plot site positions on the output map. Will not plot aircraft or satellite positions.
        use_site_info (bool, optional) :
            If plotting site positions, use positions from acrg_site_info.json file rather
            than extract them from the tdmcmc dataset.
            Default = False.

        See plot_map() function for definition of remaining inputs.

    Returns:
        None

        If out_filename specified:
            Plot is written to file
        Otherwise:
            Plot is displayed interactively


    The plot_diff_map function plots 2D map(s) of the difference between the prior and
    posterior x in g/m2/s.

    Args:
        ds_list (list) :
            List of xarray.Dataset objects. Each dataset is an output from run_tdmcmc()
            function (tdmcmc_inputs.py script).
            Expects each data set to contain:
                x_post_vit - posterior values for each iteration flattened along lat-lon axis.
                             Dimensions = nIt x NGrid (nlat x nlon)
                q_ap       - a priori flux values on a latitude x longitude grid.
                             Dimensions = nlat x nlon
        species (str) :
            Species for the tdmcmc output.
        grid (bool, optional) :
            Whether to plot the posterior on one figure as a grid or on individual plots.
        labels (str/list) :
            Can specify either one label for all plots (str) or a different label for
            each plot.
            If list is specified, it must match number of datasets in ds_list.
        plot_stations (bool, optional) :
            Plot site positions on the output map. Will not plot aircraft or satellite positions.
        use_site_info (bool, optional) :
            If plotting site positions, use positions from acrg_site_info.json file rather
            than extract them from the tdmcmc dataset.
            Default = False.

        See plot_map() function for definition of remaining inputs.

    Returns:
        None

        If out_filename specified:
            Plot is written to file
        Otherwise:
            Plot is displayed interactively


    Plot a histogram of the number of regions in trandimensional inversion

    Use this as a check for whether kmax should be larger


    Generates national totals for a given list of countries
    Args:
        ds_mcmc (xarray.Dataset) :
            Output from run_tdmcmc() function (tdmcmc_inputs.py script). (post_mcmc xarray dataset)
        countries (list) :
            List of countries (see data_path/countries files for names)
            In general names are all capitalized.
        species (str) :
            CH4, CO2 etc.
        domain (str) :
            Domain name of interest.
            e.g. EUROPE, SOUTHAMERICA etc.
        x_post_vit (numpy.array/None, optional) :
            Posterior values (Dims: nIt x NGrid) (flattened on lat and lon dimensions).
            If not specified, will be extracted from ds_mcmc.
        q_ap_abs_v (numpy.array/None, optional) :
            Flux a priori values (Dims: NGrid) (flattened on lat and lon dimensions).
            If not specified, will be extracted from ds_mcmc.
        percentiles (list) :
            List of percentiles to extract.
            Default = [5,16,50,84,95]
        units (str/None, optional) :
            Need to specify to get something sensible out, otherwise returns in g/yr
            Options are Pg/yr, Tg/yr,Gg/yr Mg/yr
        ocean (bool, optional) :
            Default is True, If False only include emissions from land surface
        uk_split (bool, optional) :
            Break UK into devolved administrations
                Country names then have to be ['Eng', 'Sco', 'Wales',
                NIre', 'IRELAND', 'BENELUX']. Horribly inconsistent I know!
            Default = False
        fixed_map (bool, optional) :
            TODO: Add comment

    Returns:
        (5 x numpy.array) :
            Country totals for each iteration in units specified (ncountries x nIt),
            Mean of country totals in units specified (ncountries),
            Percentiles for each country in units specified (ncountries x npercentiles),
            Prior for each country in units specified (ncountries),
            Country index map (nlat x nlon)

    Output in Tg/yr


    Calculate country emissions across multiple datasets. Combine mean and percentiles into
    arrays for all time points.
    See process.country_emissions() function for details of inputs
    Returns:
        (5 x numpy.array) :
            Country totals for each iteration in units specified (ncountries x nIt),
            Mean of country totals for each dataset in units specified (ncountries x ntime),
            Percentiles for each country for each dataset in units specified (ncountries x npercentiles x ntime),
            Prior for each country in units specified (ncountries),
            Country index map (nlat x nlon)