    The gosat_process function processes GOSAT input files from a directory.
    As part of processing the GOSAT input data there are multiple options including filtering based on
    various criteria and binning. See gosat_process_file() function for more details.

    Args:
        site (str) :
            Specified sub-set defined for gosat e.g. GOSAT-INDIA. Should be defined within site_info.json
        species (str, optional) :
            Species of interest. Should be defined within species_info.json
            Default = "ch4"
        input_directory (str, optional) :
            Top level directory containing GOSAT CH4 Level 2 Data Product files only.
            Assumes sub-directories are labelled by year and will find sub-directory based on start
            and end dates, if specified.
            If no dates are specified all files within all year labelled sub-directories will be processed.
            See top of file for default.
        start (str, optional) :
            Start date for range of files to be processed. Should be in format "YYYY-MM-DD"
        end (str, optional) :
            End date for range of files to be processed (optional but must be specified if start specified).
            Should match format of start.
        lat_bounds (list, optional) :
            Upper and lower bounds for latitude. (two-item list e.g. [6.0,36.5])
        lon_bounds (list, optional) :
            Upper and lower bounds for longitude. (two-item list e.g. [70.0,90.5])
        domain (str, optional) :
            If lat_bounds and lon_bounds are not specified a domain can be specified instead.
            This must be a predetermined NAME domain and a footprint file must exist to extract the latitude
            and longitude bounds.
            If both domain and pair of lat_bounds and lon_bounds are specified, the explictly specified
            bounds will take precedence.
            This parameter will also be used to find folder containing surface pressure files (if
            applicable) if pressure_domain is not specified.
        coord_bin (float/list, optional) :
            If applying binning, this should be the size of each bin in degrees.
            To specify the same bin for latitude and longitude a single values (float) can be used.
            To specify different bins include a two item list (e.g. [0.234,0.356]).
            Set to None if no binning is required.
        quality_filt (bool, optional) :
            Whether to remove data points using the quality filter flag (xch4_quality_flag)
            indicating possibly bad data (=1).
            Default = True.
        bad_pressure_filt (bool, optional) :
            Whether to remove data points where any pressure value = -9999.99 (seems to be a flag).
            Default = True.
        name_sp_filt (bool, optional) :
            Whether to remove data points based on the comparison between the GOSAT surface pressure value
            and the NAME surface pressure value.
            Exact conditions are specified by name_filters with associated values specified by cutoff
            and layer_range parameters if applicable.
            Default = False.
        mode (str, optional) :
            Which retrieval mode (retr_flag) to filter by (if any). Options: 'land' or 'glint'.
            Set to None if no filtering by mode is required.
            Default = None.
        use_name_pressure (bool, optional) :
            Whether to use the NAME surface pressure rather than the input GOSAT surface pressure
            (first pressure_levels value for each time point) when creating the NAME csv file.
            Note:
                 - This is independent of the name_sp_filt and both or either can be applied.
                 - This does not affect the pressure_levels variable in any netCDF (.nc) output.
        name_filters (list, optional) :
            If name_sp_filt=True, this is a list of which filters which will be used. Options are: "cutoff",
            "level_order","dpressure_range".
            This value must be specified if name_sp_filt=True.
            See name_pressure_filter() function for details of these filters.
        cutoff (float, optional) :
            When applying the "cutoff" NAME filter, this is the percentage cutoff to apply from comparison
            between input pressure data and NAME pressure.
            Default = 5.0
        layer_range (list, optional) :
            When applying the "dpressure_range" NAME filter, this is the range in metres the surface layer
            should have (will be converted to pressure units using barometric equation). (two-item list).
            Default = [50.,500.]
        pressure_base_dir (str, optional) :
            Base directory containing the NAME output files for the SurfacePressure run.
            If pressure_domain (or domain) is specified this will be appended to the pressure_base_dir.
            Default = "$DATA_PATH/LPDM/surface_pressure/"
        pressure_domain (str, optional) :
            Domain over which surface pressure has been created. Only needs to be specified if this is
            different (i.e. wider domain) than domain, or domain has not been explictly specified.
            Will be used to find full pressure_dir path to Pressure_*.txt files.
        pressure_max_days (int, optional) :
            Maximum number of days from time within ds to search for the relevant pressure data.
            Default = 31 (days).
        pressure_day_template (bool, optional) :
            Use nearest day as a template for the change of pressure over the course of the day and match
            to the nearest time on that day.
            E.g. if datetime is 2012-05-01 03:00:00, max_days is 31 and nearest day is 2012-01-01 then
            use entry from 2012-01-01 03:00:00 (rather than 2012-02-01 00:00:00, which would be the
            nearest entry).
            Default = True.
        write_nc (bool, optional) :
            Write output .nc files (one per bin along time axis by default)
            Default = False.
        output_directory (str, optional) :
            Top level directory to write output. Full path will be based on the "network" related to "site"
        write_name (bool, optional) :
            Write output .csv file for input into NAME (one per bin along time axis by default)
        name_directory (str, optional) :
            Top level directory to write files for NAME. Full path will be based on the "network" related to "site"
            Default defined at the top of this module.
        file_per_day (bool, optional) :
            Group together all points into create one output file per day rather than one per data point.
            Default = False.
        max_name_level (int, optional) :
            	Maximum level to use when writing out NAME csv files.
            Default = 17
        max_name_points (int/None, optional) :
            Only applicable if file_per_day is True.
            Maximum number of points to write to NAME csv file if writing file per day.
            If number of points within the day exceeds max_points multiple files will be written out with
            a character after the date of "-A","-B",...
            NOTE: This will not be applied to netCDF files even if number of points is greater than
            max_name_points, only to the NAME csv files. All points per day will be written to one file.
        overwrite (bool, optional) :
            Allow any files already present within the full path to output_directory and name_directory
            to be overwritten.
            Default = False.

    Returns:
        xarray.Dataset : merged dataset for all processed GOSAT files

        If write_nc is set to True:
            Set of .nc files will be written within path started by output_directory
        If write_name is set to True:
            Set of .csv files will be written within path started by name_directory


    The param_dict function defines the nested dictionary for the GOSAT process input parameters to be passed to
    the gosat_process function.
    Currently this format is based on "gosat_process_template.ini" and this file should not be altered unless you wish to
    change the expected parameters and types for all parameter files of this type.

    Returns
        param_type nested dictionary


    The essential_param function defines the parameters which *must* be specified in the
    gosat input parameter file.

    All other parameters will be set as optional.

    Returns:
        list: parameter names (str)


    The check function applies additional checks on parameters within the param dictionary (extracted from a
    configuration file) to ensure they are of the correct format.

    This includes:
        Check other necessary parameters are specified when certain conditions are set to true
            If 'write_name' is specified, ensure 'name_directory' is not set to "/path/to/output/directory/"
            If 'write_nc' is specified, ensure 'output_directory' is not set to "/path/to/output/directory/"

    Args:
        param (dict) : output of param function. Dictionary containing parameter and value details.

    Returns:
        None

        Raises Error if any of the above conditions are not met.


    The param function reads the parameters for input into the acrg_gosat.gosat_process(...) function.
    If param = param(config_file), the acrg_gosat.gosat_process function can be called as:
        acrg_gosat.gosat_process(**param)

    Note: Parameters which must always be specified in the input configuration file are defined by
    essential_param() function.
    Note: Additional checks on the format and inclusion of some parameters will be performed by the gosat_check()
    function.

    Args:
        config_file (str) : Configuration filename. Should match format of gosat_process_template.ini file.

    Returns:
        collections.OreredDict : dictionary of parameters from config file.


    Plot data from one tropomi oribit in its native resolution.

    Args:
        filename (str) :
            Full filename for tropomi data (including path).
        parameter (str, optional) :
            Parameter within tropomi data to plot (3D - time, scanline, ground_pixel only).
            i.e. not set up to plot parameters with additional dimensions e.g. averaging_kernel
            Default = "methane_mixing_ratio_bias_corrected"
        projection (str, optional) :
            Map projection to use when plotting. Currently limited to:
                - Geostationary (satellite view)
                - PlateCarree (equirectangular lat and lon, not good at the poles)
        central_longitude (float, optional) :
            Where to place central longitude when plotting.
            Default = 0.0
        set_extent (list/None, optional) :
            Only plot within given longitude and latitude bounds by passing a 4-item
            list containing:
                [lon0, lon1, lat0, lat1]
            To not include this option pass a None value.
            Default = None
        set_nan_zero (bool, optional) :
            Set any NaN values within the data to 0 when plotting.
            Default = True
        cmap (str, optional) :
            Colour map to use when plotting the meshgrid. See matplotlib documentation
            for the full list of options.
            Default = "YlOrBr" (Yellow Orange Brown)
        fig (Figure object/None, optional) :
            Pass an explicit matplotlib Figure object to use when creating the plot
            Default = None
        subplot (list, optional)
            Only relevant if fig is specified. Allows plot to placed as a subplot
            of the figure object. This should a 3-item list containing
            [nrows, ncols, number] e.g. [2, 1, 2]
            Default = [1, 1, 1] (one subplot)

    ## TODO: Add option to externally set min and max parameter values to be displayed
    # currently just uses the full value range.
    ## TODO: This has been tested on methane data files only so far.
    # Test this works with other tropomi data files.

    Returns:
        fig, ax - for plot


    Function efficiently opens xray datasets.

    Args:
        path (str)
        chunks (dict, optional)
            size of chunks for each dimension
            e.g. {'lat': 50, 'lon': 50}
            opens dataset with dask, such that it is opened 'lazily'
            and all of the data is not loaded into memory
            defaults to None - dataset is opened with out dask
        combine (str, optional)
            Way in which the data should be combined (if using chunks), either:
            'by_coords': order the datasets before concatenating (default)
            'nested': concatenate datasets in the order supplied


    Filter files for those in the start-end date range
    Avoids loading in data that is not needed

    Args:
        files (list) :
            files which are to be filtered
        start, end (str) :
            start and end of the date range required

    Returns:
        files (list) :
            list of files which are within the start-end date range
            if no files are found within this date range then the original file list is returned


    The filenames function outputs a list of available footprint file names,
    for given site, domain, directory and date range.

    Expect filenames of the form:
        [fp_directory]/domain/site*-height-species*domain*ym*.nc or [fp_directory]/domain/site*-height_domain*ym*.nc
        e.g. /data/shared/LPDM/fp_NAME/EUROPE/HFD-UKV-100magl-rn_EUROPE_202012.nc or /data/shared/LPDM/fp_NAME/EUROPE/MHD-10magl_EUROPE_201401.nc

    Args:
        site (str) :
            Site name. Full list of site names should be defined within data/site_info.json
        domain (str) :
            Domain name. The footprint files should be sub-categorised by the NAME domain name.
        start (str) :
            Start date in format "YYYY-MM-DD" for range of files to find.
        end (str) :
            End date in same format as start for range of files to find.
        height (str) :
            Height related to input data.
        fp_directory (str) :
            a directory containing subfolders organized by domain, if files are not in the default directory
        met_model (str):
            Met model used to run NAME
            Default is None and implies the standard global met model
            Alternates include 'UKV' and this met model must be in the outputfolder NAME
        network (str, optional) :
            Network for site.
            If not specified, first entry in data/site_info.json file will be used (if there are multiple).
        species (str, optional)
            If specified, will search for species specific footprint files.
    Returns:
        list (str): matched filenames


    The read_netcdfs function uses xarray to open sequential netCDF files and
    and concatenates them along the specified dimension.
    Note: this function makes sure that file is closed after open_dataset call.

    Args:
        files (list) :
            List of netCDF filenames.
        dim (str, optional) :
            Dimension of netCDF to use for concatenating the files.
            Default = "time".
        chunks (dict)
            size of chunks for each dimension
            e.g. {'lat': 50, 'lon': 50}
            opens dataset with dask, such that it is opened 'lazily'
            and all of the data is not loaded into memory
            defaults to None - dataset is opened with out dask

    Returns:
        xarray.Dataset :
            All files open as one concatenated xarray.Dataset object


    The footprints function loads a NAME footprint netCDF files into an xarray Dataset.
    Flux and boundary conditions are also loaded if species or emissions_name is specified.

    Either specify:
        a) A file name:
            fp = footprints(filename)
        b) A site code, domain, and date range:
            fp = footprints("MHD",
                    start = "2014-01-01", end = "2014-01-01",
                    domain = "EUROPE")

    See filenames() function for expected format of files.

    Args:
        sitecode_or_filename (str) :
            Site (e.g. 'MHD') or a netCDF filename (*.nc) (str)
        met_model (dict or str)     : Met model used to run NAME for each site in data
                               Default is None and implies the standard global met model used for all sites
                               met_model = 'UKV' will work if all sites are the same 'UKV'
                               {"MHD":'UKV', "JFJ":None} or {"MHD":'UKV', "TAC":"UKV"}
                               {"MHD":None, "TAC":None} is equivalent to met_model = None
                               {"MHD":'UKV', "TAC":'UKV'} is equivalent to met_model = 'UKV'
        fp_directory (str) :
            a directory containing subfolders organized by domain, if files are not in the default directory
        start (str) :
            Start date in format "YYYY-MM-DD" for range of files to find.
        end (str) :
            End date in same format as start for range of files to find.
        domain (str) :
            Domain name. The footprint files should be sub-categorised by the domain.
        height (str, optional) :
            Height related to NAME. If the HEIGHT keyword is not specified, the default height from the
            data/site_info.json file is assumed.
        network (str, optional) :
            Network associated with the site. This is only needed if there are multiple network options.
            This is used to extract site information e.g. height from data/site_info.json.
        species (str) :
            Species name. All species names are defined data/species_info.json.
        HiTRes (bool, optional) :
            Whether to include high time resolution footprints.
            Default = False.
        chunks (dict)
            size of chunks for each dimension
            e.g. {'lat': 50, 'lon': 50}
            opens dataset with dask, such that it is opened 'lazily'
            and all of the data is not loaded into memory
            defaults to None - dataset is opened with out dask

    Returns:
        xarray.Dataset :
            Combined footprint files


    The flux function reads in all flux files for the domain and species as an xarray Dataset.
    Note that at present ALL flux data is read in per species per domain or by emissions name.
    To be consistent with the footprints, fluxes should be in mol/m2/s.

    Expect filenames of the form:
        [flux_directory]/domain/species.lower()_*.nc
        e.g. [/data/shared/LPDM/emissions]/EUROPE/ch4_EUROPE_2013.nc

    TODO: This may get slow for very large flux datasets, and we may want to subset.

    Args:
        domain (str) :
            Domain name. The flux files should be sub-categorised by the domain.
        species (str) :
            Species name. All species names are defined data/species_info.json.
            The source can also be specified as part of the species name e.g. "co2-ff"
            will find all co2 emissions file for the fossil fuel sector.
        start (str, optional) :
            Start date in format "YYYY-MM-DD" to output only a time slice of all the flux files.
            The start date used will be the first of the input month. I.e. if "2014-01-06" is input,
            "2014-01-01" will be used.  This is to mirror the time slice functionality of the filenames
            function.
        end (str, optional) :
            End date in same format as start to output only a time slice of all the flux files.
            The end date used will be the first of the input month and the timeslice will go up
            to, but not include, this time. I.e. if "2014-02-25' is input, "2014-02-01" will be used.
            This is to mirror the time slice functionality of the filenames function.
        flux_directory (str, optional) :
            flux_directory can be specified if files are not in the default directory.
            Must point to a directory which contains subfolders organized by domain.
        HiTRes (bool, optional) :
            True if importing HiTRes fluxes
        H_back (int, optional) :
            hours back of data to collect if using the HiTRes processes
            if HiTRes=True, by default H_back=24
    Returns:
        xarray.Dataset : combined dataset of all matching flux files


    Creates a dictionary of high and low frequency fluxes for use with HiTRes footprints.

    Args:
        domain (str) :
            Domain name. The flux files should be sub-categorised by the domain.
        emissions_dict (dict) :
            This should be a dictionary of the form:
                {'high_freq': high_freq_emissions_name, 'low_freq': low_freq_emissions_name}
                e.g. {'high_freq':'co2-ff-2hr', 'low_freq':'co2-ff-mth'}.
                Or it can be the emissions names for different sources
                e.g. {'anth': {'high_freq':'co2-ff-2hr', 'low_freq':'co2-ff-mth'}}
        start (str, optional) :
            Start date in format "YYYY-MM-DD" to output only a time slice of all the flux files.
            The start date used will be the first of the input month. I.e. if "2014-01-06" is input,
            "2014-01-01" will be used.  This is to mirror the time slice functionality of the filenames
            function.
        end (str, optional):
            End date in same format as start to output only a time slice of all the flux files.
            The end date used will be the first of the input month and the timeslice will go up
            to, but not include, this time. I.e. if "2014-02-25' is input, "2014-02-01" will be used.
            This is to mirror the time slice functionality of the filenames function.
        flux_directory (str, optional) :
            flux_directory can be specified if files are not in the default directory.
            Must point to a directory which contains subfolders organized by domain.
        H_back (int, optional) :
            hours back of data to collect, by default H_back=24
    Returns:
        dictionary:
            Dictionary containing xarray Datasets for both high and low frequency fluxes for the
            dates required and 1 month prior to start
            {'high_freq': xarray.Dataset, 'low_freq': xarray.Dataset}


    The boundary_conditions function reads in the files with the global model vmrs at the domain edges
    to give the boundary conditions as an xarray Dataset.

    Expect filenames of the form:
        [bc_directory]/domain/species.lower()_*.nc
        e.g. [/data/shared/LPDM/bc]/EUROPE/ch4_EUROPE_201301.nc

    Args:
        domain (str) :
            Domain name. The boundary condition files should be sub-categorised by the domain.
        species (str) :
            Species name. All species names are defined data/species_info.json.
        start (str, optional) :
            Start date in format "YYYY-MM-DD" to output only a time slice of all the flux files.
            The start date used will be the first of the input month. I.e. if "2014-01-06" is input,
            "2014-01-01" will be used.  This is to mirror the time slice functionality of the filenames
            function.
        end (str, optional):
            End date in same format as start to output only a time slice of all the flux files.
            The end date used will be the first of the input month and the timeslice will go up
            to, but not include, this time. I.e. if "2014-02-25' is input, "2014-02-01" will be used.
            This is to mirror the time slice functionality of the filenames function.
        bc_directory (str, optional) :
            bc_directory can be specified if files are not in the default directory.
            Must point to a directory which contains subfolders organized by domain.
        chunks (dict, optional):
            size of chunks to load data using dask e.g. {'time': 50}

    Returns:
        xarray.Dataset :
            Combined dataset of matching boundary conditions files


    The basis function reads in the all matching files for the basis case and domain as an xarray Dataset.

    Expect filenames of the form:
        [basis_directory]/domain/"basis_case"_"domain"*.nc
        e.g. [/data/shared/LPDM/basis_functions]/EUROPE/sub_transd_EUROPE_2014.nc

    TODO: More info on options for basis functions.

    Args:
        domain (str) :
            Domain name. The basis files should be sub-categorised by the domain.
        basis_case (str) :
            Basis case to read in. Examples of basis cases are "voroni","sub-transd",
            "sub-country_mask","INTEM".
        basis_directory (str, optional) :
            basis_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.Dataset : combined dataset of matching basis functions


    The basis_boundary_conditions function reads in all matching files for the boundary conditions
    basis case and domain as an xarray Dataset.

    Expect filesnames of the form:
        [bc_basis_directory]/domain/"basis_case"_"domain"*.nc
        e.g. [/data/shared/LPDM/bc_basis_directory]/EUROPE/NESW_EUROPE_2013.nc

    TODO: More info on options for basis functions.

    Args:
        domain (str) :
            Domain name. The basis files should be sub-categorised by the domain.
        basis_case (str) :
            Basis case to read in. Examples of basis cases are "NESW","stratgrad".
        bc_basis_directory (str, optional) :
            bc_basis_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.Datset : combined dataset of matching basis functions


    Check if two datasets need to be reindexed_like for combine_datasets

    Args:
        dsa (xarray.Dataset) :
            First dataset to check
        dsb (xarray.Dataset) :
            Second dataset to check

    Returns:
        boolean:
            True if indexes match, False if datasets must be reindexed


    Slice and resample two datasets to align along time

    Args:
        ds1, ds2 (xarray.Dataset) :
            Datasets with time dimension. It is assumed that ds1 is obs data and ds2 is footprint data

        platform (str) :
            obs platform used to decide whether to resample

        resample_to_ds1 (boolean) :
            Override resampling to coarser resolution and resample to ds1 regardless

    Returns:
        2 xarray.dataset with aligned time dimensions


    Output a dictionary of xarray footprint datasets, that correspond to a given
    dictionary of Pandas dataframes.

    Args:
        data (dict)          : Input dictionary of dataframes with the sites as the keys.
                               Should match output from acrg_agage.get_obs() function. For example:
                               data = {"MHD": MHD_dataframe, "TAC": TAC_dataframe}
        domain (str)         : Domain name. The footprint files should be sub-categorised by the domain.
        met_model (dict or str)     : Met model used to run NAME for each site in data
                               Default is None and implies the standard global met model used for all sites
                               met_model = 'UKV' will work if all sites are the same 'UKV'
                               {"MHD":'UKV', "JFJ":None} or {"MHD":'UKV', "TAC":"UKV"}
                               {"MHD":None, "TAC":None} is equivalent to met_model = None
                               {"MHD":'UKV', "TAC":'UKV'} is equivalent to met_model = 'UKV'
        load_flux (bool)     : True includes fluxes in output, False does not. Default True.
        load_bc (bool)       : True includes boundary conditions in output, False does not. Default True.
        calc_timeseries (bool) : True calculates modelled mole fractions for each site using fluxes, False does not. Default True.
        calc_bc (bool)       : True calculates modelled baseline for each site using boundary conditions, False does not. Default True.
        HiTRes (bool)        : Set to True to include HiTRes footprints in output. Default False.
        site_modifier        : An optional site modifier dictionary is used that maps the site name in the
                               obs file to the site name in the footprint file, if they are different. This
                               is useful for example if the same site FPs are run with a different met and
                               they are named slightly differently from the obs file. E.g.
                               site_modifier = {"DJI":"DJI-SAM"} - station called DJI, FPs called DJI-SAM
        height (dict)        : Height related to input data. Should be a dictionary with
                               {site: height} key:value pairs. Can be found from acrg_sites_info.json
        network (str/list)   : Network associated with the site. This is only needed if there are multiple
                               network options. This is used to extract site information
                               e.g. height from data/site_info.json.
                               Can be specified as a string for one network for all sites or as a list for
                               multiple networks.
        emissions_name (dict): 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.
                               If using HiTRes footprints, both the high and low frequency emissions files must be specified
                               in a second dictionary like so: {'anth': {'high_freq':'co2-ff-2hr', 'low_freq':'co2-ff-mth'}}.
                               It is not a problem to have a mixture of sources, with some that use HiTRes footprints and some
                               that don't.
        fp_directory         : a directory containing subfolders organized by domain, if files are not in the default directory
        flux_directory (str) : flux_directory can be specified if files are not in the default directory.
                               Must point to a directory which contains subfolders organized by domain.
                               (optional)
        bc_directory (str)   : Same sytax as flux_directory (optional)
        resample_to_data (bool) : If set to True, the footprints are resampled to the data time series.
                                  If set to False, the data is resampled to the data
                                  If set to None (default), then the footprints and data are sampled to the
                                  coarset resolution of the two.
                                  (optional)
        species_footprint (str) : species associated with the required footprint, if different to that given in data
                                  (optional)
        H_back (int) : hours of data required prior to start if using HiTRes processes
                       optional, if HiTRes=True by default H_back=24
        chunks (dict)
            size of chunks for each dimension of fp
            e.g. {'lat': 50, 'lon': 50}
            opens dataset with dask, such that it is opened 'lazily'
            and all of the data is not loaded into memory
            defaults to None - dataset is opened with out dask

    Returns:
        Dictionary of the form {"MHD": MHD_xarray_dataset, "TAC": TAC_xarray_dataset, ".flux": dictionary_of_flux_datasets, ".bc": boundary_conditions_dataset}:
            combined dataset for each site


    Add timeseries mole fraction values in footprint_data_merge

    Args:
        fp_and_data [dict]:
            output created during footprint_data_merge
        load_flux [boolean]:
            whether the flux was loaded


    Add boundary condition mole fraction values in footprint_data_merge
    Boundary conditions are multipled by any loss (exp(-t/lifetime)) for the species

    Args:
        fp_and_data [dict]:
            output created during footprint_data_merge
        load_bc [boolean]:
            whether the boundary conditon was loaded
        species [str]
            name of species in the dataset


    The fp_sensitivity function adds a sensitivity matrix, H, to each site xarray dataframe in fp_and_data.

    Basis function data in an array: lat, lon, no. regions. In each 'region'
    element of array there is a lt lon grid with 1 in region and 0 outside region.

    Region numbering must start from 1

    Args:
        fp_and_data (dict):
            Output from footprints_data_merge() function. Dictionary of datasets.
        domain (str):
            Domain name. The footprint files should be sub-categorised by the domain.
        basis_case:
            Basis case to read in. Examples of basis cases are "NESW","stratgrad".
            String if only one basis case is required. Dict if there are multiple
            sources that require separate basis cases. In which case, keys in dict should
            reflect keys in emissions_name dict used in fp_data_merge.
        basis_directory (str):
            basis_directory can be specified if files are not in the default
            directory. Must point to a directory which contains subfolders organized
            by domain. (optional)
        calc_timeseries (bool):
            if True, calculate the mf timeseries and add to the fpdm object,
            default is False

    Returns:
        dict (xarray.Dataset):
            Same format as fp_and_data with sensitivity matrix and basis function grid added.


    The bc_sensitivity adds H_bc to the sensitivity matrix, to each site xarray dataframe in fp_and_data.

    Args:
        fp_and_data (dict)       : Output from footprints_data_merge() function. Dictionary of datasets.
        domain (str)             : Domain name. The footprint files should be sub-categorised by the domain.
        basis_case (str)         : Basis case to read in. Examples of basis cases are "NESW","stratgrad".
        bc_basis_directory (str) : bc_basis_directory can be specified if files are not in the default
                                   directory. Must point to a directory which contains subfolders organized
                                   by domain. (optional)

    Returns:
        dict (xarray.Dataset) : Same format as fp_and_data with sensitivity matrix added.


    Applies filtering (in time dimension) to entire dataset.
    Filters supplied in a list and then applied in order. For example if you wanted a daily, daytime
    average, you could do this:

        datasets_dictionary = filtering(datasets_dictionary,
                                    ["daytime", "daily_median"])

    The order of the filters reflects the order they are applied, so for
    instance when applying the "daily_median" filter if you only wanted
    to look at daytime values the filters list should be
    ["daytime","daily_median"]

    Args:
        datasets_in         : Output from footprints_data_merge(). Dictionary of datasets.
        filters (list)      : Which filters to apply to the datasets.
                              All options are:
                                 "daytime"           : selects data between 1100 and 1500 local solar time
                                 "daytime9to5"       : selects data between 0900 and 1700 local solar time
                                 "nighttime"         : Only b/w 23:00 - 03:00 inclusive
                                 "noon"              : Only 12:00 fp and obs used
                                 "daily_median"      : calculates the daily median
                                 "pblh_gt_threshold" :
                                 "local_influence"   : Only keep times when localness is low
                                 "six_hr_mean"       :
                                 "local_lapse"       :
        keep_missing (bool) : Whether to reindex to retain missing data.

    Returns:
       Same format as datasets_in : Datasets with filters applied.


        Returns hour of day as a function of local solar time
        relative to the Greenwich Meridian.


