Reads the entire contents of the log file into a list of dictionaries


Dump all the added records to a file on disk


Return true if we should compute this algorithm


Detect water using multiple MODIS algorithms and compare to the permanent water mask


Compiles a single csv file comparing algorithm results across lakes


Compute the mean and std of a list of precision/recall value pairs


Archives completed flood detection results.
       Call updateArchiveFolder once all individual results are archived.


Does the final updates needed at the top level storage folder.


Create a single KML file in the top folder that includes
       network links to all of the other folders.


Fetches the list of dates we have archived data for.


Convert abbreviated month name to integer


Get a list of flood locations from GDACS.
       Dates are in the format YYYY-MM-DD


Perform another step of the active contour algorithm


Update the algorithm on space, quit on "q"


Run flood detection using the available sensors


Reduces the number of vertices in a polygon without changing the area more than maxError.
       The height is used to insert an elevation for each 2D coordinate.


Just clean up a coordinate list so it can be passed to simplekml


Add a polygon to a simplekml object


Adds a set of features to a KML object


Parses the description line of the output KML into a dictionary


Generate the description line for the KML file containing flood information


Converts a local coordinate list to KML


Takes the ID information from the input dict and adds full, ready-
    to-use Earth Engine image IDs to the dict.


Calls the water and cloud detection algorithms on an image and packages the results


Read in an output file generated by this program


Computes lake statistics over a date range and writes them to a log file


Simple alternative to html template rendering software


Fetches the list of available dates


Extract the information encoded in the KML filename into a dictionary.


Read the description field from the kml file


Expand the abbreviated sensor list to full sensor names


Add an object to the parse tree.


Pops the tag stack up to and including the most recent
        instance of the given tag. If inclusivePop is false, pops the tag
        stack up to but *not* including the most recent instqance of
        the given tag.


Push a start tag on to the stack.

        If this method returns None, the tag was rejected by the
        SoupStrainer. You should proceed as if the tag had not occurred
        in the document. For instance, if this was a self-closing tag,
        don't call handle_endtag.


Returns a string or Unicode representation of this document.
        To get Unicode, pass None for encoding.


Used with a regular expression to substitute the
        appropriate XML entity for an XML special character.


Make a value into a quoted XML attribute, possibly escaping it.

         Most strings will be quoted using double quotes.

          Bob's Bar -> "Bob's Bar"

         If a string contains double quotes, it will be quoted using
         single quotes.

          Welcome to "my bar" -> 'Welcome to "my bar"'

         If a string contains both single and double quotes, the
         double quotes will be escaped, and the string will be quoted
         using double quotes.

          Welcome to "Bob's Bar" -> "Welcome to "Bob's bar"


Substitute XML entities for special XML characters.

        :param value: A string to be substituted. The less-than sign
          will become <, the greater-than sign will become >,
          and any ampersands will become &. If you want ampersands
          that appear to be part of an entity definition to be left
          alone, use substitute_xml_containing_entities() instead.

        :param make_quoted_attribute: If True, then the string will be
         quoted, as befits an attribute value.


Substitute XML entities for special XML characters.

        :param value: A string to be substituted. The less-than sign will
          become <, the greater-than sign will become >, and any
          ampersands that are not part of an entity definition will
          become &.

        :param make_quoted_attribute: If True, then the string will be
         quoted, as befits an attribute value.


Replace certain Unicode characters with named HTML entities.

        This differs from data.encode(encoding, 'xmlcharrefreplace')
        in that the goal is to make the result more readable (to those
        with ASCII displays) rather than to recover from
        errors. There's absolutely nothing wrong with a UTF-8 string
        containing a LATIN SMALL LETTER E WITH ACUTE, but replacing that
        character with "é" will make it more readable to some
        people.


Yield a number of encodings that might work for this markup.


If a byte-order mark is present, strip it and return the encoding it implies.


Given a document, tries to find its declared encoding.

        An XML encoding is declared at the beginning of the document.

        An HTML encoding is declared in a <meta> tag, hopefully near the
        beginning of the document.


Changes a MS smart quote character to an XML or HTML
        entity, or an ASCII character.


Fix characters from one encoding embedded in some other encoding.

        Currently the only situation supported is Windows-1252 (or its
        subset ISO-8859-1), embedded in UTF-8.

        The input must be a bytestring. If you've already converted
        the document to Unicode, you're too late.

        The output is a bytestring in which `embedded_encoding`
        characters have been converted to their `main_encoding`
        equivalents.


Alias one attribute name to another for backward compatibility


Format the given string using the given formatter.


Is this element part of an XML tree or an HTML tree?

        This is used when mapping a formatter name ("minimal") to an
        appropriate function (one that performs entity-substitution on
        the contents of <script> and <style> tags, or not). It's
        inefficient, but it should be called very rarely.


Look up a formatter function based on its name and the tree.


Destructively rips this element out of the tree.


Finds the last element beneath this object to be parsed.


Makes the given element the immediate predecessor of this one.

        The two elements will have the same parent, and the given element
        will be immediately before this one.


Makes the given element the immediate successor of this one.

        The two elements will have the same parent, and the given element
        will be immediately after this one.


Returns all items that match the given criteria and appear
        after this Tag in the document.


Returns the closest sibling to this Tag that matches the
        given criteria and appears after this Tag in the document.


Returns the siblings of this Tag that match the given
        criteria and appear after this Tag in the document.


Returns the first item that matches the given criteria and
        appears before this Tag in the document.


Returns all items that match the given criteria and appear
        before this Tag in the document.


Returns the closest sibling to this Tag that matches the
        given criteria and appears before this Tag in the document.


Returns the siblings of this Tag that match the given
        criteria and appear before this Tag in the document.


Returns the closest parent of this Tag that matches the given
        criteria.


Returns the parents of this Tag that match the given
        criteria.


Iterates over a generator looking for things that match.


Force an attribute value into a string representation.

        A multi-valued attribute will be converted into a
        space-separated string.


Create a function that performs a CSS selector operation.

        Takes an operator, attribute and optional value. Returns a
        function that will return True for elements that match that
        combination.


CData strings are passed into the formatter.
        But the return value is ignored.


Is this tag an empty-element tag? (aka a self-closing tag)

        A tag that has contents is never an empty-element tag.

        A tag that has no contents may or may not be an empty-element
        tag. It depends on the builder used to create the tag. If the
        builder has a designated list of empty-element tags, then only
        a tag whose name shows up in that list is considered an
        empty-element tag.

        If the builder has no designated list of empty-element tags,
        then any tag with no contents is an empty-element tag.


Convenience property to get the single string within this tag.

        :Return: If this tag has a single string child, return value
         is that string. If this tag has no children, or more than one
         child, return value is None. If this tag has one child tag,
         return value is the 'string' attribute of the child tag,
         recursively.


Yield all strings of certain classes, possibly stripping them.

        By default, yields only NavigableString and CData objects. So
        no comments, processing instructions, etc.


Recursively destroys the contents of this tree.


Extract all children. If decompose is True, decompose instead.


        Find the index of a child by identity, not value. Avoids issues with
        tag.contents.index(element) getting the index of equal elements.


Returns a Unicode representation of this tag and its contents.

        :param eventual_encoding: The tag is destined to be
           encoded into this encoding. This method is _not_
           responsible for performing that encoding. This information
           is passed in so that it can be substituted in if the
           document contains a <META> tag that mentions the document's
           encoding.


Renders the contents of this tag as a Unicode string.

        :param indent_level: Each line of the rendering will be
           indented this many spaces.

        :param eventual_encoding: The tag is destined to be
           encoded into this encoding. This method is _not_
           responsible for performing that encoding. This information
           is passed in so that it can be substituted in if the
           document contains a <META> tag that mentions the document's
           encoding.

        :param formatter: The output formatter responsible for converting
           entities to Unicode characters.


Renders the contents of this tag as a bytestring.

        :param indent_level: Each line of the rendering will be
           indented this many spaces.

        :param eventual_encoding: The bytestring will be in this encoding.

        :param formatter: The output formatter responsible for converting
           entities to Unicode characters.


Return only the first child of this Tag matching the given
        criteria.


Extracts a list of Tag objects that match the given
        criteria.  You can specify the name of the Tag and any
        attributes you want the Tag to have.

        The value of a key-value pair in the 'attrs' map can be a
        string, a list of strings, a regular expression object, or a
        callable that takes a string and returns whether or not the
        string matches for some custom definition of 'matches'. The
        same is true of the tag name.


Perform a CSS selection operation on the current element.


This was kind of misleading because has_key() (attributes)
        was different from __in__ (contents). has_key() is gone in
        Python 3, anyway.


Turn an HTML fragment into a document.

        The details depend on the builder.


Ensure that next_element and previous_element are properly
        set for all descendants of the given element.


Assert that a given doctype string is handled correctly.


Generate and parse a document with the given doctype.


Diagnostic suite for isolating common problems.


Print out the lxml events that occur during parsing.

    This lets you see how lxml parses a document when no Beautiful
    Soup code is running.


Print out the HTMLParser events that occur during parsing.

    This lets you see how HTMLParser parses a document when no
    Beautiful Soup code is running.


Generate a random word-like string.


Randomly generate an invalid HTML document.


Very basic head-to-head performance benchmark.


Move all of this tag's children into another tag.


        :yield: A series of 4-tuples.
         (markup, encoding, declared encoding,
          has undergone character replacement)

        Each 4-tuple represents a strategy for parsing the document.


Find the currently active prefix for the given namespace.


Handle comments as Comment objects.


Register a treebuilder based on its advertised features.


Might a tag with this name be an empty-element tag?

        The final markup may or may not actually present this tag as
        self-closing.

        For instance: an HTMLBuilder does not consider a
 tag to be
        an empty-element tag (it's not in
        HTMLBuilder.empty_element_tags). This means an empty
 tag
        will be presented as "

", not "
".

        The default implementation has no opinion about which tags are
        empty-element tags, so a tag will be presented as an
        empty-element tag if and only if it has no contents.
        "<foo></foo>" will become "<foo />", and "<foo>bar</foo>" will
        be left alone.


Replaces class="foo bar" with class=["foo", "bar"]

        Modifies its input in place.