Calculates the local ratio in the surrounding grid cells


Calculate daily median


Calculate six-hour median


Subset during daytime hours (9:00-17:00)


Subset during nighttime hours (23:00 - 03:00)


Select only 12pm data


        Subset for times when local influence is below threshold.
        Local influence expressed as a fraction of the sum of entire footprint domain.


    Plot footprint for a given timestamp.

    Args:
        fp_data (dict):
            Output of footprints_data_merge(). Dictionary of xarray datasets containing
            footprints and other variables
        date (str):
            Almost any time format should work (datetime object, string, etc). An example
            time format is '2014-01-01 00:00'. Footprints from all sites in dictionary that
            have time indices nearest to the specified time will be plotted.
        out_filename (str, optional):
            Full path to filname to save figure
        out_format (str, optional):
            Format to save figure (e.g., png or pdf)
        lon_range (list, optional):
            list of min and max longitudes [min, max] to plot
        lat_range (list, optional):
            list of min and max latitudes [min, max] to plot
        log_range (list, optional):
            list of min and max LOG10(footprints) for color scale
        plot_borders (bool, optional) :
            Plot country borders. Default = False.
        zoom (bool, optional):
            True will plot a zoomed map (+/- 10 degrees around all site in fp_data)
        colormap (str, optional):
            Color map to use for contour plot
            (https://matplotlib.org/examples/color/colormaps_reference.html)
        tolerance (float or str, optional):
            Maximum distance between date specified and closest available footprint
            Default is in nanosec if a float or in any units (e.g., '1H') if a string
        interpolate (bool, optional):
            If True, interpolates footprint between the nearest two footprints to the date specified
            If False, uses the nearest footprint avaialble
        dpi (int, optional):
            Dots per square inch resolution to save image format such as png
        figsize (tuple, optional):
            Specify figure size as width, height in inches. e.g. (12,9). Default = None.
        nlevels (int):
            Number of levels in contour plot.

    Returns
        None

        If out_filename == None:
            produces as interactive plot
        Else:
            saves plot as specified by the full path in out_filename and format in out_format


    3D plot showing the footprint and particle exit locations for a given timestamp.

    Args:
        fp_data (dict):
            Dictionary of xarray datasets containing footprints and other variables.
            Currently only one site will be plotted.
        date (str):
            Almost any time format should work (datetime object, string, etc). An example
            time format is '2014-01-01 00:00'. Footprints from all sites in dictionary that
            have time indices nearest to the specified time will be plotted.
        particle_direction (str):
            One of two options 'nw' = north-west or 'se' = south-west to determine which
            edges of the domain are plotted for particle exit locations
        out_filename (str, optional):
            Full path to filname to save figure
        out_format (str, optional):
            Format to save figure (e.g., png or pdf)
        tolerance (float or str, optional):
            Maximum distance between date specified and closest available footprint
            Default is in nanosec if a float or in any units (e.g., '1H') if a string
        log_range (list, optional):
            list of min and max LOG10(footprints) for color scale
        colormap_fp (str, optional):
            Color map to use for contour plot of footprint
            (https://matplotlib.org/examples/color/colormaps_reference.html)
        colormap_part (str, optional):
            Color map to use for contour plot of particle location
            (https://matplotlib.org/examples/color/colormaps_reference.html)
        particle_clevs (list, optional):
            List of [min, max, interval] to plot the particle color levels
        dpi (int, optional):
            Resolution to save png

    Returns
        None

        If out_filename == None:
            produces as interactive plot
        Else:
            saves plot as specified by the full path in out_filename and format in out_format


    Animate footprints into a movie.

    Args:
        fp_data (dict):
            Dictionary of xarray datasets containing footprints and other variables
        output_directory (str):
            Full path to directory in which movie and images will be saved
        plot_function (str):
            Either 'plot' or 'plot_particle_location'. If plots are being generated
            (ffpmeg_only = False), call to this plotting function.
        file_label (str):
            File lavel of animation and and images of the frames
        video_os (str):
            Operating system to play video - must be either mac or pc
        time_regular (str):
            Frequency between minumum and maximum to set the time values within fp_data. (e.g., '1H')
            Set at False to not apply this step (Default = False).
        lon_range (list, optional):
            list of min and max longitudes [min, max] to plot
        lat_range (list, optional):
            list of min and max latitudes [min, max] to plot
        log_range (list, optional):
            list of min and max LOG10(footprints) for color scale
        plot_borders (bool, optional) :
            Plot country borders. Only applicable to plot_function="plot" Default = False.
        colormap_fp (str, optional):
            Color map to use for contour plot of footprint
            (https://matplotlib.org/examples/color/colormaps_reference.html)
        colormap_part (str, optional):
            Color map to use for contour plot of particle location
            (https://matplotlib.org/examples/color/colormaps_reference.html)
        zoom (bool, optional):
            True will plot a zoomed map (+/- 10 degrees around all site in fp_data)
            if plot_function is 'plot'
        particle_clevs (list, optional):
            List of [min, max, interval] to plot the particle color levels if
            plot_function is 'plot_particle_location'
        overwrite (bool, optional):
            True will overwrite any existing files
        framerate (int, optional):
            Framerate of animation in frames per second
        delete_png (bool. optional):
            True will delete the images of each frame
        ffmpeg_only (bool, optional):
            True will generate movie from pre-saved images in the output directory
            named with file_label
        frame_max (int, optional):
            Set the maximum number of frames in the datset to animate. Animation will plot first n
            frames up to the frame_max. Useful for testing.
        dpi (int, optional):
            Dots per square inch resolution for each image generate as for example png
        figsize (tuple, optional):
            Specify figure size in width, height in inches. e.g. (12,9)

    Returns
        None

        If out_filename == None:
            produces as interactive plot
        Else:
            saves plot as specified by the full path in out_filename and format in out_format


        The time_unique function creates one set of time entries within fp_data (dictionary of datasets)
        merging across multiple sites if necessary.
        Time can also be reindexed to be evenly spaced between the minimum and maximum values if time_regular
        if specified.

        Args:
            fp_data (dict)     :
                Output from footprints_data_merge(). Dictionary of datasets.
            time_regular (str) :
                Frequency between minumum and maximum to set the time values within fp_data.
                Set at False to not apply this step (Default = False).
        Returns:
            xarray.Dataset : Time values extracted for this first site within fp_data


    Setup for timeseries_HiTRes
    - Makes sure that the footprint and fluxes have the correct time resolution
    - Selects the required data from the fluxes to match the fp datetimes and those needed for H_back
    - Sets up the low frequency fluxes
    - Reformats the flux data as a numpy or dask array - using these is faster than xarray

    Args:
        flux_dict (dict)
            A dictionary of the form output in the format:
            flux_dict: {'high_freq': xarray.Dataset, 'low_freq': xarray.Dataset}.
            If there are multiple sectors, the format should be:
            flux_dict: {sector1 : {'high_freq' : flux_dataset, 'low_freq'  : flux_dataset},
                        sector2 : {'high_freq' : flux_dataset, 'low_freq'  : flux_dataset}}
        fp_HiTRes_ds (xarray.Dataset)
            Dataset of high time resolution footprints. HiTRes footprints record the footprint at
            each timestep back in time for a given amount of time
            (e.g. hourly time steps back in time for the first 24 hours).
        fp_file (str, optional)
            footprint filename
            not needed if fp_HiTRes_ds is given
        chunks (dict, optional)
            size of chunks for each dimension
            e.g. {'lat': 50, 'lon': 50}
            opens dataset with dask, such that it is opened 'lazily'
            and all of the data is not loaded into memory
            defaults to None - dataset is opened with out dask
        time_resolution (str, optional)
            required time resolution of timeseries
            defaults to '1H'
        verbose (bool, optional)
            show progress bar throughout loop

    Returns:
        flux, fp_HiTRes, time_array
            the reformatted fluxes, footprints, and time array as either
            numpy or dask arrays


    The timeseries_HiTRes function computes flux * HiTRes footprints.

    HiTRes footprints record the footprint at each 2 hour period back in time for the first 24 hours.
    A high time resolution flux is used to multiply the first 24 hours back of footprints, high
    frequency flux can be estimated by resampling low frequency data if required

    A residual flux is used to multiply the residual integrated footprint for the remainder of the 30
    day period, the residual can be calculated from the high frequency flux.

    Args:
        flux_dict (dict)
            A dictionary of the form output in the format:
            flux_dict: {'high_freq': xarray.Dataset, 'low_freq': xarray.Dataset}.
            If there are multiple sectors, the format should be:
            flux_dict: {sector1 : {'high_freq' : flux_dataset, 'low_freq'  : flux_dataset},
                        sector2 : {'high_freq' : flux_dataset, 'low_freq'  : flux_dataset}}
        fp_HiTRes_ds (xarray.Dataset)
            Dataset of high time resolution footprints. HiTRes footprints record the footprint at
            each timestep back in time for a given amount of time
            (e.g. hourly time steps back in time for the first 24 hours).
        fp_file (str, optional)
            footprint filename
            not needed if fp_HiTRes_ds is given
        output_TS (bool, optional)
            Output the timeseries. Default is True.
        output_fpXflux (bool, optional)
            Output the sensitivity map. Default is True.
        output_type (str, optional)
            object type to be returned
            default is Dataset which returns an xarray.Dataset
        output_file (str, optional)
            filename to save data to
            data is not saved by default
        verbose (bool, optional)
            show progress bar throughout loop
        chunks (dict, optional)
            size of chunks for each dimension
            e.g. {'lat': 50, 'lon': 50}
            opens dataset with dask, such that it is opened 'lazily'
            and all of the data is not loaded into memory
            defaults to None - dataset is opened with out dask
        time_resolution (str, optional)
            required time resolution of timeseries
            defaults to '1H'

    Returns:
        xarray.Dataset, xarray.DataArray or dict
            Same format as flux_dict['high_freq']:
                If flux_dict['high_freq'] is an xarrayobject then an xarray object is returned
                (either DataArray or Dataset, as specified by output_type)
                If flux_dict['high_freq'] is a dict of xarray objects then a dict of xarray objects
                is returned (an xarray.Dataset or xarray.DataArray for each sector)

            If output_TS is True:
                Outputs a mol fraction timeseries, i.e. latlon sum of footprint * flux
            If output_fpXflux is True:
                Outputs a sensitivity map, i.e. footprint * flux


    Updates the time of release in the HiTRes output files to be start and end
    of the release at that timestep rather than the start and end of the release
    for the first timestep of that day.

    fname: path to file to be updated


    domain: string - 'EUROPE'
    site: string - 'MHD'
    height: string in magl - '10'
    year: string - '2014'
    month: string - '06'
    user_max_hour_back: int - 24
    base_dir: string, directory where [domain]_[site]_[height]magl folder is containing HiTRes footprints
    HiTRes_fields_folder: string, name of HiTRes fields folder - '24HrBk_Fields_files'
    met_folder: string, name of met folder - 'Met'
    force_met_empty: Boolean. Default is True. At this stage met data is not needed for HiTRes footprint processing.
    Met data available in the month integrated footprint files.
    normal_fp_dir: string - where the month integrated footprints are located


    Load an ASCII format grid of emissions from file

    Parameters
    ----------
    filename : Name of ascii grid to read in

    Returns
    -------
    output : xarray Dataset containing the data read from the file


    Parameters
    ----------
    naei_dir : str
        Directory containing unzupped naei .asc files
    species : str
        species as given in naei filenames
    year : str
        Two digit year (such as 17 for 2017)
    sector : str
        Sector name as given in naei filenames
    lon_out : array like
        longitude values for the output grid
    lat_out : array like
        latitude values for the output grid
    output_path : str, optional
        The filename to write the dataset to. The default is None, which does not output to a file

    Returns
    -------
    output : xarray dataset
        Regridded emissions data


    Processes UKGHG .nc files to resolution provided by lon_out and lat_out.
    Adds timestamp, author and raw file info to the output dataset.

    Args:
        ukghg_dir (str):
            Directory containing ukghg LonLat .nc files at 0.01 km resolution
        species (str):
            Species as given in ukghg filenames
        year (str):
            Year to use (e.g."2015")
        sector (str):
            Sector name as given in ukghg filenames.
            Options: "agric","domcom","energyprod",'"indcom","indproc","natural",
                     "offshore","othertrans","roadtrans","solvents","total",'waste"
        lon_out (array):
            Longitude values for the output grid
        lat_out (array):
            Latitude values for the output grid
        output_path (str), optional:
            Filepath to write output dataset to. Default is None, which does not save output.

    Returns:
        ukghg_ds (xarray dataset):
            Regridded emissions data


    Embed a country/regional flux field into a domain/larger region flux field
    The dimensions of the fields should match

    If a domain or country_file are given then a country mask is used

    Args:
        domain_field, country_field (xarray DataArray)
            domain (large region) and country (regional) flux fields to be merged
            country_field will be embedded into domain_field
        country (str, optional)
            name of the country associated with the country_field in the country_file
            if not given, then a country mask will not be used
        domain (str, optional)
            domain associated with the domain_field
            used to look up a country mask file if country_file is None
        country_file (str, optional)
            country mask filename
            if neither this or domain is given then all fluxes within the
            country flux field are embedded into the domain field
        data_type (str, optional)
            data type to return (case insensitive)
            either np_array, xr_dataset, or xr_array, defaults to xr_array
        crop (dict, optional)
            lat and lon to crop data to
            {'lat': [lat_1, lat_2], 'lon': [lon_1, lon_2]}
        var_name (str, optional)
            the variable name if saving to xarray.Dataset
            defaults to 'flux'
        global_attrs (dict, optional)
            global attributes to apply to the Dataset
            only used if data_type is xr_dataset
        verbose (bool, optional)
            print update statements

    Returns:
        xarray DataArray, xarray Dataset, or numpy array
            map with the country flux field embedded into the domain flux field


    The _JULESfile function opens the correct JULES wetland file for the given
    year (int) as an xarray.Dataset object.


    The _SWAMPSfile function opens the correct SWAMPS wetland fraction file as an
    xarray.Dataset object.

    Args:
        product (str, optional) :
            Which SWAMPS product to use
            Options:
                "inland_cap" : Inland water fraction added and capped at 1.0
                "inland_norm" : Inland water fraction added and renormalised to 1.0
                "org" : Use original product without inland water


    The _readJULESwetland function reads and interprets the JULES wetland maps for the
    specified year.

    Note: converts input "month" dimension into "time" co-ordinates containing datetime objects.

    Args:
        year (int) :
            Year of interest.
        species (str, optional) :
            Species of interest. At the moment this should just be "CH4"
            Default = "CH4".

    Returns:
        xarray.Dataset :
            Dataset of JULES flux in expected format.


    The _wetlandArea function calculates the area of the wetland extent within the specified
    latitude and longitude grid and the fraction of the total global wetlands area.

    Args:
        frac (np.array) :
            nlat x nlon array of fractional wetland extent.
        lat_in, lon_in (np.array, np.array) :
            Latitude and longitude grid of input fractional extent
        lat_out, lon_out (np.array, np.array)
            Output Latitude and longitude grid

    Returns:
        tuple (float,float) :
            wetland area in m2 within specified latitude and longitude output grid,
            fraction of global wetland area.


    The _SWAMPSwetlandArea function calculates the area of the wetland extent
    within a grid and the fraction of the total global wetlands area based on
    wetlands fraction input for SWAMPS across a global grid.

    Args:
        year (int) :
            Year of interest.
        lat_out (numpy.array) :
            Latitude grid.
        lon_out (numpy.array) :
            Longitude grid.
        month (int, optional) :
            Month to extract this area for. Should be between 1 and 12.
            Default = 1 (i.e. January)
        product (str, optional) :
            Which SWAMPS product to use (see _SWAMPSfile() for options)

    Returns:
        tuple (float,float) :
            wetland area in m2 within specified latitude and longitude grid,
            fraction of global wetland area.


    The scale_emissions function scales emissions values for one time grid to a
    total_emission value.

    Args:
        emissions_t (numpy.array) :
            Emissions values for one time point. Expect array to have dimensions nlat x nlon
            Assumes emissions are in units of mol/m2/s
        species (str) :
            Species of interest. Used to extract molar mass. e.g. "CH4"
        lat (numpy.array) :
            Latitude grid for emissions.
        lon (numpy.array) :
            Longitude grid for emissions.
        total_emission (float) :
            Total emissions of the output array.
            Value should be specified in g/yr e.g. 185Tg/yr should be 185e12.
        return_scaliing (bool, optional) :
            Return the scaling factor associated with updating the emissions field.
            Default = False

    Returns:
        numpy.array :
            Scaled emissions array (nlat x nlon x nt)


    The scale_emissions_all function scales emissions values within all time grids to the same
    total_emission value.

    Args:
        emissions (numpy.array) :
            Emissions values across multiple times. Expects array to have dimensions nlat x nlon x nt
        species (str) :
            Species of interest. Used to extract molar mass. e.g. "CH4"
        lat (numpy.array) :
            Latitude grid for emissions.
        lon (numpy.array) :
            Longitude grid for emissions.
        total_emission (float) :
            Total emissions of the output array.
            Value should be specified in g/yr e.g. 185Tg/yr should be 185e12.
        return_scaliing (bool, optional) :
            Return the scaling factor associated with updating the emissions field.
            Default = False

    Returns:
        numpy.array :
            Scaled emissions array (nlat x nlon x nt)


    The plot_emissions function plots emissions values as a contour plot on a map specified by the
    latitude and longitude extent.

    Args:
        emissions_t (numpy.array) :
            Emissions values for one time point. Expect array to have dimensions nlat x nlon
        lat (numpy.array) :
            Latitude extent of emissions in degrees. Can be just lower and upper bounds or whole
            array of latitude values.
        lon (numpy.array) :
            Longitude extent of emissions in degrees. Can be just lower and upper bounds or whole
            array of longitude values.
        fignum (int, optional) :
            Figure number for plot.
            Default = None
        cmap (str, optional) :
            Colour map to use for plotting. See matplotlib.org/users/colormaps.html for some options.
            Default = "inferno_r"
        show (bool, optional) :
            Whether to immediately flush the buffer and produce the plot.
            Default = True

    Returns:
        cartopy axis object:
            Axis object for plot so far

        If show is True:
            Plots emissions countour map.


    The _define_time function creates an array of datetimes across a year based on the
    options provided.

    The following options and combinations can be specified:
        timeframe - description of timeframe e.g. "yearly"
        periods - number of time periods within a year
        periods & timeframe - number of time periods for that timeframe
        months - specific months within the year
        months & timeframe - specific months over that timeframe

    Args:
        year (int) :
            Year of interest.
        timeframe (str, optional) :
            Timeframe to output.
            Options are: "yearly", "monthly", "daily" or "3hourly"
        periods (int, optional) :
            Number of periods within a year to include.
            If no timeframe is specified, expected periods are based on being split
            evenly across a year based on the 4 possible timeframes listed above.
        months (list, optional) :
            Specific months to include within the year. Should be numbers between 1-12.

    Returns:
        np.array :
            Array of datetime objects


    The _define_prior_dict function creates a dictionary of details for the specified priors.
    This can be passed to the flux.write() function to include prior details within the emissions
    file attributes.

    Args:
        databases (list) :
            List of database names. Full listed of accepted names within create_emissions() function.

    Returns:
        dict (list) :
            Contains a three-item list of [version,resolution,reference] for each database.


    Defines emissions database options and associated functions.
    Set print_options=True to print out the available databases to use (and which functions
    they are associated with).

    Returns:
        (dict, dict, dict, dict, list):
            - Dictionary of database names and associated functions. Note: can include nested dictionaries if more than one function can be used for a database e.g. EDGAR.
            - Dictionary of species for each database.
            - Dictionary of any timeframes for each database.
            - Dictionary of sector for each database.
            - List of databases which contain climatological values rather than specific years.


    The create_emissions function can create a combined emissions file based on the list of databases
    provided and options specified.

    See individual functions for more details on databases and inputs.

    Either a domain or longitude and latitude grid values must be specified.

    Note: For "EDGARv5.0" and "EDGARv4.3.2", three databases are available based on annual data,
    annual sector data and monthly sector data (for EDGARv4.3.2 (2010) only, there is currently no
    monthly sector data downloaded for EDGARv5.0). If "EDGARv5.0" or "EDGARv4.3.2" database is
    used, this function will assume annual data is wanted unless specified otherwise by using an
    explicit database (e.g."EDGARv5.0_yearly", see database options) or by using the edgar_keyword
    argument.

    WARNING: At the moment this function is unable to interpret "months" as an input (included
    as part of the keyword arguments) and so this input will be ignored if specified.
    This would be applicable to "GFED" and "EDGAR_sector_monthly" databases.

    Args:
        databases (list) :
            List of databases to use to create emissions file.
            The following inputs can be included:
                - "GFED"                        - GFED v4.1 biomass burning database
                - "EDGARv5.0"                   - EDGAR v5.0 anthropogenic database
                - "EDGARv4.3.2"                 - EDGAR v4.3.2 anthropogenic database
                - "EDGARv5.0_yearly"            - explicitly use yearly EDGARv5.0 database
                - "EDGARv5.0_sector_yearly"     - explicitly use annual sector EDGARv5.0 database
                - "EDGARv4.3.2_yearly"          - explicitly use yearly EDGARv4.3.2 database
                - "EDGARv4.3.2_sector_yearly"   - explicitly use annual sector EDGARv4.3.2 database
                - "EDGARv4.3.2_sector_monthly"  - explicitly use monthly sector EDGARv4.3.2 database
                - "natural"                     - other natural CH4 emissions (volcanoes, termites, hydrates) from Fung et al 1987
                - "soilsink"                    - soil sink CH4 emissions from Bousquet et al 2006
                - "Bloom"                       - CH4 wetland emissions from Bloom et al
                - "Bloom2017"                   - CH4 wetland emissions for updated WetCHARTS map from Bloom et al 2017
                - "NAEI"                        - NAEI anthropogenic database
                - "NAEI_and_EDGAR"              - Combined dataset of NAEI and EDGAR
                - "JULES_wetlands"              - CH4 wetlands emissions from combining JULES model emissions output and SWAMPS wetlands extent.
                - "Scarpelli"                   - CH4 from fugitive fossil fuel emissions (NB this is not yet published)
            See database_options() function for full and correct list of options.
        species (str) :
            Species of interest. All listed databases must have data for this species.
        domain (str) :
            Name of domain e.g. "EUROPE","SOUTHAMERICA","NORTHAFRICA".
            See $DATA_PATH/LPDM/fp_NAME/* for all available domains.
            If lat_out and lon_out not specified, domain will be used to extract grid values.
        year (int) :
            Year of emissions to use.
            Unless all input databases are climatological, year must be specified.
        lon_out (list, optional) :
            Longitude grid for emissions output. Only needed if files for the domain
            have not already been created.
        lat_out (list, optional) :
            Latitude grid for emissions output. Only needed if files for the domain
            have not already been created.
        scale (float, optional) :
            Scale total emissions by some factor.
            By default scaling factor is 1.0, meaning no scaling is applied.
        write (bool, optional) :
            Write to netCDF file. Passes to flux.write() function to ensure correct format
            is applied.
            Default = True.
        output_directory (str, optional) :
            Base directory for output file. Domain name will be used as subdirectory name.
            Default = $DATA_PATH/LPDM/emissions/

        kwargs :
            Additional keyword arguments which can be taken by the underlying functions.
            See "get*" functions within this module for full list of arguments.

            timeframe :
                Can be one of "3hourly","daily","monthly". Optional for "GFED" and "Bloom" databases.
            edgar_keyword :
                Can be one of 'yearly', 'sector_yearly' or 'sector_monthly'. MUST be specified if
                annual sector data or monthly sector data is required for 'EDGARv5.0' or 'EDGARv4.3.2'
                databases.
            edgar_sectors :
                Specific sectors for EDGAR database. MUST be specified if "EDGARv5.0"
                or "EDGARv4.3.2" databases are used and 'sector_yearly' or 'sector_monthly'
                edgar_keywords are specified.
            naei_sector :
                Specific sector for NAEI database. MUST be specified if "NAEI" database is used.
            scarpelli_sector :
                Specific sector for Scarpelli inventory. MUST be specified if "Scarpelli" inventory is
                used.
            incagr :
                Include agricultural waste burning. Optional for "GFED" database.
            extent_db :
                Use a different extent database with the JULES emissions. Optional for "JULES_wetlands"
            scale_wetlands :
                Scale wetlands to match a fraction of a total emissions value. Optional for
                "JULES_wetlands"
            total_w_emission :
                Total wetland emissions to scale emissions map to. Only used if scale_wetlands=True.
                Optional for "JULES_wetlands"
            modeltype :
                Model type to use for WetCHARTS based on options available. One of 'extended' or 'full'.
                Optional for "Bloom2017"

    Returns:
        numpy.array (nlat x nlon x nt), numpy.array (nt):
            Array of combined emissions from all databases.
            Array of time values.

        If write is True, writes to netcdf file.
        Output file naming convention defined within flux.write (check for final format).


Creates basis regions for the "transdimensional inversion".
    Creates variable central block based on sub_lat and sub_lon domain
    and four fixed regions surrounding the central box.

    Args:
        domain (str):
            String of domain area
        time (str):
            Timestamp for basis functions
        basis_case (str, optional):
            Labelling for basis case.
            Default is "transd" for transdimensional
        sub_lon_min (float):
            Minimum longitude of sub domain
        sub_lon_max (float):
            Maximum longitude of sub domain
        sub_lat_min (float):
            Minimum latitude of sub domain
        sub_lat_max (float):
            Maximum latitude of sub domain

    Returns:
        None
        Writes basis regions to netcdf

    Example:
        basis_transd(domain = "SOUTHASIA", time = "2012-01-01", basis_case = "transd",
            sub_lon_min = 65, sub_lon_max = 100, sub_lat_min = 5, sub_lat_max = 40)


Creates uniform blocks for boundary conditions in each direction (NESW).
    Each direction is split into vertical slabs with number specified by input 'vertical'

    Args:
        domain (str):
            String of domain area
        basis_case (str):
            Labelling for basis case.
        time (str):
            Timestamp for basis functions
        vertical (int, optioanl):
            Number of vertical slabs to split boundary conditions into
            Default = 1

    Returns:
        None
        Writes basis boundary condition blocks to netcdf

    Example:
        basis_bc_blocks(domain='SOUTHASIA', basis_case='NESW', time='2012-01-01', vertical = 4)


Creates creates one uniform scaling for boundary conditions for all directions

    Args:
        domain (str):
            String of domain area
        basis_case (str):
            Labelling for basis case.
        time (str):
            Timestamp for basis functions

    Returns:
        None
        Writes uniform basis boundary condition to netcdf

    Example:
        basis_bc_uniform(domain='SOUTHASIA', basis_case='uniform', time='2012-01-01')


Creates five terms for bc basis regions
        (1) offset to shift entire field up and down
        (2) factor to scale the entire field
        (3) scaling of N-S gradient
        (4) scaling of E-W gradient
        (5) scaling of stratospheric gradient
        Technically file is species specific as it calculates the stratosphere
        based on the vmm but one can assume/hope that the stratosphere doesn't
        change by species

    Args:
        domain (str):
            String of domain area
        time (str):
            Timestamp for basis functions
        species (str):
            Species of interest
        units (str, optional):
            Units of boundary conditions. Default ppb
        basis_case (str, optional):
            Name of basis case.
            Default 'horiz-strat-grad'

    Returns:
        None
        Writes basis boundary condition gradients to netcdf

    Example:
        basis_bc_all_gradients('SOUTHASIA', '2012-01-01', 'ch4', units='ppb', basis_case='horiz-strat-grad')


Creates three terms for bc basis regions for each direction
        (1) offset to shift field up and down
        (2) scaling of N-S gradient on east and west curtains
        (3) scaling of E-W gradient on north and south curtains

    Args:
        domain (str):
            String of domain area
        time (str):
            Timestamp for basis functions
        basis_case (str, optional):
            Name of basis case.
            Default 'horiz-grad'

    Returns:
        None
        Writes basis boundary condition gradients to netcdf

    Example:
        basis_bc_all_gradients('SOUTHASIA', '2012-01-01')


breaks the MOZART VMR into the first 'numregions' principal components and scales each PC

    Args:
        domain (str):
            String of domain area
        time (str):
            Timestamp for basis functions
        species (str):
            Species of interest
        units (str, optional):
            Units of species. Default is 'ppb'
        basis_case (str):
            Labelling for basis case. Default is 'pca'
        numregions (int):
            Number of PCs

    Returns:
        None
        Writes PCA basis boundary condition to netcdf

    Example:
        basis_bc_pca("SOUTHASIA", "2012-01-15", 'ch4', units='ppb', basis_case='pca', numregions = 4)


    inputs:
        grid: 2d numpy array to apply quadtree division to
        limit: float to use as bucket level for defining maximum subdivision
    outputs:
        outputGrid: 2d numpy grid, same shape as grid, whose values indicate the box from boxList each index corresponds to
        boxList: list of lists, where each sublist describes the corners of a quadtree leaf


    Creates a basis function with nbasis grid cells using a quadtree algorithm.
    The domain is split with smaller grid cells for regions which contribute
    more to the a priori (above basline) mole fraction. This is based on the
    average footprint over the inversion period and the a priori emissions field.
    Output is a netcdf file saved to /Temp/<domain> in the current directory
    if no outputdir is specified or to outputdir if specified.
    The number of basis functions is optimised using dual annealing. Probably
    not the best or fastest method as there should only be one minima, but doesn't
    require the Jacobian or Hessian for optimisation.

    Args:
        emissions_name (dict):
            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.
        fp_all (dict):
            Output from footprints_data_merge() function. Dictionary of datasets.
        sites (list):
            List of site names (This could probably be found elsewhere)
        start_date (str):
            String of start date of inversion
        domain (str):
            The inversion domain
        species (str):
            Species of interest
        outputname (str):
            Identifier or run name
        outputdir (str, optional):
            Path to output directory where the basis function file will be saved.
            Basis function will automatically be saved in outputdir/DOMAIN
            Default of None makes a temp directory.
        nbasis (int):
            Number of basis functions that you want. This will optimise to
            closest value that fits with quadtree splitting algorithm,
            i.e. nbasis % 4 = 1.
        abs_flux (bool):
            If True this will take the absolute value of the flux

    Returns:
        If outputdir is None, then returns a Temp directory. The new basis function is saved in this Temp directory.
        If outputdir is not None, then does not return anything but saves the basis function in outputdir.


Write a flux file for emissions

    Args:
        lat (arr):
            1D array of latitudes
        lon (arr):
            1D array of longitudes
        time (numpy.datetime64):
            Either an array (format from xarray) or a datetime index (format from pandas).
            See 'Creating datetime64 data' : http://xarray.pydata.org/en/stable/time-series.html
            If making a 'climatology' then this can be passed any dates but must be of same length
            as time dimension of flux variable.
        flux (array):
            2D array of size [lat x lon x time]. Should be in mol/m2/s.
        species (str):
            Species of interest.
        domain (str):
            String of domain area
        source (str):
            Sources in file. E.g. 'ff' (fossil fuel), 'agriculture'.
            source = None if the file contains all sources of a species.
            If multiple sources: -source- is a chain of sources: 'waste-and-agriculture' (with hyphens between words).
        title (str):
            Gives more information about what is in the file, e.g. Fossil Fuel CO2.
        prior_info_dict (dict):
            {'NAME_OF_PRIOR' : ['VERSION','RAW RESOLUTION', 'REFERENCE']}
        regridder_used (str, optional):
            regrid function used. Default is 'acrg_grid.regrid.regrid_3D'.
        copy_from_year (str, optional):
            If the data is the same as another year but with a different timestamp give the original year here as a string
            Default is None
        climatology (bool, optional):
            If the data is a climatology set this to True and give detail using flux_comments.
            Default is False
        flux_comments (str, optional):
            Extra comments. Default is None.
        uncertainty (array, optional):
            Uncertainty in the flux
        uncertainty_desc (str, optional):
            Description to add to uncertainty attributes
            e.g. describing method of calculation
        output_directory (str, optional):
            Output directory. Default is 'data_path + LPDM/emissions/'.
        units (str, optional)
            Units of data, defaults to flux units of mol/m2/s
        overwrite (bool, optional)
            If True, automatically overwrite files with the same species, source, and year
            defaults to False - will ask for user input to overwrite file

    Returns:
        None
        Writes flux file to netcdf
        Naming convention of output file:
            The output filename depends on both whether a source is specified and if the output is
            for climatology.
            "species"-"source"_"domain"_"year".nc      (source specified, not climatology)
            "species"-climatology-"source"_"domain".nc (source specified, climatology)
            "species"-total_"domain"_"year".nc         (no source specified, not climatology)
            "species"-climatology-total_"domain".nc    (no source specified, climatology)
            e.g. co2-ff_EUROPE_2012.nc
            e.g. co2-climatology-ff_EUROPE.nc
            e.g. ch4-total_SOUTHAMERICA_2010.nc
            e.g. ch4-climatology-total_SOUTHAMERICA.nc

    Example:
        flux.write(lat, lon, time, flux, 'ch4', 'EUROPE', '2012',
          comments = comments, title="2012_CH4_emissions_EUROPE")

    Todo:
        Add some error checking (e.g. check that domain is correct)


    Unzip .gz files

    Args:
        filename (str)
            name of file to be unzipped, including path to file
        out_filename (str)
            filename for unzipped file
            if None, the original filename is used
        delete_zipped_file (bool)
            if True the zipped file will be deleted and be replaced with the unzipped version
            if False both the original and gzipped file will remain


    Determine whether file is zipped or not, and then extract text into
    file_lines variable.

    Args:
        fname (str):
            file name to extract text from

    Returns:
        file_lines (str array):
            lines of text extracted from fname

    Example:
        fname = 'sometextfile.txt'
        file_lines = extract_file_lines(fname)


    Define output grid using file header information.

    Note: header, column_headings can be extracted using read_file() function and passed to this function.

    Args:
        header (list):
            header information
        column_headings (list):
            headings for columns
        satellite (bool, optional):
            If using satellites then True. Default = False.
            For satellite instructions, see help(process.satellite_vertical_profile).
        upper_level (int, optional):
            Only needed when satellite=True.
            Highest level number from within the NAME run for the satellite data.
            Default = None.

    Returns:
        lons (np.array):
            NAME grid longitudes
        lats (np.array):
            NAME grid latitudes
        levs (list):
            Levels of NAME grid
        time (list):
            Time step label at start of each time period
        timeStep (float):
            Timestep in hours

    Example:
        lons, lats, levs, time, timeStep = define_grid(header, column_headings, satellite = False)
        lons, lats, levs, time, timeStep = define_grid(header, column_headings, satellite = True, upper_level = 17)

    Note:
        Largely taken from Met Office Python code.


Create an empty Met dictionary. Not recommended.


    Given list of filenames, extract site meteorology and concatenate into Pandas dataframe.

    Args:
        fnames (list):
            List of filenames for met data.
        met_def_dict (dict, optional):
            Dictionary of met parameters.
            Default=None, which takes default entries.
        vertical_profile (bool, optional):
            TODO. Default=False
        satellite (bool, optional):
            If using satellites then True. Default = False.

    Returns:
        output_df (pandas.Dataframe):
            Dataframe of met data.

    Example:
        df = read_met(fnames, met_def_dict=None, vertical_profile=False)

    Note:
        A dictionary of output column names and met file header search strings
        is given in the met_default dictionary at the top of process.py.
        Vertical profile assumes a file structure that consists of a time column
        14 temperature (C) columns, followed by 14 pressure (Pa), and 14 potential
        temperature (K)


    Splits the met input into points for satellite data if the data has been grouped into all levels and points
    for one day.

    Looks for an additional column in the met dataframe called "label" which contains the label
    associated with the input point. For data which has been grouped by day the label values should in
    the format "PPPLL" e.g. '00507' which translates to Point 005, Level 07.
    If this format or column is not found then the met input will be returned unchanged.

    Args:
        met (pandas.DataFrame/list) :
            Output from read_met function. Expects a Dataframe but can also handle a list
            containing one dataframe.

    returns:
        list(pandas.DataFrame):
            Met data split out into separate points each one containing all the associated levels.


    Read and process a particle location file.

    Note: lons, lats, levs, time can be derived from corresponding fields files using define_grid() function
    and passed to this function.

    Args:
        particle_file (str):
            File of file containing particle locations
        time (list):
            List of timestamps for NAME run
        lats (np.array):
            Array of latitudes of domain for NAME run
        lons (np.array):
            Array of longitudes of domain for NAME run
        levs (list):
            List of levels within input data for NAME run
        heights (np.array/list):
            TODO: Needs better explanation here.
            Particle location heights
        id_is_lev (bool, optional):
            Indicate that the input "Id" value from the particle files relates to the level rather than the
            timestamp.
            Default = False.
        satellite (bool, optional):
            Used for satellite data. This flag is used to know how to process the "Id" value to link to time values
            and levels. Expect all time points have the same number of levels corresponding to upper_level value.
            Default = False.
        upper_level (int):
            Needed if satllite=True. Used to separate out the input "Id" values to link to both time and level
            values.

    Returns:
        hist (xarray.Dataset):
            Number of particles at each boundary.
            Contains "pl_n","pl_e","pl_s""pl_w" data variables.
            Dimensions are "time", "lev", "lon", "height"


        The particle_location_edges function calculates the histogram along with the x and y edge values
        for input xvalues, yvalues.


        The mean_age_edges function calculates the mean age of particles along with the x and y edge values
        for input xvalues, yvalues.


    Convert text output from given files into arrays in an xarray.Dataset.

    Args:
        fields_file (str):
            Filename of footprint text file.
        particle_file (str, optional):
            File containing particle locations.
            Default = None.
        met (dict):
            Dictionary of Met data.
            Output from read_met() function.
            Default = None.
        satellite (bool, optional):
            If using satellites then True. Default = False.
            For satellite instructions, see help(process.satellite_vertical_profile).
        time_step (float, optional):
            Timestep of footprint.
            Needed if timestep cannot be extracted from input fields file.
            Default = None
        upper_level (int, optional):
            Only needed when satellite=True. Highest level number from within the NAME run for the satellite data.
            Default = None.
        obs_file (str, optional):
            Optional for satellite=True; not used otherwise. Files containing observation data (.nc file).
            Time values cannot always be accurately determined from the input fields file. If obs_file is
            specified, time values will be extracted from these files.
            Default = None.
        use_surface_conditions (bool, optional) :
            Use default expected surface conditions for meteorological values
            if converting from gs/m3 to mol/mol / mol/m2/s units.
            P/T ratio is fixed as 345 based on typical surface conditions.
            Default = True.
        species (str,optional):
            Defaults to None which will process footprints for an inert species
            Otherwise will look in json file for lifetime and process a species-
            specific footprint
        user_max_hour_back (float, required when species = 'CO2'):
            Defaults to 24 hours. This is the maximum amount of time back from release time that
            hourly footprints are calculated.
        lifetime_hrs (float, optional):
            Defaults to None which will process footprints for an inert species.
            Otherwise will process it for the specified loss timescale.

    Returns:
        fp (xarray.Dataset):
            Dataset of footprint data.


        Conversion is based on inputs units

        If units are 'ppm s':
            Convert from [ppm s] (i.e. mu-mol/mol) units to [(mol/mol) / (mol/m2/s)].

            Using conversion:
                sensitivity [mu-mol/mol s] * area [m2] * molar mass [g/mol] * 1e-6 [mu]
                    / (time [s] * release rate [g/s])

        If units are 'g s / m^3' (or 'gs/m3'):
            Convert from [g s/m3] units to [(mol/mol) / (mol/m2/s)].

            Using conversion:
                sensitivity [g s/m3] * area [m2] * RT/P [m3/mol]
                / (time [s] * release rate [g/s])

        Note:
            release rate is assumed to be 1. [g/s]
            molecular weight in the NAME run itself was set to 1.0, so molar mass will
            be 1.0 in this calculation as well.

        Optional args:
            use_surface_conditions (bool, optional) :
                If the input units are 'gs/m3', use representation surface P/T ratio of 345 rather
                than using the input meteorological data.
                Default = True


        Conversion is based on inputs units
        Input: an xarray dataset with uncoverted HiTRes footprints.
        The following dimensions of the fp_HiTRes is expected: [time, lev, lat, lon, H_back]

        For each slice dictionary,

        If units are 'ppm s':
            Convert from [ppm s] (i.e. mu-mol/mol) units to [(mol/mol) / (mol/m2/s)].

            Using conversion:
                sensitivity [mu-mol/mol s] * area [m2] * molar mass [g/mol] * 1e-6 [mu]
                    / (time [s] * release rate [g/s])

        If units are 'g s / m^3' (or 'gs/m3'):
            Convert from [g s/m3] units to [(mol/mol) / (mol/m2/s)].

            Using conversion:
                sensitivity [g s/m3] * area [m2] * RT/P [m3/mol]
                / (time [s] * release rate [g/s])

        Note:
            release rate is assumed to be 1. [g/s]
            molecular weight in the NAME run itself was set to 1.0, so molar mass will
            be 1.0 in this calculation as well.

        Optional args:
            use_surface_conditions (bool, optional) :
                If the input units are 'gs/m3', use representation surface P/T ratio of 345 rather
                than using the input meteorological data.
                Default = True


Given file search string, finds all fields and particle
    files, reads them and concatenates the output arrays.

    Args:
        fields_prefix (str):
            prefix for fields file search string.
        particle_prefix (str, optional):
            prefix for particle file search string.
            Default = None
        datestr (str, optional):
            Date for particle and fields files. Default = '*'
        met (dict, optional):
            Dictionary of met data. Default = None (empty)
        satellite (bool, optional):
            Is it for satellite data? Default = False
        time_step (float, optional):
            Timestep of footprint. Default = None
        upper_level (int):
            Only needed when satellite=True. Highest level number from within the NAME run for the satellite data.
            Default = None.
        use_surface_conditions (bool, optional) :
            Use default expected surface conditions for meteorological values
            if converting from gs/m3 to mol/mol / mol/m2/s units.
            P/T ratio is fixed as 345 based on typical surface conditions.
            Default = True.
        species (str,optional):
            Defaults to None which will process footprints for an inert species
            Otherwise will look in json file for lifetime and process a species-
            specific footprint
        user_max_hour_back (float, optional):
            Defaults to 24 hours. This will calculate high-time res footprints back to the
            number of hours specied here.
        lifetime_hrs (float, optional):
            Defaults to None which will process footprints for an inert species.
            Otherwise will process it for the specified loss timescale.
        unzip (bool)
            If True, unzip .nc.gz field files, defaults to False

    Returns:
        fp (xarray dataset):
            Concatenated array of all field and particle files

    Example:
        fp_dataset = footprint_concatenate("/dagage2/agage/metoffice/NAME_output/MY_FOOTPRINTS_FOLDER/Fields_Files/filename_prefix")


Writes netCDF with footprints, particle locations, meteorology and release locations.

    Args:
        fp (xarray dataset):
            Array of all footprint and particle fields in (mol/mol)/(mol/m2/s)
        lons (array):
            1D array of longitudes
        lats (array):
            1D array of latitudes
        levs (???array or list):
            TODO: Clarify inputs
            1D array of particle levels
        time (???str or datetime object):
            TODO: Clarify inputs
            Timestamps for footprints
        outfile (str):
            Name of output file
        temperature (array, optional):
            Input temperature variable in C. Default=None
        pressure (array, optional):
            Input pressure variable in hPa. Default = None
        wind_speed (array, optional):
            Input wind speed variable in m/s. Default = None
        wind_direction (array, optional):
            Input wind direction variable in degrees.
            Default = None
        PBLH (array, optional):
            Input planetary boundary layer height in m.
            Default = None
        fp_HiTRes_inc (str, optional):
            True if writing out fp_HiTRes
        varname (str, optional):
            Name of output footprint variable. Default = 'fp'
        release_lon (array, optional):
            Array of release longitude locations.
            Default = None
        release_lat (array, optional):
            Array of release latitude locations.
            Default = None
        particle_locations (xarray dataset, optional):
            Number of particles at locations at each boundary
            Default=None
        particle_heights (array, optional):
            Heights of particles leaving boundary.
            Default=None
        global_attributes (dictionary, optional):
            Dictionary of global attributes.
            Default={} (empty)
        lapse_rate (array, optional):
            Potential temperature gradient from 60 - 300 m in K/km.
            Default=None
        lapse_error (array, optional):
            Error in potential temperature gradient in K/km

    Returns:
        None.
        Writes netCDF with footprints, particle locations, meteorology and release locations

    Note:
        netCDF4 is required, as we make use of compression.


Do weighted average by satellite averaging kernel and
    pressure weight. One time point only. Expects xray.dataset
    with one time point and N vertical levels.

    Args:
        fp (xarray dataset):
            footprint for ONE time point. N levels in lev dimension with
            footprints and particle locations defined at each level
        satellite_obs_file (str):
            Filename of NetCDF-format satellite observation file.
            One per time step.
        max_level (int):
            Maximum vertical level of the retrieval that is included.
            (maximum for GOSAT to include all levels from model is 20).
            The remaining levels are set equal to the a priori value.

    Returns:
        fp (dictionary):
            Footprint for column totals of satellite observations.

    Note:
        Requirements for running processing satellite footprints

        - General file naming:
            Files/folders need to have a date string of the form
            YYYYMMDD-II at the end of the file/folder name,
            where II is a two-digit index corresponding to the
            sequence of footprints throughout the day. This modifies the usual
            naming convention for surface sites, which are only YYYYMMDD.
        - Met:
            The Met/ folder MUST contain a set of subfolders which are labeled
            with the YYYYMMDD-II time stamp. Each of these subfolders should then
            contain nLev Met output files, where nLev are the number of vertical
            levels in the NAME output. This is required so that we know
            what pressure/temperature each NAME footprint for each vertical level
            corresponds to. The files can be named in any way, but the file names
            must be in ascending order when sorted (i.e. blah_01.txt.gz, blah_02.txt.gz).
        - Fields files:
            There must be ONE fields file per time stamp, labeled at the end
            of the file string with YYYYMMDD-II (e.g. blah_YYYYMMDD-II.txt.gz).
            The fields file must contain exactly nLev columns, one for each vertical
            level, in ascending order, left to right.
        - Particle location files:
            There must be ONE fields file per time stamp, labeled at the end
            of the file string with YYYYMMDD-II (e.g. blah_YYYYMMDD-II.txt.gz).
            The ID column in this file must contain nLev values in ascending order
            specifying the vertical level that each particle belongs to.


Write a log of an error or a warning to file. Will append to a file

    Args:
        message(str):
            Error message
        directory (str, optional):
            Directory of error log. Default = None
        error_or_warning (str):
            Message type. Default = "status"
        print_to_screen (bool):
            Print to screen? Default=True

    Returns:
        None.
        Writes error to file

    Example:
        status_log("Everything has gone wrong")


Basic processing with no meteorology or particle files
    NOT recommended, but helpful for a quick check

    Args:
        field_folder (str):
            folder containing fields data
        outfile (str):
            Name of outfile

    Returns:
        None.
        Writes outfile.