Copy TreeBuilders from the given module into this module.


        :return: A 4-tuple (markup, original encoding, encoding
        declared within markup, whether any characters had to be
        replaced with REPLACEMENT CHARACTER).


Make sure that the given tags have the correct text.

        This is used in tests that define a bunch of tags, each
        containing a single string, and then select certain strings by
        some mechanism.


Make sure that the given tags have the correct IDs.

        This is used in tests that define a bunch of tags, each
        containing a single string, and then select certain strings by
        some mechanism.


Initialize the object from XML data and the desired bounding box


Init from an already loaded Earth Engine Image


Helper function - Look for and load source info about a band


load a data source for a band or mask, represented by the <source> tag.


load a probability distribution into a python dictionary, which may, for
            example, represent the expected distribution of water pixels


Read the band specification and load it into _band_sources and _mask_source.
            Does not load the bands


Automatically determines the source band from an image even if one was not specified


given band specifications in _band_sources and _mask_source, load them into self.image


read a <range> tag


Find and load the dedicated sensor XML file


Parse an xml document representing a domain or a sensor


Return all the parameters needed for the "addToMap()" function for a human-readable image of this sensor


Returns true if the domain contains the named sensor


Manual init with input sensor observations


Load an xml file representing a domain or a sensor


read a bbox, <bbox>


Load in a JSON file containing training features for an EE classifier


Convert pixel coordinate to latitude and longitude.


Convert a latitude and longitude to a pixel coordinate.


Rasterize each of the tiles on to the output image display


Return the visible portion of the map as [xlo, ylo, xhi, yhi] in weird Google coordinates.


Return the bounding box of the current view as [minLon, minLat, maxLon, maxLat]


Refresh the entire map.


Composite together all the tiles in this cell into a single image.


Add a tile to the map.

        This keeps track of the tiles for each overlay in each grid cell.
        As new tiles come in, all the tiles in a grid cell are composited together
        into a new tile and any old tile for that spot is replaced.

        Args:
            image: The image tile to display.
            key: A tuple containing the key of the image (level, x, y)
            overlay: The overlay this tile belongs to (MapViewOverlay object).
            layer: The layer number this overlay corresponds to.    Only used
                    for caching purposes.


Zoom the map.

        Args:
            event: The event that caused this zoom request.
            direction: The direction to zoom.   +1 for higher zoom, -1 for lower.


Saves the current map view to disk as a GeoTIFF


Records the anchor location and sets drag handler.


Updates the map position and anchor position.


Unbind drag handler and redraw.


Return the longitude and latitude of a pixel in the map


Return the pixel coordinate in the map for a given longitude and latitude


Center the map at the given lon, lat and zoom level.


Ads an EE object to the map


Removes an overlay from the map by matching its EE object


Calculate which tiles to load based on the visible viewport.

        Args:
            level: The level at which to calculate the required tiles.
            bbox: The viewport coordinates as a tuple (xlo, ylo, xhi, yhi])

        Returns:
            The list of tile keys to fill the given viewport.


Upsample a lower res tile if one is available.

        Args:
            key: The tile key to upsample.
            callback: The callback to call when the tile is ready.


Insert a new tile in the cache and eject old ones if it's too big.


Record all tile cache information to a file on disk


Read a cache file from disk


Pull URLs off the TileManager's queue and call the callback when done.


Create a TileManager from a mapid.


Dump the cache to disk


Brings up the GUI without adding any new data to it


Adds a layer to the default map instance.

    Args:
            eeobject: The object to add to the map.
            vis_params: A dictionary of visualization parameters.   See
                        ee.data.getMapId().
            *unused_args: Unused arguments, left for compatibility with the JS API.

    This call exists to be an equivalent to the playground addToMap() call.
    It uses a global MapInstance to hang on to "the map".   If the MapInstance
    isn't initialized, this creates a new one.


Removes a layer to the default map instance.

    Args:
            eeobject: The object to add to the map.

    This call uses a global MapInstance to hang on to "the map".   If the MapInstance
    isn't initialized, this creates a new one.


Initialize the Earth Engine object, using your authentication credentials.


An implementation of the paper:
           Matgen, Hostache, Schumann, et. al. "Towards an automated SAR-based flood monitoring system:
           Lessons learned from two case studies." Physics and Chemistry of the Earth, 2011.

        TODO: ????


Use training data to compute the band statistics needed by the active contour algorithm.
       - This version uses a single region and a labeled raster image.


Use training data to compute the band statistics needed by the active contour algorithm.
       This version uses multiple labeled regions.


Initialize a Snake class on an input image


Start up an active contour and process it until it finishes


Special Active Contour radar function wrapper to work with Skybox images


Divides up a single boundary into a grid based on a grid size in meters


Translates the input SAR image into a hybrid linear-log scale as described in
        "Robust automated thresholding of SAR imagery for open-water detection"
        by Patrick J Cutler and Frederick W Koehler


Compute a global threshold via histogram splitting on selected subregions


Standard Z shaped fuzzy math membership function between a and b


Standard S shaped fuzzy math membership function between a and b


Changes the scaling of a number from one range to a new one.


Main function of algorithm from:
          Martinis, Sandro, Jens Kersten, and Andre Twele.
          "A fully automated TerraSAR-X based flood service."
          ISPRS Journal of Photogrammetry and Remote Sensing 104 (2015): 203-212.


As part of the Kittler/Illingworth method, compute J(T) for a given T


Tries to compute an optimal histogram threshold using the Kittler/Illingworth method


Run the chosen algorithm on the given image.


Compute several common interpretations of the MODIS bands


Computes a threshold for a value given examples in a classified binary image


Computes a slope in degrees for each pixel of the DEM


Convert a low resolution water fraction map into a higher resolution DEM-based flooded pixel map


Set up features for the classifier to be trained on


Set up features for the classifier to be trained on: [b2, b2/b1, b2/b1, NDVI, NDWI]


Like _get_modis_learning_bands but adding a lot of simple classifiers


Apply EE classifier tool using a ground truth image.


Based on Figure 3 from "A Multi-Scale Flood Monitoring System Based on Fully
        Automatic MODIS and TerraSAR-X Processing Chains" by
        Sandro Martinis, Andre Twele, Christian Strobl, Jens Kersten and Enrico Stein

       Some steps had to be approximated such as the cloud filtering.  The main pixel
       classification steps are implemented as accurately as can be determined from
       the figure.


Wrapper function for passing domain data into history_diff_core


Leverage historical data and the permanent water mask to improve the threshold method.

       This method computes statistics from the permanent water mask to set a good b2-b1
       water detection threshold.  It also adds pixels which have a b2-b1 level significantly
       lower than the historical seasonal average.


Dynamic Nearest Neighbor Search adapted from the paper:
        "Li, Sun, Yu, et. al. "A new short-wave infrared (SWIR) method for
        quantitative water fraction derivation and evaluation with EOS/MODIS
        and Landsat/TM data." IEEE Transactions on Geoscience and Remote Sensing, 2013."

        The core idea of this algorithm is to compute local estimates of a "pure water"
        and "pure land" pixel and compute each pixel's water percentage as a mixed
        composition of those two pure spectral types.


Enhance the DNNS result with high resolution DEM information, adapted from the paper:
        "Li, Sun, Goldberg, and Stefanidis. "Derivation of 30-m-resolution
        water maps from TERRA/MODIS and SRTM." Remote Sensing of Environment, 2013."

        This enhancement to the DNNS_DEM algorithm combines a higher resolution DEM with
        input pixels that have a percent flooded value.  Based on the percentage and DEM
        values, the algorithm classifies each higher resolution DEM pixel as either
        flooded or dry.


Dynamic Nearest Neighbor Search with revisions to improve performance on our test data


Run flood detection with a named algorithm in a given domain.


Return True if the algorithm has a fractional output.


Like _create_learning_image but using a lot of simple classifiers to feed into Adaboost


Binary search to find best threshold for this band


Run Adaboost classifier trained for a radar data set


For each band, find lowest and highest fixed percentiles among the training domains.


Train Adaboost classifier


Just use a height threshold on the DEM!


Simple EVI based classifier


Method from paper: Xiao, Boles, Frolking, et. al. Mapping paddy rice agriculture in South and Southeast Asia using
                          multi-temporal MODIS images, Remote Sensing of Environment, 2006.

        This method implements a very simple decision tree from several standard MODIS data products.
        The default constants were tuned for (wet) rice paddy detection.


modis_diff but with the threshold calculation included (training image required)


Compute (b2-b1) < threshold, a simple water detection index.

       This method may be all that is needed in cases where the threshold can be hand tuned.


The dartmouth method but with threshold calculation included (training image required)


A flood detection method from the Dartmouth Flood Observatory.

        This method is a refinement of the simple b2-b1 detection method.


 Floating Algae Index. Method from paper: Feng, Hu, Chen, Cai, Tian, Gan,
    Assessment of inundation changes of Poyang Lake using MODIS observations
    between 2000 and 2010. Remote Sensing of Environment, 2012.


Count the number of unconnected blobs in an image


Try to appraise the quality of a result without access to ground truth data!


Compare result to ground truth in region and compute precision and recall


Call merge_bands and clean up the band names


Draw all the sensors and ground truth from a domain


Check the blacklist to see if we should skip a lake


Create a blacklist of lakes we will skip


Computes lake statistics over a date range and writes them to a log file.
        processing_function is called with two arguments: a bounding box and an ee_image.


This main needs to be called from another file with some arguments


Selects and renames the landsat bands we are interested in.
       Works with any Landsat satellite.


Compute the Floating Algae Index


Compute NDTI (Turbidity) index


Compute several indicators of cloudiness and take the minimum of them.


Clear anything this window has drawn on the map


Updates the map with the current class


Deselect all items in the class list


Reset the list after loading a file


Add a new class to the list


Remove class from the list


Write the class list to a JSON formatted text file


Load a class list from a JSON formatted text file


When the map is clicked, add the point to the currently selected class


Remove the last point of the currently selected class


Cleanup all other windows and dump cache to disk


Adds a single parameter slider to the passed in container.


Open a new window to define classifier training regions


Just unload all the current images. Low level function


Loads in an image stored in Google Maps Engine


Add all the current images to the map. Low level function


Updates the MODIS and LANDSAT images for the current date


Creates the Earth Engine flood detection function and adds it to the map


Reload an EE algorithm when one of its parameters is set in the GUI


Sets the processing region to the current viewable area


Pop up a little calendar window so the user can select a date


Tries to rename the given bands of the collection.  Safely ignores
       any bands which are not present.


Keep trying to call getInfo() on an Earth Engine object until it succeeds.


Returns true if the current region is inside the US.


"Decomputes" an ee Rectangle object so more functions will work on it


Generates a MODIS domain file for a location using the permanent water mask


Write a test/train pair of domain files for a single domain


Tests if a given command line tool is available, replicating the "which" function


Downloads an Earth Engine image object to the specified path


Wraps downloadEeImage to allow multiple attempts.


Converts SUDSAQ TreeInterpreter outputs to SHAP Explanation objects


    Unstacks the first parameter of the decorated function and restacks it if
    the incoming data is already stacked; otherwise, do nothing.

    Parameters
    ----------
    func : function
        The function to be decorated.

    Returns
    -------
    function
        The wrapped function.

    Notes
    -----
    This decorator checks if the first parameter of the decorated function (`func`) is
    stacked along a specific dimension named 'loc'. If it is, it unstacks the data
    before passing it to the decorated function. After the function call, it checks
    if the result is a DataArray or Dataset and flattens it along certain dimensions
    if necessary.


    Save an xarray dataset into monthly files.

    Parameters
    ----------
    ds : xarray.Dataset
        The dataset to be saved.
    path : str
        The path to the directory where the monthly files will be saved.

    Notes
    -----
    The dataset is grouped by year and then by month, and each group is saved as a separate NetCDF file.
    Each file name corresponds to the month in the format 'MM.nc'.


    Formats a simple expression by replacing `(key)` with `ds['key']`

    Parameters
    ----------
    ds : xr.Dataset
        The dataset being operated on
    string : str
        Code to be performed on the Dataset object where keys are surrounded by parenthesis
    evaluate : bool, default=False
        Call eval(string) to return instead

    Returns
    -------
    string : str or xr.DataArray
        Formatted string or
    keys : list
        List of keys that were used in the string


    Flatten multi-dimensional xarray data along specified dimensions.

    Parameters
    ----------
    data : xarray.DataArray or xarray.Dataset
        The input xarray data to be flattened.

    Returns
    -------
    xarray.DataArray
        The flattened data.

    Notes
    -----
    If the input data is a dataset, it will first be converted into a DataArray
    using the to_array method.
    The flattening process stacks the data along latitude ('lat') and longitude ('lon') dimensions.
    If the data contains a 'time' dimension, it will also be stacked along this dimension.


    Resample time series data to a specified frequency.

    Parameters
    ----------
    data : xarray.DataArray or xarray.Dataset
        The input time series data.
    freq : str
        The frequency to which the data will be resampled.
        This should be a string representing the desired time frequency,
        such as 'D' for daily, 'W' for weekly, 'M' for monthly, etc.
    how : str, optional
        The method used to aggregate the data after resampling.
        Default is 'mean'. Other options include 'sum', 'min', 'max', etc.

    Returns
    -------
    xarray.DataArray or xarray.Dataset
        The resampled time series data.

    Notes
    -----
    This function relies on the resample method of xarray objects.


    Subsamples along a dimension by dropping every N sample

    Parameters
    ----------
    data: xarray
        Data to subsample on
    dim: str
        Name of the dimension to subsample
    N: int
        Every Nth sample is dropped


    Scale the input data `x` along specified dimensions to have a mean of 0 and a standard deviation of 1.

    Parameters
    ----------
    x : xarray.DataArray
        The input data array to be scaled.

    dims : list, optional
        The dimensions along which to calculate the mean and standard deviation for scaling.
        Default is ['loc'].

    Returns
    -------
    xarray.DataArray
        A new DataArray containing the scaled values.

    Notes
    -----
    The standard score (z-score) of a sample `x` is calculated as:
        z = (x - u) / s
    where `u` is the mean and `s` is the standard deviation along the specified dimensions.
    This function scales the input data along the specified dimensions to have a mean of 0 and a standard deviation of 1.

    Examples
    --------
    >>> import xarray as xr
    >>> import numpy as np
    >>> data = xr.DataArray(np.random.rand(10, 10), dims=['lat', 'lon'])
    >>> scaled_data = scale(data, dims=['lat'])


    Selects data from an xarray Dataset based on latitude and longitude pairs.

    Parameters
    ----------
    ds : xr.Dataset
        The xarray Dataset containing the data.

    pairs : list
        A list of latitude and longitude pairs used for selection.

    remove : bool, optional
        If True, remove the specified pairs instead of selecting them.
        Default is False.

    Returns
    -------
    xr.Dataset
        A new xarray Dataset containing the selected data based on the specified pairs.

    Notes
    -----
    This function selects data from the input xarray Dataset based on latitude and longitude pairs.
    If `remove` is True, it removes the specified pairs from the selection instead of selecting them.


    Aligns a dataset to a daily average

    Parameters
    ----------
    ds : xarray.Dataset
        The input dataset to align.
    sels : mlky.Sect
        {key: sel} where
            key: name of selection
            sel: Sect containing:
                time: int or 2 item list
                    - int: select this exact time
                    - list:
                vars: str, list
                    Variables to operate on

    Returns
    -------
    Dataset
        The aligned dataset.


        Selects timestamps using integer hours (0-23) over all dates

        Parameters
        ----------
        ds : xarray.Dataset
            The dataset to select timestamps from.
        sel : int or list of int
            The hour(s) to select.
        time : xarray.DataArray
            The time dimension of the dataset.

        Returns
        -------
        xarray.Dataset
            The dataset with selected timestamps.


        Globs for input files and opens the dataset

        Config Options
        --------------
        .glob: list
            Glob strings
        .open_mfdataset: dict
            kwargs for function
        .lazy: bool
            Lazy load dataset or not


        Performs custom sel operations defined in the Config

        Config Options
        --------------
        .sels: Sect
            {dim: sel} where
                dim: Dimension to select on
                This can also be:
                    'vars': Select specific variables ds[sel]
                    'month': Select on the time dimension such that time.month == sel
                    'drop_date': Drop a specific date
                        sel may contain:
                            'year': Drop this year
                            'month': Drop this month
                            'day': Drop this day
                        A mask will be constructed using these three keys, ex:
                            sel:
                                year: 2004
                                month: 2
                                day: 29
                        This will drop 2004-02-29
                            sel:
                                year: 2004
                                month: 2
                        This will drop all of February 2004
                if `dim` is an existing dimension, `sel` can be:
                    - 2 item list
                    - A single value


Splits the target from the data and stacks both to be 1d


        Loads and preprocesses data from files.

        Parameters
        ----------
        split: bool, default=False
            Split the data into (data, target), ie. (X, y). This will also
            stack/flatten the data


    Initializes the root logger with parameters defined by the config.

    Parameters
    ----------
    args

    Notes
    -----
    config keys:
        log:
            level: str
            format: str
            datefmt: str


    Pretty prints an iterable in the form {key} = {value} such that the delimiter (=)
    aligns on each line

    Parameters
    ----------
    iterable: iterable
        Any iterable with a .items() function
    enum: bool, default = False
        Whether to include enumeration of the items
    delimiter, default = '='
        The symbol to use between the key and the value
    offset: int, default = 1
        Space between the key and the delimiter: {key}{offset}{delimiter}
        Defaults to 1, eg: "key ="
    prepend: str, default = ''
        Any string to prepend to each line
    print: func, default = print
        The print function to use. Allows using custom function instead of Python's normal print


Attempts to create directories for a given path


    Loads data from a pickle

    Parameters
    ----------
    file : str
        Path to a Python pickle file to load

    Returns
    -------
    any
        The data object loaded from the pickle file


    Saves data to a file via pickle

    Parameters
    ----------
    data: any
        Any pickleable object
    output : str
        Path to a file to dump the data to via pickle


    Handles saving NetCDF (.nc) files. Unstacks an object if the `loc` dimension is present.

    Parameters
    ----------
    data: xr.core.dataarray.DataArray or xr.core.dataarray.Dataset
        An xarray object to be saved. If the object is not one of these types, the
        function quietly returns
    name: str
        Name of the object for logging purposes
    output: str
        Path to output to
    dataset: bool, default = False
        If this should be unstacked to a Dataset object instead of a DataArray
    reindex: Dataset or DataArray, default = None
        If provided, reindexes the data object with the given object
        This is primarily used to expand dimensions back to the MOMO grid after having
        shrunk from dropna


    Simplifies saving objects by taking a dictionary of {name: obj}
    where obj is an xarray object to be passed to save_netcdf

    Parameters
    ----------
    output: str
        Output directory path
    kind: str
        The kind of data to save, eg. train/test
    **others: dict
        {name: object} items to save


    Loads objects from a SUDSAQ run

    Parameters
    ----------
    path: str
        Input directory path
    kind: str, default=None
        The kind of data from the run to read, eg. test, train
    objs: list, default=None
        Objects to retrieve, options: [model, data, target, predict, explanation]
    load: bool, default=True
        Load the data into memory, False leaves the data as lazy
    stack: bool, default=False
        Objects that are typically stacked will be prior to return

    Returns
    -------
    ret: list
        Requested objects


    Decorator that protects the caller from an exception raised by the called function.

    Parameters
    ----------
    func: function
        The function to wrap

    Returns
    -------
    _wrap: function
        The wrapper function that calls func inside of a try/except block


        Wrapper function

        Parameters
        ----------
        *args: list
            List of positional arguments for func
        **kwargs: dict
            Dict of keyword arguments for func


Initializes the mlky Config object


Initializes the logging module per the config


\
    TimeFED is a machine learning system for Time series Forecasting, Evaluation and Deployment.


\
    Create models using the SUDSAQ pipeline


\
    Explain SUDSAQ models using SHAP


    Fits a model and analyzes the performance

    Parameters
    ----------
    model: sklearn.ensemble.*
        An sklearn ensemble model. Tested well with RandomForestRegressor, all
        other models are experimental
    data: mlky.Sect
        Sect object containing the .train and .test splits for this X
        These splits should be xarray.Dataset
    target: mlky.Sect
        Sect object containing the .train and .test splits for this y
        These splits should be xarray.Dataset

    Notes
    -----
    The test set may not want to have NaNs
    The training set must have its NaNs dropped
    Loading is done in this function to ensure
    memory usage is kept down. Lazy load before
    this function.

    Cannot drop NaNs on target prior to kfold as
    X and y wouldn't align raising an exception


    Searches hyperparameter space to determine the best parameters
    to use for a given model and data input.

    Parameters
    ----------
    data:
    target:
    model:

    Returns
    -------
    lambda
        Lambda function that creates an instance of the provided model with the optimized parameters


Creates and trains a desired model.


Retrieves and formats the importances from a RandomForest model


    Calls and returns TreeInterpreter.predict(model, X)

    Parameters
    ----------
    model: ...
        A compatible tree model with TreeInterpreter
    data: xr.DataArray
        2D data to predict with

    Returns
    -------
    (pred, bias, cont): tuple
        The calculated predictions, biases, and contributions objects from
        TreeInterpreter


Performs extra predictions for RandomForestQuantileRegressor models


    Analyzes a model using different metrics and plots

    Parameters
    ----------
    model: sklearn.ensemble
        A fitted sklearn.ensemble model
    data: xarray.DataArray
        The input data, X
    target: xarray.DataArray
        The input target, y
    kind: str, default = 'default'
        The kind of data this is, eg. Train, Test
        Used for titling
    output: str, default = None
        Directory path to output to


        Recursively traverses the DecisionTree and returns a list of paths from the
        given node to all leaf nodes.

        Parameters
        ----------
        node : int
            The current node being traversed.

        Returns
        -------
        list
            A list of paths from the current node to all leaf nodes.


    Predicts outcomes for a single tree model and calculates biases and feature
    contributions.

    Parameters
    ----------
    estimator : DecisionTreeRegressor or DecisionTreeClassifier
        The tree model to calculate predictions, biases, and contributions from.
    X : array-like or pd.DataFrame, shape (n_samples, n_features)
        The input data.

    Returns
    -------
    tuple
        A tuple containing three arrays:
        - predicts : array-like
            Direct predictions for each sample.
        - biases : array-like
            Biases for each prediction.
        - contributions : array-like
            Feature contributions for each prediction.

    Notes
    -----
    The contributions are calculated based on the minimal feature contribution paths
    in the tree.


    Updates a contributions list with another

    Parameters
    ----------
    contributions: list
        Contribution list containing dicts which represent the
        {feature number: contribution value} for each sample
    update: list
        Same as `contributions`, this will update that


    Predicts outcomes for an entire forest model and calculates biases and feature contributions.

    Parameters
    ----------
    model : RandomForestRegressor
        The random forest model to make predictions with.
    X : array-like or pd.DataFrame, shape (n_samples, n_features)
        The input data.
    n_jobs : int, optional (default=None)
        The number of parallel jobs to run. Follows the style of sklearn's n_jobs parameter:
              -1 : All available cores
            None : 1 core
             int : Number of cores to use.

    Returns
    -------
    tuple
        A tuple containing three arrays:
        - predicts : array-like
            Direct predictions for each sample.
        - biases : array-like
            Biases for each prediction.
        - contributions : array-like
            Feature contributions for each prediction.

    Notes
    -----
    The contributions are calculated by aggregating individual tree contributions.


Applies the TreeInterpreter algorithm against an existing SUDSAQ output


Converts this explanation object to an xarray Dataset object


Converts this dataset to a SHAP Explanation object


    Generate and optionally save a SHAP summary plot.

    Parameters
    ----------
    explanation : shap.Explanation
        The SHAP explanation object containing SHAP values and other related data.
    data : pandas.DataFrame or numpy.ndarray
        The dataset used to generate the SHAP values.
    save : str, optional, default=None
        The file path to save the plot. If None, the plot is displayed instead of being saved

    Returns
    -------
    None
        The function saves or displays the plot, but does not return any value.

    Examples
    --------
    >>> summary(explanation, data)
    >>> summary(explanation, data, save='summary_plot.png')


    Generate and optionally save a SHAP heatmap plot.

    Parameters
    ----------
    explanation : shap.Explanation
        The SHAP explanation object containing SHAP values and other related data.
    save : str, optional, default=None
        The file path to save the plot. If None, the plot is displayed instead of being saved.

    Returns
    -------
    None
        The function saves or displays the plot, but does not return any value.

    Examples
    --------
    >>> heatmap(explanation)
    >>> heatmap(explanation, save='heatmap_plot.png')


    Generate and optionally save a SHAP dependence plot for the first feature.

    Parameters
    ----------
    explanation : shap.Explanation
        The SHAP explanation object containing SHAP values and other related data.
    save : str, optional, default=None
        The file path to save the plot. If None, the plot is displayed instead of being saved.

    Returns
    -------
    None
        The function saves or displays the plot, but does not return any value.

    Examples
    --------
    >>> dependence(explanation)
    >>> dependence(explanation, save='dependence_plot.png')


    Calculate SHAP values quickly using FastTreeSHAP.

    Parameters
    ----------
    model : object
        The tree model to explain
    data : pandas.DataFrame
        The dataset for which SHAP values are to be calculated
    n_jobs : int, optional
        The number of parallel jobs to run. Default is -1, which means use all processors
    _dataset : optional
        Additional dataset information used to cast back to SUDSAQ-compatible xarray object

    Returns
    -------
    Explanation
        An object containing SHAP values, feature names, and the dataset.


    Calculate SHAP values by splitting the dataset for parallel processing.

    Experimental.

    Parameters
    ----------
    model : object
        The tree model to explain
    data : pandas.DataFrame
        The dataset for which SHAP values are to be calculated
    n_jobs : int, optional
        The number of parallel jobs to run. Default is -1, which means use all processors
    _dataset : optional
        Additional dataset information used to cast back to SUDSAQ-compatible xarray object

    Returns
    -------
    Explanation
        An object containing combined SHAP values from all subsets, feature names, and the dataset.


    Calculate approximate SHAP values.

    Parameters
    ----------
    model : object
        The tree model to explain
    data : pandas.DataFrame
        The dataset for which SHAP values are to be calculated
    _dataset : optional
        Additional dataset information used to cast back to SUDSAQ-compatible xarray object

    Returns
    -------
    Explanation
        An object containing approximate SHAP values, feature names, and the dataset.


    Generate SHAP explanations for a given model and dataset.

    This function supports resampling the data if specified in the configuration,
    and generates SHAP explanations using either FastTreeSHAP or an approximate
    method depending on availability. The results can be saved and optionally
    plotted.

    Parameters
    ----------
    model : object
        The machine learning model to explain.
    data : xarray.DataArray
        The dataset for which SHAP values are to be calculated. Currently supports
        the kind returned by `utils.load_from_run`.
    kind : str, optional
        The name of the dataset being explained.
    output : str, optional
        The directory path where the results and plots will be saved. Default is None.

    Returns
    -------
    Explanation
        An object containing SHAP values, feature names, and the dataset.

    Notes
    -----
    - The `data` parameter currently only supports the format returned by
      `utils.load_from_run`. This is different from the format passed during
      runtime in the pipeline, which needs to be supported in future versions.
    - If `config.explain.resample` is True, the data will be resampled to 3-day
      intervals, and incomplete groups will be removed.

    See Also
    --------
    fast_shap_values : Function to calculate SHAP values using FastTreeSHAP.
    approx_shap_values : Function to calculate approximate SHAP values.
    utils.load_from_run : Utility function to load data in the supported format.


Helper function to write a script template


Prints the squeue for the current user


Lists the model directories for a given run


Tails 1 on each log file for a given run


Generates a SLURM job for the SUDSAQ pipeline


    Matches silo data to the MOMO lat/lon grid using silo lat/lon data.

    Parameters
    ----------
    ds: xarray.Dataset
        The MOMO Dataset object containing the dimensions latitude and longitude
        to be used for matching
    df: pandas.DataFrame
        Silo dataframe in expected format. Must contain columns: [time, lat, lon]
    tag: str
        The unique tag for this silo. For example, TOAR is `toar.{Config.input.toar.variable}`

    Returns
    -------
    bool or int
        Returns True if the function finished properly, or an int indicating the status code.
        See notes for more information on status codes.

    Notes
    -----
    Status Codes:
    1 - An invalid metric to be used in scipy.stats.binned_statistic_2d was provided


    Calculates the maximum daily average for a variable using a time slice.
    Does NOT include times from the next day.

    Parameters
    ----------
    data: xarray.DataArray
        A single day of data with a `time` dimension
    offset: int, default=8
        Hour many hours to average
    inclusive: bool, default=False
        Whether the offset timestamp is to be included if it lands on a valid timestamp

    Returns
    -------
    xarray.DataArray
        Maximum [offset]-hour daily average


    Performs GET operations to the TOAR2 API for the given parameter, tweaked by config

    Parameters
    ----------
    parameter: str
        Name of the parameter to query

    Returns
    -------
    errors: list
        List of errors incurred while downloading

    Notes
    -----
    The configuration file can control the parameters of the API call

    Config
    ------
    sampling: str
    metrics: list
    daterange:
        start: datetime
        end: datetime
    parameters: list
    networks: list
    stations: list
    output: str
    overwrite: bool


Main VCS-independent setup function for installing Versioneer.


        This method solves an approximation of the ODE.

        Parameters
        ----------
        fun : list(function)
            List of functions to calculate the fluxes of the ODEs. One equation
            for ODE. The function must accept:

            - State, called S, used to evaluate the fluxes

            - Initial state of the element, called S0, used to calculate
              the mainimum and maximum possible state of the reservoir

            - Other parameters (**kwargs) needed to calculate the fluxes

            The function must return:

            - list of fluxes with positive sign if incoming and negative if
              outgoing

            - minimum possible value of the state

            - maximum possible value of the state
        S0 : list(float)
            Initial states used for the ODEs. One value per fun
        **kwargs
            Additional arguments needed by fun. It must also contain dt.

        Returns
        -------
        numpy.ndarray
            Array of solutions of the ODEs. It is a 2D array with dimensions
            (#timesteps, #functions)


        This method finds a component using the name of the parameter or the
        state.

        Parameters
        ----------
        name : str
            Name to use for the search

        Returns
        -------
        int or tuple
            Index of the component in self._content


        This method sets the states to the values provided to the __init__
        method. If a state was initialized as None, it will not be reset.

        Parameters
        ----------
        id : list(str)
            List of element's id where the method is applied.


        This method define the solver to use for the differential equation.

        Parameters
        ----------
        solver : superflexpy.utils.root_finder.RootFinder
            Solver used to find the root(s) of the differential equation(s).
            Child classes may implement their own solver, therefore the tipe
            of the solver is not enforced.


        To be implemented by any child class. This method finds the root of the
        numerical approximation of the differential equation. It can operate
        over the whole time series.


        This method calculated the root of the input function.

        Parameters
        ----------
        diff_eq : function
            Function be solved. The function must accept the following inputs:
            - fluxes : function used to calculate the fluxes given parameters
                       and state
            - S : proposed root. If None, the function must initialize the root
            - S0 : state at the beginning of the time step
            - dt : time step
            - kwargs : other parameters needed by diff_eq
            It must return three float values:
            - Value of the function given the root and the kwargs
            - Lower x boundary for the search
            - Upper x boundary for the search
        fluxes : function
            Function to be passed to diff_eq. See specificatio in
            superflexpy.utils.numerical_approximator
        S0 : float
            state at the beginning of the time step
        dt : float
            time step
        kwargs : dict(str: float)
            parameters needed by diff_eq

        Returns
        -------
        float
            Root of the function


        This method calculated the root of the input function.

        Parameters
        ----------
        diff_eq : function
            Function be solved. The function must accept the following inputs:
            - fluxes : function used to calculate the fluxes given parameters
                       and state
            - S : proposed root. If None, the function must initialize the root
            - S0 : state at the beginning of the time step
            - dt : time step
            - kwargs : other parameters needed by diff_eq
            It must return three float values:
            - Value of the function given the root and the kwargs
            - Lower x boundary for the search
            - Upper x boundary for the search
            - Derivative of the differential equation wrt the root
        fluxes : function
            Function to be passed to diff_eq. See specification in
            superflexpy.utils.numerical_approximator
        S0 : float
            state at the beginning of the time step
        dt : float
            time step
        kwargs : dict(str: float)
            parameters needed by diff_eq

        Returns
        -------
        float
            Root of the function


        This method allows to call methods of the objects that belong to the
        the network.

        Parameters
        ----------
        id : str
            Id of the object. If it is not a node, it must contain the ids of
            the object containing it. If, for example it is a unit, the id will
            be idNode_idUnit.
        method : str
            Name of the method to call.

        Returns
        -------
        Unknown
            Output of the called method.


This method constructs all the structures needed to solve the network


        This method is used to find the attributes or methods of the components
        contained for post-run inspection.

        Parameters
        ----------
        id : str
            Identifier of the component

        Returns
        -------
        int, bool
            Index of the component to look for and indication if it is an
            element or a unit (True) or not.


        This method appends a layer to the structure.

        Parameters
        ----------
        layer : list(superflexpy.framework.elements.BaseElement)
            Layer to be appended.


        This method inserts a layer in the unit structure.

        Parameters
        ----------
        layer : list(superflexpy.framework.elements.BaseElement)
            Layer to be inserted.
        position : int
            Position where the layer is inserted.


        This method allows to call methods of the objects that belong to the
        unit.

        Parameters
        ----------
        id : str
            Id of the object.
        method : str
            Name of the method to call.

        Returns
        -------
        Unknown
            Output of the called method.


        This method adds the prefix to the parameters of the elements that are
        contained in the unit.

        Parameters
        ----------
        id : str
            Prefix to add.


        This method adds the prefix to the states of the elements that are
        contained in the unit.

        Parameters
        ----------
        id : str
            Prefix to add.


This method populates the self._content_pointer dictionary.


        This method is used to find the attributes or methods of the components
        contained for post-run inspection.

        Parameters
        ----------
        id : str
            Identifier of the component
        function : str
            Name of the attribute or method

        Returns
        -------
        Unknown
            Attribute or method to inspect


        This method controls if the layers respect all the rules in terms of
        number of upstream/downstream elements.


Number of downstream elements.


Number of upstream elements


        This method add a prefix to the name of the parameters of the element.

        Parameters
        ----------
        prefix : str
            Prefix to be added. It cannot contain '_'.


        This method sets the states to the values provided to the __init__
        method. If a state was initialized as None, it will not be reset.


        This method add a prefix to the id of the states of the element.

        Parameters
        ----------
        prefix : str
            Prefix to be added. It cannot contain '_'.


        This method define the solver to use for the differential equation.

        Parameters
        ----------
        solver : superflexpy.utils.root_finder.RootFinder
            Solver used to find the root(s) of the differential equation(s).
            Child classes may implement their own solver, therefore the type
            of the solver is not enforced.


        This method calls the solver of the differential equation(s). When
        called, it solves the differential equation(s) for all the timesteps
        and populates self.state_array.


        This method must be implemented by any child class. It calculates the
        weight array(s) based on the lag_time.

        Parameters
        ----------
        lag_time : float
            Characteristic time of the lag function.

        Returns
        -------
        list(numpy.ndarray)
            List of weight array(s).


        This method sets the states to the values provided to the __init__
        method. In this case, if a state was initialized as None, it will be
        set back to None.


        This method distributes the input fluxes according to the weight array
        and the initial state.

        Parameters
        ----------
        weight : list(numpy.ndarray)
            List of weights to use
        lag_state : list(numpy.ndarray)
            List of the initial states of the lag.
        input : list(numpy.ndarray)
            List of fluxes

        Returns
        -------
        numpy.ndarray
            3D array (dimensions: number of timesteps, number of fluxes, max
            lag length) that stores all the states of the lag in time


        This method sets the initial state of the lag to arrays of proper
        length.

        Parameters
        ----------
        lag_time : list(float)
            List of lag times

        Returns
        -------
        list(numpy.ndarray)
            List of the initial states of the lag.


        This method allows to call methods of the objects that belong to the
        node.

        Parameters
        ----------
        id : str
            Id of the object. If it is not a unit, it must contain the ids of
            the object containing it. If, for example it is an element, the id
            will be idUnit_idElement.
        method : str
            Name of the method to call.

        Returns
        -------
        Unknown
            Output of the called method.


        This method adds the prefix to the parameters of the elements that are
        contained in the node.

        Parameters
        ----------
        id : str
            Prefix to add.


        This method adds the prefix to the states of the elements that are
        contained in the node.

        Parameters
        ----------
        id : str
            Prefix to add.


        This methods applies the external routing to the fluxes. External
        routing is the one that affects the fluxes moving from the outflow of
        this node to the outflow of the one downstream. This function is used
        by the Network.

        Parameters
        ----------
        flux : list(numpy.ndarray)
            List of fluxes on which the routing has to be applied.


        This method is used to find the attributes or methods of the components
        contained for post-run inspection.

        Parameters
        ----------
        id : str
            Identifier of the component

        Returns
        -------
        int, bool
            Index of the component to look for and indication if it is an
            element (True) or not.


        Internal routing is the one that affects the flux coming to the Units
        and reaching the outflow of the node. This function is internally
        used by the node.


    Calculate the distance matrix between all FU colours (21x21 matrix) for each
    kind of cone deficiency.


Add country names.

    Parameters:
        axis (cartopy.mpl.geoaxes.GeoAxesSubplot): cartopy axis.
        extent (list): geographical limits.
        projection (cartopy.crs projection, optional): geographical projection,
            PlateCarree default.


Plot exposed value, irma track and irma wind field.


Plot irma damage in USD.


Plot irma damage in %.


Plot irma damage in % in lesser antilles and TCA.


Plot exposure, irma track and contour lines, and irma damage.


Generate figures 03 and 04


 Compute tracks from ibtracs data, if not contained in data_dir.
    This functions is the longest one to execute.


Compute exposure in every island group, if not contained in data_dir.


 Compute tropical cyclone events from tracks at every island group,
    if not contained in data_dir.


Compute impacts of TCs in every island group.


Compute average annual impact


FIGURE EXCEEEDANCE FREQUENCY CURVES


Create a new Hail hazard from MeteoCH radar data
    or COSMO HAILCAST ouput (single- or multi-member)

    Parameters
    ----------
    files : list of str or xarray Dataset
        list of netcdf filenames (string) or xarray Dataset object
    varname : string
        the netcdf variable name to be read from the file
    time_dim : str
        Name of time dimension, default: 'time'
    forecast_init : datetime object
        List with datetimes of forecast initializations,
        needs to have same length as time, default: None
    ensemble_dim : str
        Name of ensemble dimension, default: None
    spatial_dims : list of str
        Names of spatial dimensions
    country_code : int
        ISO 3166 country code to filter the data
    extent : list / array
        [lon_min, lon_max, lat_min, lat_max]
    ignore_date : boolean
        If True: ignores netcdf dates (e.g. for synthetic data).
    n_year_input : int
        Number of years: will only be used if ignore_date=True
    Returns
    -------
    haz : Hazard object
        Hazard object containing radar data with hail intensity (MESHS)


Read MFZ exposure shapefile (.gpkg) to exposure object

    Parameters
    ----------
    shapefile : csv
        file with GVZ exposure (or damage) data
    input_type : string
        'random_points' for point gdf, 'poly' for polygon gdf
    return_type : string
        'exp_pnt' for point exposure, 'exp_shp' for polygon exposure
    Returns
    -------
    exp : Exposure object
        Exposure object


Read CSV file

    Parameters
    ----------
    csv_file : csv
        file with GVZ exposure data
    exp_n_assets : bool
        if True: read number of assets as exposure (rather than their value)
    on_grid : bool
        whether or not data should be interpolated on regular grid (not implemented yet)
    exterior_only : bood
        if yes: estimate value for building exterior (which is easily damaged) from total value
    Returns
    -------
    exp : Exposure object
        Exposure object


Read CSV file

    Parameters
    ----------
    csv_file : csv
        file with GVZ exposure (or damage) data
    cant_insurance : str
        Name of cantonal building insurance company (e.g. 'GVZ')
    on_grid : bool
        whether or not data should be interpolated on regular grid
        (not implemented yet)
    w_rel_dmg : bool
        if relative damage should be saved in gdf too
    return_type: str
        if 'imp': return imp object
        if 'gdf': return gpd.GeoDataFrame
        if 'imp_df': return pd.Dataframe to be used for calib_optimize
        if 'imp_df_yearly': same, but with yearly damages
    exp_n_assets : bool
        if True: read number of assets as exposure (rather than their value)
    haz: climada.hazard
        climada.hazard object to get event_ids. Only needed if return_type='imp_df'
    years: tuple
        tuple of (yearMin,yearMax), to only select the years in this range
    baujahr_filter: str
        if not '', filters damages only for assets with certain year of construction
    Returns
    -------
    xxx : *see "return type" input


Read exposure from netCDF file


Read impact from netCDF file


     Parameters
    ----------
    nc : xr.DataArray
        with 1 timestep only


plot scale bar on map

    Args:
        ax (plt.Axes): figure axes
        point (tuple): starting point of scale (in fig coordinates)
        length (int): length in coord units (m by default)
        crs (str, optional): CRS. Defaults to 'EPSG:2056'.


Plot POH (+-2d) and reported damages per


Plot various plots per event

    Parameters
    ----------
    date : datetime
        date
    imp : Impact
        CLIMADA impact
    haz : Hazard
        CLIMADA hazard (MESHS)
    act_dmgs : dict of CLIMADA Exposure OR CLIMADA impact object
        Dictionary of actual damages read into a CLIMADA Exposure object
        The keys are the dates, formated as strings "ddmmYYYY"
    exp : CLIMADA Exposure
        Exposure
    dur_path : str
        path to duration files with YYYY=year and XXX = variable
    projection : cartopy.crs
        default = ccrs.PlateeCaree()
    extent : list
        [lon_min,lon_max,lat_min, lat_max]
    pl_type : str
        'default' to plot 1d, including duration
        'temp_ev' to ploat also +- 1 day, but no duration
        'sel_dates' to plot only the selected dates
    canton : str
        which (if any) canton borders to plot
    vmax: float
        maximum value for colorbar
        if vmax=0: set vmax as maximum of observed and modelled damages (default)
    Returns
    -------
    plot : matplotlib.figure.Figure
        Figure with plots


plotting function for skill plot from hail_main.py

    Args:
        imp_df (pd.DataFrame): dataframe with modelled and observed damages
        unit (str): unit of impacts
        xmin (float): minimum displayed values
        dmg_thresh (float): threshold used for the skill metrics calculation
        eval_dict (dict): Dictionary of evaluation metrics and hazard,
        exposure and impact info

    Returns:
        plt.Figure: Pyplot figure


Create a maximum filter of a xarray Dataarray, to analyse the highest
    values in a neighbourhood of a certain radius.

    Args:
        da (xr.DataArray): 3d dataaaray with spatial dimensions
        radius (int): Radius in pixels
        spatial_dims (list, optional): dimension names of spatial coords. Defaults to ['chy','chx'].

    Returns:
        da: Dataarray with maximum filter applied


helper function to split events and non events

    Args:
        df (pd.DataFrame): at_centroid_data
        haz_var (str): hazard variable

    Returns:
        tuple: Dataframe with damages and without damages


    Compute verification statistics for at centroid data

    Parameters
    ----------
    at_centroid_data : pandas.Dataframe
        Dataframe with at centroid data, required cols: n_exp, n_dmgs,date,*haz_var*
    haz_var : str, optional
        hazard variable. The default is 'MESHS'.
    exposure_thresh : int, optional
        number of exposure points above which data is considered. The default is 0.

    Returns
    -------
    df : pd.DataFrame
        Dataframe with skill scores.
    npred : int
        number of prediction.


    Parameters
    ----------
    datadir : string
        data directory
    croptypes : list
        list of croptypes. If len(list)>1 data of the different croptypes merged.
    haz_var : string, optional
        Hazard variable. The default is 'MESHS'.
    sample_id : string, optional
        Sample id if data from random sampling is read. The default is None.

    Returns
    -------
    at_centroid_data_out : pandas.Dataframe
        Dataframe with data at centroids for croptype (either single crop or combination)
    croptype : string
        croptype (single crop or combination)


Fit emanuel-type impact function to empirical data

    Args:
        emp_df (pd.DataFrame): DF with empirical data, including 'MDR', 'PAA', and 'count_cell'
        pbounds (dict): dictionary of parameter bounds
        opt_var (str, optional): Variable from emp_df to fit data to. Defaults to 'MDR'.
        options (dict, optional): Additional options for the Bayesian optimizer. Defaults to None.
        optimizer (str, optional): Choice of optimizer. Defaults to 'Nelder-Mead'.
        plot (bool, optional): Whether or not to plot the data. Defaults to True.
        param_start (dict, optional): Initial parameter values. Defaults to None.

    Raises:
        ValueError: if get_emanuel_impf returns an error except for v_half <= v_thresh

    Returns:
        tuple: Parameters, optimizer object, and impact function


create an ImpactFunc based on the parameters in param_dict using the
    method specified in impf_parameterisation_name and document it in df_out.

    Parameters
    ----------
    impf_name_or_instance : str or ImpactFunc
        method of impact function parameterisation e.g. 'emanuel' or an
        instance of ImpactFunc (not implemented here)
    param_dict : dict, optional
        dict of parameter_names and values
        e.g. {'v_thresh': 25.7, 'v_half': 70, 'scale': 1}
    intensity_range : array
        tuple of 3 intensity numbers along np.arange(min, max, step)
    Returns
    -------
    imp_fun : ImpactFunc
        The Impact function based on the parameterisation
    df_out : DataFrame
        Output DataFrame with headers of columns defined and with first row
        (index=0) defined with values. The impact function parameters from
        param_dict are represented here.


Plotting function derived from Jerome Kopp

    Args:
        meas_crowd (pd.Dataframe): DF with crowd sourced data
        dpi (int, optional): DPI of figure. Defaults to 200.
        relief (bool, optional): Whether to plot relief. Defaults to True.
    Returns:
        fig,ax: Figure and axes object


plot corwd sourced data for a given date

    Args:
        date (str): date
        processed (bool, optional): Wheter to use locally saved processed data,
        or download raw data. Defaults to False.
        dpi (int, optional): Figure DPI. Defaults to 200.
        relief (bool, optional): Whether to plot a relief. Defaults to True.

    Returns:
        fig, ax (tuple): Figure and axes object


Processing raw crowd sourced data

    Args:
        crowd_data (pd.DataFrame): Dataframe of crowd sourced data
        processed (bool, optional): whether data is already pre processed. Defaults to True.

    Returns:
        crowd_data: pandas.DataFrame with crowd sourced data


filter exposure to remove buildings that are not built yet

    Args:
        exp (climada.entity.Exposures): exposure to be filtered
        yearMin (int): minimum year to be kept (usually 0, except if only subset
                                                of buildings is to be kept)
        yearMax (max): maximum year to be kept (usually the year of the hazard event)

    Returns:
        exp_out: filtered exposure


        for agriculture, assign average field area from exposure to each
        reported damage claim if damage is reported in a region without exposure,
        use Swiss average field area


    Parameters
    ----------
    ds : xr.dataset
        containing calibration data.
    variable : str
        Hazard variable.
    intensity_range : np.array
        Intensity range of hazard variable.
    cut_off : int
        cut off value for the smooth-empirical fit.
    window_size : int
        windowsize for rolling average.

    Returns
    -------
    ds_roll : xr.dataset
        same as ds, but with rolling average values.
    ds_roll_cut : xr.dataset
        same as ds_roll, but with values above cut_off as constant defined by
        the weighted average.


    Parameters
    ----------
    damages : climada.Impact
        damages impact object
    haz : climada.Hazard
        hazard object
    variable : str
        variable name

    Returns
    -------
    damages : climada.Impact
        damages with new attribute haz_intensity


    Parameters
    ----------
    exp_at_centroid : pd.DataFrame
        Dataframe containing exposure data at centroids
    variable : str
        hazard variable
    date_now : datetime
        current date
    dmg_at_centroid : pd.DataFrame, optional
        Dataframe containing damage data at centroids. The default is None.
    variable_2 : str, optional
        secondary hazard variable to be traced along analysis. The default is None.
    get_PVA : boolean, optional
        get PVA and MDD in output, requires a column 'value_affected' in
        dmg_at_centroids. The default is False.

    Returns
    -------
    at_centroid_dict : Dictionary
        Dictionary containing the important values at all centroids
        that have at least a damage or an overlap between
        exposure and hazard (i.e., a damage prediction)


    main function for calibration - computes a range of variables as
    function of values of the hazard variable

    Parameters
    ----------
    hazard_object: climada.hazard
            hazard object used for calibraiton
    exposure_object: climada.entity.exposures.base.Exposures
            exposure object used for calibration
    damages: dict or climada.engine.impact.Impact
            either dictionary of exposure objects, dictionary of impact objects
            or a single impact objects hat contain damage claims
    exposure_type: str
            type of exposure ('agriculture' or 'buildings')
    variable: str
            hazard variable name
    hazard_object_2: climada.hazard
            hazard object with a secondary hazard variable that is traced trough the analysis
    variable_2: str
            secondary hazard variable name
    filter_year : tuple
            (yearMin,yearMax): to filter exposure data by year when an exposure was built
    dates_modeled_imp : np.array
        array of dt.datetime() with all dates where modelled impact is not zero
        (i.e. there is a hazard_intensity>0 somewhere)
    roll_window_size : int
        Size of rolling window. default to 10 for 10mm moving window in MESHS

    Returns
    -------

    ds: xarray.Dataset
        Dataset with additive calibration-relevant variables as function of hazard variable for each event
            count_cell: number of grid cells with non-zero exposure
            count_all: number of exposed assets
            value_all: total value of exposed assets
            count_dmg: number of affected assets
            value_dmg: total damage
            value_affected: total value affected
    df_all: pandas.Dataframe
        Dataframe which corresponds to the sum of the data in ds over all events
    ds_roll: xarray.Dataset
        ds with rolling average applied
    ds_roll_cut: xarray.Dataset
        ds_roll with cutoff for high values of hazard variable
    values_at_centroid_all: pandas.Dataframe
        A Dataframe with information on damages per gridpoint (PAA, MDD, MDR, n_dmgs),
        and exposure (n_exp), as well as hazard intensity (variable and variable_2)
    intensity_range: numpy.array
        Intensity array for hazard variable used in the calibration


    Parameters
    ----------
    ds: xarray.Dataset
        Dataset with relevant values grouped per MESHS value
    ds_roll: xarray.Dataset
        moving average of ds
    ds_roll_cut: xarray.Dataset
        moving average of ds but with a cutoff after MESHS=60

    Returns
    --------
    df: pandas.Dataframe
        Dataframe with values computed over all events
    df_roll: pandas.Dataframe
        moving average of df
    df_roll_cut: pandas.Dataframe
        moving average of ds but with acutoff
    n_dmgs: pandas.Dataframe
        number of damage claims per intensity value


 get tuple for mapping used to initialized xarray.Dataset
    var name: (tuple of dimension names, array-like)

    Parameters
    ---------
    n_intensity: int
        number of intensity values / length of dimension "variable"
    n_samples: int
        number of bootstrap samples / length of dimension 'b_sample'

    Returns
    --------
    tuple of dimension names and array-like


    Parameters
    ds: xarray.Dataset with date for each sample date
    ds_roll: ds but for rolling averages
    variable: hazard variable
    n_samples: number of bootstrap samples. If do_cross_validation=True,
                n_samples is the number of splits for cross validation
    cut_off: intensity value where function is cut off (default to 60 for MESHS=60mm)
    log_fit: boolean
        if True, fit a logistic function to the data
    keep_raw_values: boolean
        if True, also add raw values to output dataset
    do_cross_validation: boolean
        if True, do cross validation INSTEAD of bootstrapping
    n_splits: int
        number of splits for cross validation
    by_year: boolean
        if True, select cross validation splits by year

    Returns
    -------


fit monotonic function to variables in df (MDR, PAA, MDD, PVA) and
    return a new dataframe with fitted values

    Parameters
    ----------
    df : pandas.Dataframe
        dataframe with values of MDR, PAA, MDD, PVA that a monotonic fit needs
        to be applied to
    Returns
    -------
    df_monotonic : pandas.Dataframe
        dataframe with monotonic fot of values in df


extend hazard object with empty events for calibration

    Args:
        haz (climada.hazard): hazard object to extend
        dates_to_extent (array-like): dates to extend hazard object with


Assign for each exposure coordinate closest hazard coordinate.
    -1 used for disatances > threshold in point distances. If raster hazard,
    -1 used for centroids outside raster.
    Parameters
    ----------
    hazard : Hazard
        Hazard to match (with raster or vector centroids).
    distance : str, optional
        Distance to use in case of vector centroids.
        Possible values are "euclidean", "haversine" and "approx".
        Default: "euclidean"
    threshold : float
        If the distance (in km) to the nearest neighbor exceeds `threshold`,
        the index `-1` is assigned.
        Set `threshold` to 0, to disable nearest neighbor matching.
        Default: 100 (km)
    See Also
    --------
    climada.entity.exposures.base for details: same function for exposure.gdf's
    climada.util.coordinates.assign_coordinates: method to associate centroids to
        exposure points


 Add for each grid cell of output grid, specified by 'index_right'
    in merged, rows with intensity zero such that the total number
    values for the aggregation is equal to n=gridsize_output**2/gridsize_input**2

    Parameters
    ----------
    merged : geopandas.GeoDataframe
        merged dataframe of input data and output grid, with m values per grid cell

    Returns
    -------
    new_merged : geopandas.GEoDataframe
        merged datafarame with n-m zero values added for each grid cell


Create GeoDataFrame from hazard object with columns 'intensity',
    'date', 'event_id', and hazard centroids as geometry

    Parameters
    ----------
    hazard : climada.hazard
        Climada hazard
    Returns
    -------
    gdf : pandas.GeoDataFrame
        geodataframe with hazard information


Aggregating a hazard object to a coarser grid

    Parameters
    ----------
    hazard_in : climada.hazard
        Climada hazard to aggregate to coarser grid
    original_grid_epsg : int, optional
        EPSG number of the original coordinate reference sytem
        of the hazard. The default is 2056.
    extent_new : list of ints, optional if original_grid_epsg is 2056.
        Extent of the new grid (xmin,ymin,xmax,ymax). The default is None.
    cell_size_new : float, optional
        Cell size of the new grid (in units of the original CRS). The default is 2000.
    projection_new_epsg : int, optional
        projection of the centroid coordinates of the new hazard. The default is 4326.
    aggfunc : str, optional
        Function to be used for aggregation. The default is 'mean'.
    treat_zeros_as_nans : boolean, optional
        If True, treat zero values as nans and neglect for aggregation
        If False, treat zero values as zeros and include for aggregation (time consuming).
        The default is True.
    return_xr: boolean, optional
        If True, return the aggregated hazard also as xarray.Dataset
        If False, only return hazard

    Raises
    ------
    ValueError
        If aggregation function is 'max' and treat_zeros_as_nans is False,
        an error is raised to avoid unnecessary time consuming computation.

    Returns
    -------
    hazard_out : climada.hazazrd
        Climada hazard on an aggregated grid


function to grid crowd-sourced data

    Args:
        crowd_source_data (Path,str,pd.DataFrame): dataframe of crowd-source reports
        pop_path (Path,str): path for population data source
        date_sel (str, optional): 'all' for all dates, otherwise '%Y%m%d'. Defaults to '20210628'.
        kernel_size_gap_fill (int, optional): size of kernel (must be odd). Defaults to 7.
        min_crowd_count (int, optional): min count of crowd-source reports.
            Only used if date_sel='all'. Defaults to 100.

    Returns:
        ds: xr.Dataset of gridded crowd-sourced data


create regular grid of cells (e.g. 1kmx1km grid)

    Args:
        extent2056 (tuple): (xmin, xmax, ymin, ymax) values in swiss coordinates (epsg:2056)
        cell_size (int): cell size in coordinate units (with epsg:2056, 1 equals 1km)
        epsg (int, optional): EPSG. Defaults to 2056.

    Returns:
        GeoDataFrame: gdf with one row for each cell


Group values to pre-defined cells (regular grid)

    Args:
        cell (GeoDataFrame): gdf of cells (regular grid of square cells)
        gdf_exp (GeoDataFrame): gdf of exposure points
        aggfunc (dict): Dictionary with signature {var_1:*aggregation type*,var2:...},
            aggregation type can be e.g.: 'sum', 'mean', 'first'.
        count_var (str): Column name used to count the entries. Can be any column
        plot (bool, optional): Plot the grid. Defaults to False.

    Returns:
        GeoDataFrame: gdf with aggregated values


 get an empty grid as geopandas dataframe based on passed epsg, resolution, and grid size

   Parameters
   ----------
       epsg: int
           String denoting the required coordinate system (EPSG format)
       cell_size: float or int
           size of the grid cells either in the unit of the specified coordinate system
       extent: list or tuple
           extent of the grid (xmin, ymin, xmax, ymax)
   Returns
   ----------
       cell: geopandas.GeoDataFrame
           a GeoDataFrame with each grid cell of the 1x1km regular grid represented as polygon.


interpolate 2d array with nan values

    Args:
        zs (np.array): 2d array
        method (str, optional): interpolation method. Defaults to 'linear'.

    Returns:
        np.array: filled array


same as assign_centroids_gdf, but for impact object


    Calculate skill scores and save them to a csv file

    Args:
        imp_df (pd.DataFrame): modelled impact, observed impact
        dmg_thresh (float): damage threshold
        imp_var (str): name of impact variable (MDR or PAA)
        expHazImp_str (str): String of Exposure Hazard ImpactFunction

    Returns:


Assign random points to polygon

    Args:
        number (int): number of points to assign
        polygon (shapely.polygon): polygon

    Returns:
        Point/MultiPoint: radnomly assingned points


assign random points to geodataframe with polgon geometry

    Args:
        gdf (gpd.GeoDataFrame): gdf
        n_pts (str): 'always_one' to calculate 1 point per polygon
                    otherwise name of column that stores the number
                    of points to calculate (e.g. n_claims)
        epsg (int): epsg code
        mode (str, optional): Defaults to 'random'.


Filter impact object by certain events

    Parameters
    ----------
    imp : climada.impact
        imact object to filter
    sel_ev : np.array, dtype=bool
        boolean array of length of event_id with the events to keep

    Returns
    -------
    imp_filtered : climada.impact


cut netcdf xarray object to rectangular lat/lon

    Parameters
    ----------
    da : xarray.Dataset or xarray.DataArray
        dataset
    extent : list or str
        lon_min, lon_max, lat_min, lat_max, default = Switzerland

    Returns
    -------
    da : xarray.DataArray, xarray.Dataset


add background colors for skill score metrics

    Args:
        a-d (axes): axes to add background colors to
        min_plot_val (int): minimum value of "main" plot (axis b)
        dmg_thresh (int, optional): _description_. Defaults to 100.


loops through bins of tc track files (ibtracs, CSV)
    and computes + saves TC hazards


initiates centroids depeding on grid border points and resolution


fix data frames resulting from CALIB 3 or 4:
        - remove 'Unnamed' columns
        - apply GDP scaling for TWN if not yet applied
        - remove mismatched TC events (from list)
    Input:
        df (DataFrame)
        save_path (str): full path to save fixded df to,
            if None (default), it is not saved
        rm_mismatches (boolean): if True, events are removed
    Returns:
        df (DataFrame)


CALIB2: matched events EM-DAT / CLIMADA
    for country:
        impact with full hazard and national exposure


Loop through all regions/countries/matched events and range of v_half
    Returns results, DataFrame which is ammended from input from CLAIB2 called
    results_CVA_ratio
    Called in CALIB3.


Find RMSF or RMSD for each v_half/region combi
    Required by CALIB 4


Find v_half per rgeion with log-ratio of total impact closest to 0.
    Required by CALIB 4


Find global RMSF for list of v_half values and for regional v_half set


Find best fit to log(ratio)=0 for each event/country combo
    Required by CALIB 4


 Plot a sorted Boxplot from Dataframe
    Required in CALIB 2.


 called from CALIB 5: for Impact() from CLIMADA and EM-DAT,
    return DataFrames with event impacts
    for matched events


compute trends in reported damanges from EM-DAT for selected countries


compute trends in simulated damages for selected countries


for all regions, return annual average impact aai, i.e. mean annual impact


Plot the impact functions MDD, MDR and PAA in one graph, where
    MDR = PAA * MDD.

    Parameters:
        axis (matplotlib.axes._subplots.AxesSubplot, optional): axis to use
        kwargs (optional): arguments for plot matplotlib function, e.g. marker='x'

    Returns:
        matplotlib.axes._subplots.AxesSubplot


assign_hazard_to_EMdat: link EMdat event to hazard
        Parameters:
            input files (paths):
                intensity: sparse matrix with hazards as rows and grid points as cols,
                values only at location with impacts
                names: identifier for each hazard (i.e. IBtracID) (rows of the matrix)
                reg_ID: ISO country ID of each grid point (cols of the matrix)
                date: start date of each hazard (rows of the matrix)
                EMdat_data: pd.dataframe with EMdat data
                start: start date of events to be assigned 'yyyy-mm-dd'
                end: end date of events to be assigned 'yyyy-mm-dd'
                disaster_subtype: EMdat disaster subtype

    Returns:
        pd.dataframe with EMdat entries linked to a hazard


hit_country_per_hazard: create list of hit countries from hazard set

        Parameters:
            input files:
                intensity: sparse matrix with hazards as rows and grid points
                as cols, values only at location with impacts
                names: identifier for each hazard (i.e. IBtracID) (rows of the matrix)
                reg_ID: ISO country ID of each grid point (cols of the matrix)
                date: start date of each hazard (rows of the matrix)
    Returns:
        pd.dataframe with all hit countries per hazard


create_lookup: prepare a lookup table of EMdat events to which hazards can be assigned

        Parameters:
                EMdat_data: pd.dataframe with EMdat data
                start: start date of events to be assigned 'yyyy-mm-dd'
                end: end date of events to be assigned 'yyyy-mm-dd'
                disaster_subtype: EMdat disaster subtype
        Returns:
            pd.dataframe lookup


relate EM disaster to hazard using hit countries and time

        Parameters:
            input files:
                lookup: pd.dataframe to relate EMdatID to hazard
                tracks: pd.dataframe with all hit countries per hazard
                delta_t: max time difference of start of EMdat event and hazard
                hit_countries:
                start: start date of events to be assigned
                end: end date of events to be assigned
                disaster_subtype: EMdat disaster subtype
        Returns:
            list with possible hits


function to check if EM_ID has been assigned already and combine possible hits

        Parameters:
            lookup: pd.dataframe to relate EMdatID to hazard
            poss_hit: list with possible hits

        Returns:
            list with all possible hits per EMdat ID


function to assign a hazard to an EMdat event
        to get some confidene into the procedure, hazards get only assigned
        if there is no other hazard occuring at a bigger time interval in that country
        Thus a track of possible_tracks_1 gets only assigned if there are no other
        tracks in possible_tracks_2.
        The confidence can be expressed with a certainty level

        Parameters:
            lookup: pd.dataframe to relate EMdatID to hazard
            possible_tracks_1: list of possible hits with smaller time horizon
            possible_tracks_2: list of possible hits with larger time horizon
            level: level of confidence
        Returns:
            pd.dataframe lookup with assigend tracks and possible hits


compare lookup with assigned tracks to a set with checked sets

        Parameters:
            lookup: pd.dataframe to relate EMdatID to hazard
            checkset: pd.dataframe with already checked hazards
        Returns:
            error scores


Check EM-DAT dataframe from CSV and update variable names if required.

    Parameters:
        Input:
            df_emdat: pandas dataframe loaded from EM-DAT CSV
            target_version (int): target format version. default: 2020
            varnames_emdat: dict with list of variable names in different
                versions of EM-DAT
            varnames_mapping: dict of strings, mapping between varnames_emdat


return list of all countries exposed to a chosen hazard type
    from EMDAT data as CSV.

    Parameters
    ----------
    hazard_name : str
        Disaster (sub-)type accordung EMDAT terminology, i.e.:
        Animal accident, Drought, Earthquake, Epidemic, Extreme temperature,
        Flood, Fog, Impact, Insect infestation, Landslide, Mass movement (dry),
        Storm, Volcanic activity, Wildfire;
        Coastal Flooding, Convective Storm, Riverine Flood, Tropical cyclone,
        Tsunami, etc.
    emdat_file_csv : str
        Full path to EMDAT-file (CSV), i.e.:
        emdat_file_csv = os.path.join(SYSTEM_DIR, 'emdat_201810.csv')
    ignore_missing : boolean
        Ignore countries that that exist in EMDAT but
        are missing in iso_cntry(). Default: True.
    verbose : boolean
        silent mode
    year_range : tuple of integers or None
        range of years to consider, i.e. (1950, 2000)
        default is None, i.e. consider all years

    Returns
    -------
    exp_iso : list
        List of ISO3-codes of countries impacted by the disaster type
    exp_name : list
        List of names of countries impacted by the disaster type


function to load EM-DAT data by country, hazard type and year range

    Parameters:
        country (list of str): country ISO3-codes or names, i.e. ['JAM'].
            set None or 'all' for all countries


function to load EM-DAT data and sum impact per year
    Parameters:
        countries (list of str): country ISO3-codes or names, i.e. ['JAM'].
        hazard_name (str): Hazard name according to EMDAT terminology or
            CLIMADA abbreviation
        emdat_file_csv (str): Full path to EMDAT-file (CSV), i.e.:
            emdat_file_csv = os.path.join(SYSTEM_DIR, 'emdat_201810.csv')
        reference_year (int): reference year of exposures. Impact is scaled
            proportional to GDP to the value of the reference year. No scaling
            for 0 (default)
        imp_str (str): Column name of impact metric in EMDAT CSV,
            default = "Total Damages ('000 US$)"

    Returns:
        yearly_impact (dict, mapping years to impact):
            total impact per year, same unit as chosen impact,
            i.e. 1000 current US$ for imp_str="Total Damages ('000 US$)".
        all_years (list of int): list of years


function to load EM-DAT data return impact per event

    Parameters:
        countries (list of str): country ISO3-codes or names, i.e. ['JAM'].
        hazard_name (str): Hazard name according to EMDAT terminology or
            CLIMADA abbreviation, i.e. 'TC'
        emdat_file_csv (str): Full path to EMDAT-file (CSV), i.e.:
            emdat_file_csv = os.path.join(SYSTEM_DIR, 'emdat_201810.csv')
        reference_year (int): reference year of exposures. Impact is scaled
            proportional to GDP to the value of the reference year. No scaling
            for 0 (default)
        imp_str (str): Column name of impact metric in EMDAT CSV,
            default = "Total Damages ('000 US$)"

    Returns:
        out (pandas DataFrame): EMDAT DataFrame with new columns "year",
            "region_id", and scaled total impact per event with
            same unit as chosen impact,
            i.e. 1000 current US$ for imp_str="Total Damages ('000 US$) scaled".


function to load EM-DAT data return impact per event

    Parameters:
        emdat_file_csv (str): Full path to EMDAT-file (CSV), i.e.:
            emdat_file_csv = os.path.join(SYSTEM_DIR, 'emdat_201810.csv')

        hazard_type_emdat (str): Hazard (sub-)type according to EMDAT terminology,
            i.e. 'Tropical cyclone' for tropical cyclone
        OR
        hazard_type_climada (str): Hazard type CLIMADA abbreviation,
            i.e. 'TC' for tropical cyclone
    Optional parameters:
        year_range (list with 2 integers): start and end year i.e. [1980, 2017]
            default: None --> take year range from EM-DAT file
        countries (list of str): country ISO3-codes or names, i.e. ['JAM'].
            Set to None or ['all'] for all countries (default)

        reference_year (int): reference year of exposures. Impact is scaled
            proportional to GDP to the value of the reference year. No scaling
            for reference_year=0 (default)
        imp_str (str): Column name of impact metric in EMDAT CSV,
            default = "Total Damages ('000 US$)"

    Returns:
        impact_instance (instance of climada.engine.Impact):
            impact object of same format as output from CLIMADA
            impact computation
            scaled with GDP to reference_year if reference_year noit equal 0
            i.e. 1000 current US$ for imp_str="Total Damages ('000 US$) scaled".
            impact_instance.eai_exp holds expected annual impact for each country.
            impact_instance.coord_exp holds rough central coordinates for each country.
        countries (list): ISO3-codes of countries imn same order as in impact_instance.eai_exp


Define impact functions


    Drop events from damage impact objects for different croptypes

    Parameters
    ----------
    drop_dict: dict
        Dictionary with events to be dropped per croptype
    damages : dict
        Dictionary of damages (damages as impact objects) from which to drop events

    Returns
    -------
    damages : dict
        Dictionary of damages with dropped events


same as assign_centroids_gdf, but for impact object


Assign for each exposure coordinate closest hazard coordinate.
    -1 used for distances > threshold in point distances. If raster hazard,
    -1 used for centroids outside raster.
    Parameters
    ----------
    hazard : Hazard
        Hazard to match (with raster or vector centroids).
    distance : str, optional
        Distance to use in case of vector centroids.
        Possible values are "euclidean", "haversine" and "approx".
        Default: "euclidean"
    threshold : float
        If the distance (in km) to the nearest neighbor exceeds `threshold`,
        the index `-1` is assigned.
        Set `threshold` to 0, to disable nearest neighbor matching.
        Default: 100 (km)
    See Also
    --------
    climada.entity.exposures.base for details: same function for exposure.gdf's
    climada.util.coordinates.assign_coordinates: method to associate centroids to
        exposure points