    Computes the signal or K matrix after the PCA analysis.

    Returns
    -------
    K : `~numpy.ndarray`
        Signal matrix, one of the outputs from the PCA analysis. It is
        currently not been used in the `pypcaf` main core. It represents the
        transposed ``EVec_sorted`` timess the normalized waterfall matrix.


    It returns the eigenvalues and eigenvectors (PCA) from the covariance
    matrix of a normalized waterfall array of length, math:`N\\times M`.
    math:`M` represents the number of eigenvalues and eigenvectors.

    Parameters
    ----------
    waterfall : `~numpy.ndarray`
        Array that contains an Amount of ``num_div`` rows (math:`M`). The
        number of elements in a column is N (related to the number of
        iterations in the function `~pypcaf.find_period`). It also is the
        same output as mentioned in function `~pypcaf.folding`.

    Returns
    -------
    EVal_sorted : `~numpy.ndarray`
        Eigenvalues from the covariance matrix, it is always one dimensional
        array. It has also been sorted, in such a way that their values are
        from maximum to minimum. Since the waterfall matrix has been
        normalized their values are of mean equals zero and std 1.
    EVec_sorted : `~numpy.ndarray`
        Eigenvectors from the covariance matrix, it is a multidimensional
        array, and it depends on the number of dimensions of the waterfall
        array. Their values have been sorted in the same way as the ones from
        the eigenvalues, ``EVal_sorted``, viz. their correspondent eigenvalue
        and eigenvector are in the same position in each array.
    signal : `bool`
        If `True` it will compute the signal matrix.


    Finds the best period given an initial starting point, ``T_init``, and
    ``iteration`` and an increase step in every iteration, ``delta``.It also
    computes the merit function, derived from the eigenvalues and
    eigenvectors in `~pypcaf.pca` function.

    Parameters
    ----------
    times : `~numpy.ndarray`
        One dimensional times array with certain hidden periodicity, e.g.
        pulsar period.
    dt : `float`
        times bin.
    T_init : `float`
        Initial period to start looking for a best estimate, ``T_est``.
    iteration : `int`
        Number of iterations in which a ``delta`` increase will be applied.
        The initial period, ``T_init``, is the center point.
    delta : `float`
        Increase of the period in each iteration. The recommended order of it
        is between ``1e-7`` and ``1e-8``.
    num_div : `int`
        Number of divisions made to the times array, which corresponds to the
        number of elements in a row of the waterfall matrix.
    merit_func : `function`
        It computes the merit function from eigenvalues and scalar arrays.
        Both of them should be a one dimensional array.
    region_order : `int`
        It makes use of the `~pypcaf.flat_region_finder` to search for the
        maximum in the selected merit function. If ``region_order = 1``,
        it will compute the ordinary maximum of the merit array, i.e.
        ``np.max(merit)``. This function defines the estimated period after
        one ``iteration``.

    Returns
    -------
    T_est : `float`
        Estimated period from the iteration. The period corresponds to
        ``T_est = T_init - iteration / 2 * delta + idx_max * delta``.
    EValw : `~numpy.ndarray`
        Set of eigenvalues of math:`N` length, i.e. the number of
        iterations, ``iteration``. EValw[:, 0] represents all iteration for the
        first eigenvalue.
    Sw : `~numpy.ndarray`
        Set of scalars of math:`N` length, i.e. the number of
        iterations, ``iteration``. The scalar value is the projection of each
        for the eigenvectors into the hyper-diagonal unitary vector. In other
        words, the dot product of the (absolute value) eigenvector timess the
        same dimension unitary vector. Sw[:, 0] represents all iteration for
        the first eigenvector.
    merit : `~numpy.ndarray`
        Output from the evaluation of ``merit_func``.
    idx_max : `int`
        Position of the maximum value in the merit function (or maximum in a
        plateau region, depending on ``region_finder``). This index is
        then used to compute the estimated period from the selected
        ``iteration``.


    Core function for the `~pypcaf` package. It computes one estimated period
    given an inital period and a ``times`` array (one dimenional), with its
    corresponent time bin.

    Parameters
    ----------
    times_path : `str`
        String with the path to the file. The file must be a text-like file,
        e.g. .csv, .txt, ext. It can also be a python binary file .npy. In any
        case it must be always a one dimensional array.
    dt : `float`
        time bin.
    T_init : `float`
        Initial period to start looking for a best estimate, ``T_est``.
    iterations : `list`
        Corresponds to ``[iteration1, iteration2]``.
    delta : `float`
        Increase of the period in each iteration. The recommended order of it
        is between ``1e-7`` and ``1e-8``.
    num_div : `int`
        Number of divisions made to the ``time`` array, which corresponds to the
        number of elements in a row of the waterfall matrix.
    merit_func : `function`
        It computes the merit function from eigenvalues and scalar arrays.
        Both of them should be a one dimensional array.
    region_order : `int`
        It makes use of the `~pypcaf.flat_region_finder` to search for the
        maximum in the selected merit function. If ``region_order = 1``,
        it will compute the ordinary maximum of the merit array, i.e.
        ``np.max(merit)``. This function defines the estimated period in both
        ``iterations``.
    work_dir : `str`
        Default is `None`, it will store the ``pywpf_out/`` folder in
        elsewhere. The current configuration stores files next to the
        `~pypcaf.pcaf` script.


Plot the average of a list of num_div elements


    Plot for all the merit functions computed up to num_div iterations of
    pypcaf.


for the moment only for a single iteration NO pcaf_double output


Simple chi-squared epoch folding algorithm.


    Merit function calculation. Computes the merit function out of the
    eigenvalues and scalar product after the waterfall diagram has been
    calculated.

    Parameters
    ----------
    EValw : `~numpy.ndarray`
        Set of eigenvalues of math:`N` length, i.e. the number of
        iterations, ``iteration``. EValw[:, 0] represents all iteration for the
        first eigenvalue.
    Sw : `~numpy.ndarray`
        Set of scalars of math:`N` length, i.e. the number of
        iterations, ``iteration``. The scalar value is the projection of each
        for the eigenvectors into the hyper-diagonal unitary vector. In other
        words, the dot product of the (absolute value) eigenvector times the
        same dimension unitary vector. Sw[:, 0] represents all iteration for
        the first eigenvector.

    Returns
    -------
    merit : `~numpy.ndarray`
        The merit function is calculated by selecting the maximum scalar over
        each iteration and then it is multiplied by its correspondent
        eigenvalue.


    Merit function calculation. Computes the merit function by selecting the
    first scalar, ``Sw``. The first scalar is constructed in
    `pypcaf.find_period` and `pypcaf.pca` functions. First the eigenvalues are
    sorted (maximum in the zero position) and then the eigenvector are ordered
    according to the same relocation done in the sorting of the eigenvalues.
    Later the hyper-diagonal is multiplied by the new sort of the
    eigenvectors. Finally the first scalar is multiplied by the first
    eigenvalues.

    Parameters
    ----------
    EValw : `~numpy.ndarray`
        Set of eigenvalues of math:`N` length, i.e. the number of
        iterations, ``iteration``. EValw[:, 0] represents all iteration for the
        first eigenvalue.
    Sw : `~numpy.ndarray`
        Set of scalars of math:`N` length, i.e. the number of
        iterations, ``iteration``. The scalar value is the projection of each
        for the eigenvectors into the hyper-diagonal unitary vector. In other
        words, the dot product of the (absolute value) eigenvector times the
        same dimension unitary vector. Sw[:, 0] represents all iteration for
        the first eigenvector.

    Returns
    -------
    merit : `~numpy.ndarray`
        The merit function is calculated by selecting only the first position
        or first scalar and then multiplied it by its correspondent eigenvalue
        which coincides with the first eigenvalue as well.


    Merit function calculation. Computes the merit function by selecting the
    first scalar, ``Sw`` minus a weight. The weight is given by the average of
    the second until last scalar. The first scalar is constructed in
    `pypcaf.find_period` and `pypcaf.pca` functions. First the eigenvalues are
    sorted (maximum in the zero position) and then the eigenvector are ordered
    according to the same relocation done in the sorting of the eigenvalues.
    Later the hyper-diagonal is multiplied by the new sort of the
    eigenvectors. Finally the first scalar is multiplied by the first
    eigenvalues.

    Parameters
    ----------
    EValw : `~numpy.ndarray`
        Set of eigenvalues of math:`N` length, i.e. the number of
        iterations, ``iteration``. EValw[:, 0] represents all iteration for the
        first eigenvalue.
    Sw : `~numpy.ndarray`
        Set of scalars of math:`N` length, i.e. the number of
        iterations, ``iteration``. The scalar value is the projection of each
        for the eigenvectors into the hyper-diagonal unitary vector. In other
        words, the dot product of the (absolute value) eigenvector times the
        same dimension unitary vector. Sw[:, 0] represents all iteration for
        the first eigenvector.

    Returns
    -------
    merit : `~numpy.ndarray`
        The merit function is calculated by selecting only the first position
        or first scalar minus weight (average of second until last scalar) and
        then multiplied it by its correspondent eigenvalue which coincides with
        the first eigenvalue as well.


    Save the logs to a file.

    Arguments
    ---------
        app : str
            The name of the app.
        message : str
            The message to save.

    Returns
    -------
        None


    Wraps a string with ANSI color escape sequences corresponding to the
    style parameters given.

    All of the color and style parameters are optional.

    This function is from Robert Kern's grin:

      https://github.com/cpcloud/grin

    Copyright (c) 2007, Enthought, Inc. under a BSD license.

    Parameters
    ----------
        s : str
        fg : str
            Foreground color of the text.  One of (black, red, green, yellow, blue,
            magenta, cyan, white, default)
        bg : str
            Background color of the text.  Color choices are the same as for fg.
        bold : bool
            Whether or not to display the text in bold.
        underline : bool
            Whether or not to underline the text.
        reverse : bool
            Whether or not to show the text in reverse video.

    Returns
    -------
        A string with embedded color escape sequences.


    Logs a message the console and saves it to a file.

    Arguments
    ---------
        app : str
            The name of the app.
        message : str
            The message to log.

    Returns
    -------
        None


    Creates a log function for the given app.

    Arguments
    ---------
        app : str
            The name of the app.

    Returns
    -------
        A function that logs a message.


Upload the results to the webhook.


    Use `nmma` to fit data to a model with name `source_name`.

    For this analysis, we expect the `inputs` dictionary to have the following keys:
       - source: the name of the model to fit to the data
       - fix_z: whether to fix the redshift
       - photometry: the photometry to fit to the model (in csv format)
       - redshift: the known redshift of the object

    Other analysis services may require additional keys in the `inputs` dictionary.


        Analysis endpoint which sends the `data_dict` off for
        processing, returning immediately. The idea here is that
        the analysis model may take awhile to run so we
        need async behavior.


            Callback function for when the nmma analysis service is done.
            Sends back results/errors via the callback_url.

            This is run synchronously after the future completes
            so there is no need to await for `future`.


    compares the creation of a lightcurve injection from command line with light_curve_generation and through calling the relevant function directly
    Parameters:
    -----------
    - model_name: string
    Name of model prior to test (e.g. 'nugent-hyper'). Must be included in ./priors/ directory
    - model_lightcurve_function: function
    One of the nmma.em.model functions (e.g. nmma.em.model.SupernovaLightCurveModel) that corresponds to the associated model name


        Creates the injection file from command line using nmma_create_injection
        Parameters:
        ------------
        - model_name: string
        Name of model prior to test (e.g. 'nugent-hyper'). Must be included in ./priors/ directory

        Returns:
        ---------
        - injection_name: string
        path to the injection file created by nmma_create_injection


        Creates the lightcurve file from command line using light_curve_generation
        Parameters:
        ------------
        - model_name: string
        Name of model prior to test (e.g. 'nugent-hyper'). Must be included in ./priors/ directory
        - injection_file: string
        path to injection file created by create_injection_from_command_line

        Returns:
        ----------
        - command_line_lightcurve_file: string
        path to the lightcurve file created by light_curve_generation


        create lightcurve using associated LightcurveModel function
        Parameters:
        ------------
        - model_name: string
        name of model prior to test (e.g. 'nugent-hyper'). Must be included in ./priors/ directory
        - injection_file: string
        path to injection file
        - model_lightcurve_function: function
        associated nmma LightcurveModel function

        Returns:
        ----------
        - lightcurve_from_function: dictionary
        dictionary of lightcurve generated via functions


        Compare the values of the lightcurves generated from the function and command line to look for differences

        Parameters:
        ------------
        - lightcurve_from_function: dictionary
        Dictionary of lightcurve generated from function (keys: filters, values: list of magnitudes)
        - lightcurve_from_command_line: dictionary
        Dictionary of lightcurve generated from command line (keys: filters, values: list of magnitudes)

        Returns:
        None


deletes test files directory


    Given a directory of EOSs and nmma.joint.Constraint,
    returns sorted EOSs and the corresponding prior

    Parameters
    ----------
    eos_path: str
        Path to the original EOSs
    out_path: str
        Path to the sorted EOSs
    Neos: int
        Number of EOSs
    Constraint: nmma.joint.Constraint
        The EOS constraint to be consider

    Returns
    -------
    prior: bilby.core.Prior
        Prior on the EOSs
    logNorm: float
        log normalization constant for the EOS prior


Wrapper function that uses bilby_pipe's complete config writer.

    Note: currently this function does not verify that the written complete config is
    identical to the source config

    :param parser: The argparse.ArgumentParser to parse user input
    :param args: The parsed user input in a Namespace object
    :param inputs: The bilby_pipe.input.Input object storing user args
    :return: None


    API for running the generation from Python instead of the command line.
    It takes all the same options as the CLI, specified as keyword arguments,
    and combines them with the defaults in the parser.

    Parameters
    ----------
    parser: generation-parser
    **kwargs:
        Any keyword arguments that can be specified via the CLI

    Returns
    -------
    inputs: NMMADataGenerationInput
    logger: bilby.core.utils.logger


    nmma_generation entrypoint.

    This function is a wrapper around generate_runner(),
    giving it a command line interface.


    nmma_gw_generation entrypoint.

    This function is a wrapper around generate_runner(),
    giving it a command line interface.


        Calls the bilby rescaling function on an array of values

        Parameters
        ----------
        u_array: (float, array-like)
            The values to rescale

        Returns
        -------
        (float, array-like)
            The rescaled values


        Calculates the log(likelihood)

        Parameters
        ----------
        u_array: (float, array-like)
            The values to rescale

        Returns
        -------
        (float, array-like)
            The rescaled values


        Calculates the log of the prior

        Parameters
        ----------
        v_array: (float, array-like)
            The prior values

        Returns
        -------
        (float, array-like)
            The log probability of the values


    API for running the analysis from Python instead of the command line.
    It takes all the same options as the CLI, specified as keyword arguments.

    Returns
    -------
    exit_reason: integer u
        Used during testing, to determine the reason the code halted:
            0 = run completed normally, based on convergence criteria
            1 = reached max iterations
            2 = reached max runtime
        MPI worker tasks always return -1


    nmma_analysis entrypoint.

    This function is a wrapper around analysis_runner(),
    giving it a command line interface.


Reorders the stored log-likelihood after they have been reweighted

    This creates a sorting index by matching the reweights `result.samples`
    against the raw samples, then uses this index to sort the
    loglikelihoods

    Parameters
    ----------
    sorted_samples, unsorted_samples: array-like
        Sorted and unsorted values of the samples. These should be of the
        same shape and contain the same sample values, but in different
        orders
    unsorted_loglikelihoods: array-like
        The loglikelihoods corresponding to the unsorted_samples

    Returns
    -------
    sorted_loglikelihoods: array-like
        The loglikelihoods reordered to match that of the sorted_samples


Return the kwargs required for the ROQ setup

    Parameters
    ----------
    args: Namespace
        The parser arguments

    Returns
    -------
    kwargs: dict
        A dictionary of the required kwargs


Parser for nmma_analysis


Parser for nmma_gw_analysis


Parse the command line arguments for nmma_analysis and nmma_gw_analysis


    :param args: args from parallel_bilby
    :return: Namespace argument object


Parser for nmma_generation


Parser for nmma_gw_generation


    Returns dictionary of arguments, as specified in the
    parser.

    If no cli_args arguments are specified, returns the default arguments
    (by running the parser with no ini file and no CLI arguments)

    Parameters
    ----------
    parser: generation-parser
    cli_args: list of strings (default: [""])
        List of arguments to be parsed. If empty, returns default arguments
    as_namespace: bool (default False)
        If True, returns the arguments as a Namespace object. If False, returns a dict

    Returns
    -------
    args: dict or Namespace


    Reads in lightcurve data from a file and returns data in a dictionary format.

    Args:
    - filename (str): Path to lightcurve file

    Returns:
    - data (dict): Dictionary containing the lightcurve data from the file. The keys are generally 't' and each of the filters in the file as well as their accompanying error values.


    Read in a list of photometry files with given filenames and process them in a dictionary

    Args:
        files (list): List of filenames with the photometry files.
        filters (list): List of photometry filters to be extracted.
        tt (np.array): Array containing the time grid at which photometry values are given.
        datatype (str): Which model we are considering. Currently supports

    Returns:
        data: Dictionary with keys being the given filenames and values being dictionaries themselves, with keys
        being t (time) and specified filters and values being the time grid, and values the time grid and lightcurves.


    Function to read in lightcurve file and create a dictionary containing the time (in days) at which the lightcurves
    are evaluated and the corresponding values for different filters.


    Utility function for converting mchirp,eta to component masses. The
    masses are defined so that m1>m2. The rvalue is a tuple (m1,m2).


    Interpolates the NaN values in a photometric data.

    Args:
        data (dict): Dictionary containing photometric data. The keys correspond to the filenames
        of the data. The values are dictionaries of which the keys correspond to time (t) or the filters considered.
        The corresponding values are the time grid (in days) and the magnitudes of the different filters.


    Computes the lightcurve from a surrogate model, given the model parameters.
    Args:
        tt (Array): Time grid on which to evaluate lightcurve
        param_list (Array): Input parameters for the surrogate model
        svd_mag_model (SVDTrainingModel): Trained surrogate model for mag
        svd_lbol_model (SVDTrainingModel): Trained surrogate model for lbol
        mag_ncoeff (int): Number of coefficients after SVD projection for mag
        lbol_ncoeff (int): Number of coefficients after SVD projection for lbol
        interpolation_type (str): String denoting which interpolation type is used for the surrogate model
        filters (Array): List/array of filters at which we want to evaluate the model


        Interpolate a functional form of the flux density
        array as a function of wavelength
        Returns
        -------
        spectrum_func: scipy.interpolate.interpolate.interp1d
            functional representation of spectrum


        Plot spectrum in format similar to Even et al. (2019)
        Returns:
        --------
        ax: Axes object
            contains figure information


    Read in spectra at multiple timesteps
    for Even et al. (2019) and subsequent
    paper data format. Written by Eve Chase.
    Parameters
    ----------
    filename: string
        path to spectrum file
    Returns
    -------
    spectra: dictionary
        - time in days as keys
        - each time contains a dictionary with
        a wavelength array in cm and a flux density
        array in erg / s / cm^3


    Tool for reading data from the Wollaeger et al. (2018)
    and subsequent paper data format.
    Used to determine the number of rows for a given passband
    filter or timestep.
    Written by Eve Chase.
    Parameters
    ----------
    filename: string
        path to magnitude file
    key: string
        key to search for in file. Options: 'band', 'time'
    Returns
    -------
    nrows: int
        Number of rows between successive appearances of key
    keys_in_file: dictionary
        Dictionary where keys are each occurance of the selected
        keyword (i.e. each bandname or each timestep) and values
        are the line number to start searching for that value in.


Computes the nuclear specific heating rate over time.

    This implementation is based on a model from Korobkin et al. 2012
    (DOI: 10.1111/j.1365-2966.2012.21859.x), derived from nucleosynthesis
    simulations in compact binary merger ejecta. The model uses these
    parameters: eps0 = 2e18, t0 = 1.3, sig = 0.11, alpha = 1.3.

    Args:
        t: float or numpy.ndarray
           Time(s) in rest-frame to evaluate the light curve. Can be an array
           for multiple time points.
        eth: float or numpy.ndarray, default=0.5
           Efficiency parameter representing the fraction of nuclear power
           retained in the matter, as defined by Korobkin et al. 2012.

    Returns:
        float or numpy.ndarray: Nuclear specific heating rate in erg/g/s
        (units implied but not explicitly used).


    Check if the code is running in a GitHub Actions.

    Returns:
    --------
        bool: True if running in CI, False otherwise.


    Evaluates whether the lightcurve has the requisite user-defined number of observations in the filters provided within the defined time window from the first observation. In the case where one wants to check that at least one filter has the requisite number of observations, the function should be called multiple times with different filter arguments.

    Args:
        data (str): Path to the data file in [nmma-compliant format (.dat, .json, etc.)
        filters (str): Comma separated list of filters to validate against. If not provided, all filters in the data will be used.
        min_obs (int): Minimum number of observations required in each filter before cutoff time.
        cutoff_time (float): Cutoff time (relative to the first data point) that the minimum observations must be in. If not provided, the entire lightcurve will be evaluated
        silent (bool): Suppress output

    Returns:
        bool: True if the lightcurve meets the minimum number of observations in the defined time window, False otherwise.


        Function that preprocesses the data and performs the SVD decomposition for each filter of the data.
        The SVD is done with np.linalg

        Returns:
            svd_model: A dictionary with keys being the filters. The values are dictionaries containing
            the processed values of the parameters, processed values of the data (normalized into a [0, 1] range)
            and the matrices which are used in the projection of the SVD.


Train a tensorflow model to emulate the KN model.


Load a gaussian-process-api GaussianProcess model
    Parameters
    ----------
    gp : dict
        Dictionary representation of gaussian-process-api GaussianProcess model
    Returns
    -------
    gp_api.gaussian_process.GaussianProcess


    Similar to `from_file` but instead of file buffer, takes a list of Prior strings
    See `from_file` for more details


    Training function
    Inputs:
        epoch_index: current epoch number
        tb_writer: writes to tensorboard
        data_loader: validation data in tensor format
        similarity_embedding: ResNet to train
        optimizer: desired optimization method
        verbose: (bool) print loss after each epoch
        vicreg_loss: loss function
        **vicreg_kwargs: additional loss function parameters to change loss weights
    Outputs:
        last_sim_loss: final loss calculation


    Validation training function
    Inputs:
        epoch_index: current epoch number
        tb_writer: writes to tensorboard
        data_loader: validation data in tensor format
        similarity_embedding: ResNet to train
        vicreg_loss: loss function
        **vicreg_kwargs: additional loss function parameters to change loss weights
    Outputs:
        last_sim_loss: final loss calculation


1d convolution with padding


kernel-size 1 convolution


    Opens a json file, loads the data as a dictionary, and closes the file
    Inputs:
        file_name = /name of json file.json
        dir_path = directory containing json files
    Returns:
        data = dictionary containing json content


    Flattens json files into a dataframe
    Inputs:
        file_names = list, contains full path file names as strings
        num_sims = int, number of files to unpack
        detection_limit = float, photometric detection limit
        bands = list, contains the json photometry keys as strings
    Returns:
        df_list = list of dataframes containing the photometry data, time, and number of total detections across all bands


    front end padding
    Inputs:
        column_list: list of columns of the dataframe
        detection_limit: number that is used as the filler, ie the detection limit
        t_min: minimum time
        t_max: maximum time
        step: time increment
    Outputs:
        filler_df: dataframe to pad the existing data


    back end padding
    Inputs:
        column_list: list of columns of the dataframe
        detection_limit: number that is used as the filler, ie the detection limit
        t_min: minimum time
        t_max: maximum time
        step: time increment
    Outputs:
        filler_df: dataframe to pad the existing data


    pads both ends of the light curve dataframe to ensure consistent number of data points across all data
    Inputs:
        actual_df: existing light curve data
        desired_count: desired length of data, ie number of points for the light curve
        filler_time_step: time increment
        filler_data: number that is used as the filler, ie the detection limit
    Outputs:
        cat_df: padded dataframe


    Pads multiple dataframes at a time
    Inputs:
        df_list: list of dataframes to pad
    Outputs:
        padded_df_list: list of dataframes after padding


    Loading in multiple saved csv files containing light curve data as one dataframe
    Inputs:
        data_dir: directory containing the csv files
        csv_no: number of csv files to load in
        num_points: number of data points per light curve
        num_repeats: repeats of injection parameters to determine batches
    Outputs:
        data_df: single dataframe containing the data


    Matches the shifted injection light curve data to its fixed counterpart
    Inputs:
        data_dir: directory containing the data
        name1: label of the varied csv files
        name2: label of the fixed csv files
        start: starting csv number
        stop: ending csv number
        num_points: number of points in the light curve
        num_repeats: number of repeated mass, velocity, lanthanide injections
    Outputs:
        fixed_data_df: returns the fixed portion of the light curve data
        varied_data_df: returns the shifted/varied portion of the light curve data


    Matches light curves with the same injection parameters
    Inputs:
        data_dir: file path for data
        name1: label of the varied csv files
        name2: label of the fixed csv files
        start: starting csv number
        stop: ending csv number
        num_points: number of points in the light curve
        num_repeats: number of repeated mass, velocity, lanthanide injections
    Outputs:
        matched_df: combined dataframe of the shifted and fixed light curves


    Adds a simulation and batch id number to each light curve
    Inputs:
        df: dataframe containing light curve data
        num_points: number of points in the light curve
        num_repeats: number of repeated mass, velocity, lanthanide injections
    Outputs:
        None


    Converts dataframes into pytorch tensors
    Inputs:
        df_varied: dataframe containing the shifted light curve information
        df_fixed: dataframe containing the analagous fixed light curve information
        batches: number of unique mass, velocity, and lanthanide injections
    Outputs:
        data_shifted_list: list of tensors of shape [repeats, channels, num_points] containing the shifted light curve photometry
        data_unshifted_list: list of tensors of shape [repeats, channels, num_points] containing the fixed light curve photometry
        param_shifted_list: list of tensors of shape [repeats, 1, 5] containing the injection parameters of the shifted light curves
        param_unshifted_list: list of tensors of shape [repeats, 1, 5] containing the injection parameters of the fixed light curves


    make barplots of 25th, 50th and 75th percentiles of reduced chi2 distributions for trained models

    :param outdir: Path to the output directory (str)
    :param interpolation_type: Type of interpolation (str)


    Extract plotting parameters and latex representation from the given prior file.
    Keys will be used as column names for the posterior samples and values will be used as axis labels.
    Parameters
    ----------
    prior_filename : str
        The file path of the prior file.
    Returns
    -------
    dict
        A dictionary containing the plotting parameters.


    Load posterior samples from a CSV file.
    Parameters
    ----------
    filename_with_fullpath : str
        The file path of the posterior samples in CSV format.
    prior_filename : str
        The file path of the prior file to crossmatch the parameters and only load the (astrophysical) source parameters.
    Returns
    -------
    numpy.ndarray
        A 2D numpy array representing the posterior samples.


    Load injection data from a JSON file.
    Parameters
    ----------
    prior_filename : str
        The file path of the prior file.
    injection_file_json : str
        The file path of the injection JSON file.
    Returns
    -------
    numpy.ndarray
        A 1D numpy array representing the injection data to be used as truths.


    Load bestfit params from a JSON file.
    Parameters
    ----------
    prior_filename : str
        The file path of the prior file.
    bestfit_file_json : str
        The file path of the bestfit JSON file.
    Returns
    -------
    numpy.ndarray
        A 1D numpy array representing the bestfit params to be used as truths.


    Generate a corner plot for one or multiple datasets.
    Parameters
    ----------
    data : list of numpy.ndarray
        A list of 2D numpy arrays representing multiple datasets.
    labels : dict
        A dictionary containing the labels for each dimension in the datasets. Comes from the plotting_parameters function.
    filename : str
        The file path for saving the corner plot image.
    truths : numpy.ndarray or None
        A 1D numpy array representing the truth values (optional).
    legendlabel : list of str
        A list of legend labels for each dataset.
    ext : str
        The output file extension for the image (e.g., "png", "pdf").
    **kwargs
        Additional keyword arguments for the corner plot.
    Returns
    -------
    None


Translate a file to a COG.


    Function to act as a child process, matching forecasts to the obs until a certain size dataframe is reached. Then that file is written, and the booksfile is updated.
    Neirest neighbouring to match the forecast grid to the observed grid in the form of the clusterarray belonging to the observations. Be careful when domain of the (clustered) observations is larger.
    Determines the order in which space-time aggregation and classification is done based on the potential newvar.
    Also calls unit conversion for the forecasts. (the observed units of a newvariable are actually its old units)
    Loadkwargs can carry the delimiting spatial corners if only a part of the domain is desired.


        Here the forecasts corresponding to the observations are determined, by testing their existence.
        Hindcasts and forecasts might be mixed. But they are in the same class.
        Leadtimes may differ.
        Returns an empty list if non were found


        Gets the daily processed forecasts into memory. Delimited by the left timestamp and the aggregation time.
        This is done by using the load method of each Forecast class in the dictionary. They are stored in a list.


        Force the observed resolution onto the supplied Forecast. Checks if the same resolution and force spatial/temporal aggregation if that is not the case. Checks will fail on the roll-norm difference, e.g. 2D-roll-mean observations and .
        Makes use of the methods of each Forecast class. Checks can be switched on and off. Time-rolling is never applied to the forecasts as for each date already the precise window was loaded, but space-rolling is.


Linear conversion of forecast object units to match the observed units.


        Call upon event classification on the forecast object to get the on-the-grid conversion of the base variable.
        This is classification method is the same as applied to obs and is determined by the similar name.
        Possibly returns xarray object if inplace is False. If newvar is anom and model climatology is supplied through newvarkwargs, it should already have undergone the change in units.


        Control function to spawn the processes matching forecasts to the observation.
        Prepares the input to the top-level matching function (see parameter description there), and spawns it.
        Waits until termination to figure out by means of the booksfile how much was matched, such that the next is spawned.
        This termination is currently determined by the pressure on memory, inside the top level function.
        NOTE: perhaps in the future find a way to split the dates according to resources, and run a few matchings in parallel.


Makes a dask dataframe object. The outfilenames can be collected by reading the timefiles. Or for instance by searching with a regular expression.


        Computes simple predictors like ensmean and ensstd if they are not yet present as columns, and needed by the pp_model
        pp_model is an object from the fitting script. It has a fit method (returning parameters) and a predict method (requiring parameters).
        Currently adds those to the alignedobject frame. Does a bit of bookkeeping about what predcols were added


        Starts the computation of simple predictors (next to the optional raw 'pi' for a binary variable)
        Groups the dask dataframe with the groupers, and then pushes these groups to an apply function.
        In this apply a model fitting function is called which uses the predictor columns and the observation column.
        pp_model is an object from the fitting script. It has a fit method (returning parameters) and a predict method (requiring parameters).
        Computation is only invoked when exporting


            Acts per group (predictors should already be constructed). Calls a fitting function
            in a time-cross-validation fashion. Supplies data as (nfolds - 1)/nfolds for training,
            and writes the returned coeficients by the model to the remaining 1/nfolds part
            (where the prediction will be made) as a dataframe. The returned Dataframe is indexed with time
            Which combines with the groupers to a multi-index.


        Merging ased on day-of-year and the spatial coordinate, returns a dataframe in which the (potentially numerous) columns
        from climatology are added (either a numeric quantile, the climatological probability or the random draws)


        Merges the fits (which when exported have a two-level column index) based on the variables used in fitting
        plus time because of the 3-fold cross validation.


        Makes a probabilistic forecast based on already fitted models (either exported and imported, or externally supplied).
        From that fit it gets the coefficients (indexed by time and fitgroupers), from the aligned frame the compited predictors, and
        with predict method of the pp_model a new dataframe is created. (computation invoked upon exporting)
        If n_members is not None, then we are forecasting n members from the fitted distribution, either randomly or with the weibull equidistant estimator
        If n_members is None then there are two options:
        1) The event for which we forecast is already present as an observed binary variable and we use the Logistic model for the probability of 1.
        2) The event is the exceedence of the quantile beloning to the climatology in this object and we employ scipy implementation of the normal model.


        Computes the climatological and raw scores. The raw scores uses a different threshold when a 'modelclimatology' column is present
        Also computes the score of the predictions from the post-processed model this attribute was created beforehand


        This method goes over the respective frames for the raw, the climatological (and potentially the post-processed) forecasts.
        The score resulting from all of those frames are written as a column to the original aligned frame
        Discrete crps scoring by use of the properscoring package. For a small number of members (11),
        the overestimation compared to the gaussian analytical form is about 20%.
        For good comparison the climatology, the forecast, and corrected should be scored with the same number of members.


Wrapper for discrete ensemble crps scoring. Finds observations and forecasts to supply to the properscoring function


        Put both in the same hdf file, but different key. So append mode. If frame than writes one dataframe for self.frame
        Columns have already been downcased in the previous steps. If store_minimum the function tries to drop forecast members, model coefficients, climatology column. Boolean columns are always dropped.


        Searches for relevant columns to load. Should find either _bs in certain columns or _crps
        Also searches for what the spatial coordinates are, either ['latitude','longitude'] or ['clustid']


        Grouping. Average and compute skill score.
        Always a mid-point leadtime correction is performed.


        Computes a characteristic length per location to use as bootstrapping block length.
        According the formula of Leith 1973 which is reference in Feng (2011)
        T_0 = 1 + 2 * \sum_{\tau= 1}^D (1 - \tau/D) * \rho_\tau
        The number is in the unit of the time-aggregation of the variable. (nr days if daily timeseries, which rolling aggregated ones are)
        Note: should the use of the charlengths have to be adapted for the small datasets? Cannot be 7 weeks or something.


            Computes the lagged autocorrelation in df['observation'] starting at lag one till cutofflag.
            It is assumed that the rows in the dataframe are unique timesteps
            For the scoresets written in experiment 2 this is a correct assumption.
            Uses the time column to make the correct shifts, with the native freq of the variable (difficult to infer)


        At each random instance picks a local time-block-bootstraped sample and computes local skill for each location.
        Full grouping. returns 200 samples per group. Either does a full fraction = 1 sampling
        But also has the possibility to fix the sample size: either with providing an integer to fixsize or according to the minimum availabilities in the loaded dataset, thereby under-sampling the smaller groups.
        Exports the bootstrap samples to the scorefile. Such that later quantiles can be computed.
        Returns a true if completed


            Acts per location/leadtime group.
            Assumes that all rows in the supplied data are unique timesteps.
            Returns a dataframe of 3 cols and n_samples rows.
            Block bootstrapping splits the sets of rows in a non-overlapping sense in blocks with the local blocklength.
            These splits currently might jump into the new season. Otherwise it will be more expensive to track consequtive months
            with local records of uneven length.
            The local blocklength is read from the self.charlengths attribute.


        Rework all sampled local skills to a spatial mean for each random instance. Or let the scores remain local.
        Compute quantiles on these skills. Standard empirical, option is quantile fitted exponential model
        Option to rework this to forecast horizon. Option to average these spatially afterwards when dealing with local scores.
        The options can be seen as a sequential procedure, for the forcast horizon quantiles are needed.
        Always a mid-point leadtime correction is performed.


Saves the experiment log if it is present


        Wrapper that calls the function with a specific spaceagg and timeagg and writes the returns of the function to the column if a name was given
        Invokes the quantile multiplier if the desired column has multiple quantiles


Writes the observations that will be matched to forecasts. Also applies minfilter for average minimum amount of daily observations per season.


Writes the intermediate files. And returns the (possibly appended) booksname


        Possibility to make climatologies based on a longer period than the observations,
        when climtmin and climtmax are supplied.
        No observation minfilter needed. Climatology has its own filters.


        Possible to make model climatologies for certain quantiles (not lead time dependend in contrast to the highresmodelclim)
        All aggregation and possble conversion. Units will not be changed in the meantime, Though quantiles of Kelvin anomalies later be compared to matched & aligned Celsius forecasts.


        Only needed for later subtraction of mean from model fiels to create the anom variable (in matching or in model quantile climatology)
        Performed at the highest possible model resolution (daily and 0.38 degrees).
        Only done once (at the first iteration) and for other iterations this name is copied.
        Changing to the correct (observation) units is done later in the matching.


        Only needed for later subtraction of mean from observations to create the anom variable (in prepareobs and makeclim)
        Performed at the highest possible observation resolution (daily and 0.25 degrees).
        Only done once (at the first iteration) and for other iterations this name is copied.


        Read the obs and clim. make a comparison object which computes the scores in the dask dataframe.
        This dask dataframe is exported.
        Returns a list with intermediate filenames of the raw, climatological and corrected scores.
        Has a post-processing step if the pp_model is supplied. Fit is the same regardless of the quantile, so done only once.
        If there are no quantiles to predict or binary variable, we force equidistant sampling (random = True led to overestimations of the crps)


        Will bootstrap the scores in the scoreanalysis files and export these samples
        Such that these can be later analyzed in the skill function.


Invokes characteristic timescale computation in the ScoreAnalysis object and returns the field


        Reads the exported scoreanalysis file and analyses it.
        Standard is to compute the mean score. But when bootstrapping has been performed in the previous step
        and when usebootstrapped is set to True then quantiles, forecast horizons,
        can all be computed. These options are controlled with analysiskwargs


        Multiplying the returns with the amount of desired quantiles. And supplying this quantile to the function.
        Always making sure that an array is returned which is easily written to the pandas log


Generates the appropriate mars request dictionary. This is the place to set parameters. Called from within the classes when ensemble or control files do not yet exist and need to be downloaded


    Every monday and thursday an operational run is initialized, and associated hindcasts are saved for that date minus 20 years.
    For a batch of initialization days the operational members and the hindcast members are downloaded.


        Tries to load the 6h forecasts with all members and variables in it, and to load the variable res precipitation forecast.
        If not available these are create by 'join_members' calls.
        Joining of members for the combined file is not needed for (re)forecasts
        that are extracted form hindcast Grib-files, therefore CascadeError is raised before function call.
        The actual processing does a daily temporal resampling, and left-labels timestamps to match E-OBS variables:
        - tg: Mean of 6h temperatures in the 24 hrs belonging to yyyy-mm-dd (including 00UTC, excluding 00 UTC of next day)
        - tx: Maximum temperature in the 24 hrs belonging to yyyy-mm-dd
        - rr: Precipitation that will accumulate in the 24 hrs belonging to yyyy-mm-dd


        Join members save the dataset. Control member gets the number 0.
        Only for non-hindcast forecasts.


Remove all files except the processed one and the raw ones.


        Loading of processedfile. Similar behaviour to observation class
        Default behaviour is to load the full spatial field and whole forecast range.
        Field is stored with decreasing latitude but increasing longitude.
        Variable needs to be supplied. Otherwise no array can be loaded.
        If n_members is set to one it selects only the control member.
        Then the numbers are set to a default range because they are not unique across initialization times
        over which they are later pooled. Within one forecast instance they do of course resemble a physical pathway.


        Uses the pandas frequency indicators. Method can be mean, min, max, std
        Completely lazy when loading is lazy. Array needs to be already loaded because of variable choice.


        Aggregation by means of irregular clusters which can be supplied with the clusterarray for quickness.
        Otherwise the desired level is sought from the clustering dataset. In that case we cannot count on the fact that forecasts were already re-indexed in the matching and need to shrink by re-indexing.
        Completely lazy when supplied array is lazy.
        NOTE: this actually changes the dimension order of the array.


        hdates within a file are extracted and perturbed and control are joined.
        The final files are saved per hdate as netcdf with three variables,
        getting the name "_comb.nc" of "_comb_varres.nc" which can afterwards be read by the Forecast class


Remove all files except the processed one. GRIB files are currently kept.


        Name and filepath are based on the base variable and the relevant attributes (if present).
        Var can be a combination like basevar-newvar


        Method to construct the climatology based on forecasts within a desired timewindow.
        Should I add a spacemethod and spatial aggregation option? spacemethod = '0.38-degrees'
        Climatology dependend on doy and on leadtime. Takes the average over all ensemble members and times within a window.
        This window is determined by daysbefore and daysafter and the time aggregation of the desired variable.
        Newvarkwargs should contain a highresmodelclim for the conversion to anomalies. Observed clusterarray to do a spacemethod conversion is supplied seperately (also saved later)


        Per initialization date either the hindcast or the forecast can exist.
        Teste for possibility of empty supplied windows.
        Returns the whole block of (potentially time averaged) forecasts belonging to a set of windows around a doy, at different leadtimes.
        If no forecasts existed for these doy-specific evaluation_windos then it returns none.
        All conversion to newvars, and potential time and space-aggregation happens here.
        Time aggregation can both be rolling and non-rolling.


        Simple linear change of units. Beware with changing units before saving.
        This will lead to problems with for_netcdf_encoding


        Evaluates the analytical gaussian crps for vectorized input of training samples and 4 parameters
        Also analytical calculation of the gradient to each parameter, which is also returned.


        Uses CRPS-minimization for the fitting to the train dataframe.
        Returns an array with 4 model coefs. Internal conversion to float64 for more precise optimization.


        Test dataframe should contain columns with the model_coefs parameters. Otherwise a (4,) array should be supplied
        Predicts climatological quantile exceedence. Or random/equidistant draws from the normal distribution if number of members is supplied.
        If only one (non-random) member is wanted, q_equidistant should be supplied, range [0,1].


        Uses L2-loss minimization to fit a logistic model
        Fitting with liblinear fails if training set has only one category (usually happens when always dry, but there are some cases of always wet).
        If it fails we check if there is indeed one class in the observations. And then return the intercept values that will approximate it with a high precision


        Test dataframe should contain columns with the model_coefs parameters. Otherwise a (3,) array should be supplied
        p = exp(a0 + a1 * raw_pop + a2 * mu_ens) / (1 + exp(a0 + a1 * raw_pop + a2 * mu_ens))


        Uses the statsmodel implementation of quantile regression. Quantile weighted least squares.
        Possibility to only fit the exponential decay beyond a certain leadtime
        Works on dataframe with resetted index. (i.e. leadtime as a column)


        Uses the coefficients that were stored as attributes in fit method.
        Needs a dataframe with resetted index (i.e. leadtime as a column)


        Name and filepath are based on the base variable (or new variable) and the relevant attributes (if present).
        If name is already present as an attribute given upon initialization: reverse engineer the other attributes


Downloads daily highres observations on regular 0.25 degree lat-lon grid.


        Loads the netcdf (possibly delimited by maxtime and corners). Corners need to be given as tuples (lat,lon)
        Creates new attributes: the array with the data, units, and coordinates, and possibly a timemethod.
        If a lazychunk is given (e.g. dictionary: {'time': 3650}) a dask array will be loaded


Requires on average a minimum amount of daily observations per season of interest (91 days). Assigns NaN all year round when this is not the case.


        Aggregation by grouping the cells defined at a certain level in the clustering object. This object was based on a certain season.
        If the domain of the level's extracted clusterarray is smaller, the obs.array domain shrinks too.
        The method deterimines the extracted statistic. With 1 cluster per cell nothing change Of course might not contain an equal number of cells.
        Completely lazy when supplied array is lazy.


        Uses the pandas frequency indicators. Method can be mean, min, max, std
        Completely lazy when loading is lazy.


        Calls new name creation after writing tmin and tmax as attributes. Then writes the dask array to this file.
        Can give a warning of all NaN slices encountered during writing.
        If the particular encoding forces a downcast it is ignored.


        Name and filepath are based on the base variable (or new variable) and the relevant attributes (if present).
        The second position in the name is just 'clim' for easy recognition in the directories.


        Load a local clim if one with corresponding var, tmin, tmax and method is found, or if name given at initialization is found.
        Construct local climatological distribution within a doy window, determined by daysbefore and daysafter, but with pooled years
        Extracts mean (giving probabilities if you have a binary variable). Or a random number of draws if these are given.
        It can also compute a quantile on a continuous variables. Returns fields of this for all supplied day-of-year (doy) and space coordinates.
        Daysbefore and daysafter are inclusive.
        For non-daily aggregations the procedure is the same, as these obs are already rolling and thus stamped daily. Meaning that all needed aggregation, both in space and time, and all needed event classification shoulg already have taken place.


        Method to change rainfall accumulation arrays to a boolean variable of whether it rains or not. Unit is mm / day.
        Because we still like to incorporate np.NaN on the unobserved areas, the array has to be floats of 0 and 1
        Default threshold taken from official definition: https://www.ecad.eu/indicesextremes/indicesdictionary.php#3


        Method to change rainfall accumulation arrays to a boolean variable of whether it is dry or not. Unit is mm / day.
        Because we still like to incorporate np.NaN on the unobserved areas, the array has to be floats of 0 and 1
        Default threshold taken from official definition: https://www.ecad.eu/indicesextremes/indicesdictionary.php#3


        First a climatology. Then local exceedence, 4 consecutive days, 60% in sliding square of 3.75 degree.
        Not the connection yet of events within neighbouring squares yet.


        Substracts the climatological value for the associated day of year from the observations.
        This leads to anomalies when the climatological mean was taken. Exceedances become sorted by doy.
        The climatology object needs to have been supplied at initialization.


        Method to compute the 1D triangular correlation matrix between all cells in the loaded array of the supplied observation class
        The metric is the maximum correlation in a set of lagged timeseries between each pair of cells
        Cells without any observations are removed, otherwise there is no minimum amount.
        Only on timeseries within the season.
        TODO: add parallel computation option


        Hierarchal clustering with a lagged correlation based distance metric (0 is perfect correlated, 2 is perfectly anticorrelated)
        The triangular matrix is supplied to the scipy algorithm linking the clusters with the least average distance.
        The z matrix is stored for dendogram inspection. Cuts of the tree (based on dissimilarity heights) are put into the array format.


        Computes the area in square kilometers for each cluster at each threshold.
        It does so with a correction based on the cosine of the latitude
        Has the possibility to summarize the distribution of clustersizes.


Computes the number of unique clusters for each level and returns this number in a dataframe


Get the number of unique (non-nan) values in an array and return as an xarray with zero dimension


    Regular lat lon or gridbox aggregation by creating new single coordinate which is used for grouping.
    In the case of degree grouping the groups might not contain an equal number of cells.
    Returns an adapted array and spacemethod string for documentation.


    Aggregation allong the lat-lon dimensions by means of a field of clusters. Assumes that the array and the cluster field are on the exact same spatial grid.
    Returns an adapted array, with clustid as the new spatial dimension and a spacemethod string for documentation.
    Skipna


    Assumes an input array with a regularly spaced daily time index. Uses the pandas frequency indicators. Method can be mean, min, max, std
    Completely lazy when loading is lazy. Returns an adapted array and a timemethod string for documentation.
    Skipna is false so no non-observations within the period allowed.
    Returns array with the last (incomplete) interval removed if the input length is not perfectly divisible.
    For rolling the first incomplete fields (that lie previous in time) are also removed.


    Provides the correct factors to linearly convert the units of x to the unit of y: y = ax + b, thus returning a and b.
    The desired outcome should be the units supplied at y.


Character array output of integer array input


    Get quantile along the first axis of the array. Faster than numpy, because it has only a quantile function ignoring nan's along one dimension.
    Quality checked against numpy native method.
    Check here: https://krstn.eu/np.nanpercentile()-there-has-to-be-a-faster-way/
    Modified to take both 2d and 3d array. For 1d use normal np.nanquantile.


    Computes the lagged autocorrelation in df[column] starting at lag one till cutofflag.
    It is assumed that the rows in the dataframe are unique and sorted by time.
    For the scoresets written in experiment 2 this is a correct assumption.


    Provides the leadtime index of the last positive value in the first consecutively positive series
    So input is a multi-index pandas series (of which one level is the leadtime index)
    Returns a float or integer.


    To correct the leadtime index for the fact that leadtime was assigned to the first day.
    Now we assign it to the midpoint of the temporal aggregation. Acts on groupedby timeagg.
    Or on a unique frame and with the string timeagg supplied.


    Vectorized computation of the correlation coefficients betweeen 3D matrix and 1D vector
    X is (d,n,m) with n the number of overvations, d the number of lags and m the number of cells, and y is (n,)
    Takes maximum over first d axis. Thereby returning (m,)
    Can handle NA values.
    adaptation of https://waterprogramming.wordpress.com/2014/06/13/numpy-vectorized-correlation-coefficient/


    X is (m,n) with n the number of overvations, and y is (n,)
    Can handle NA values.


    Will match the data (either array form or dataframe) by clustid to the geolocations of the clusterarray.
    Returns the data in array form with latitude and longitude coordinates. If the supplied dataframe contained multiple variables then these are all returned as dataset.


 Find orbit crossover locations.
        Link to algorithm

        https://stackoverflow.com/questions/
        17928452/find-all-intersections-of-
        xy-data-point-graph-with-numpy


Transform coordinates from proj1 to proj2 (EPSG num).


Extract tile number from file name.


Matches tile indices


Find and compute crossover values.


Converte from GPS time to decimal years.


List files in dir recursively.


        Determines ascending and descending tracks.
        Defines unique tracks as segments with time breaks > tmax,
        and tests whether lat increases or decreases w/time.


Read raster from file.


Bilinear interpolation from grid.


Construct output grid-coordinates.


2D interpolation using median.


2D interpolation using gaussian weight.


2D interpolation using ordinary kriging


Cleaning of spatial data


Raster to point interpolation.


Generic HDF5 writer.

    vardict : {'name1': var1, 'name2': va2, 'name3': var3}


Extrapolate w/Gaussian average of increasing width and taper weights.

    Extend field (internal and external borders) by applying a Gaussian
    average of increasing width at each iteration, and scaling the result
    by a cosine/linear taper (from 1 to 0 with iterations).

    Args:
        grid: 2D field to extrapolate.
        mask: region to exclude from the Gaussian average.
        gauss_widths: width (n_pixels) of Gaussian average at each iteration.
        taper: cosine|linear|None, shape of the weight window.
    Notes:
        Cosine taper goes from 1 at gauss_widths[0] to 0 at gauss_widths[-1].
        gauss_widths define the number of iterations (one per width).
        Widths can be passed as a range (1, N) or explicitly (1, 3, 5, ...).


Transform coordinates from proj1 to proj2 (EPSG num).

    Examples EPSG proj:
        Geodetic (lon/lat): 4326
        Stereo AnIS (x/y):  3031
        Stereo GrIS (x/y):  3413


Regrid z1(x1,y1) onto z2(x2,y2).

    Args:
        z1 is a 2D array.
        x1/y1/x2/y2 can be either 1D or 2D arrays.


    Transform coordinates from proj1 to proj2 (EPSG num).

    Examples EPSG proj:
        Geodetic (lon/lat): 4326
        Stereo AnIS (x/y):  3031
        Stereo GrIS (x/y):  3413


Covariance => average of pair products.


    Calculate sample distance convariance.

    x, y: pair of values to compute covariance.
    dists: distances between x and y (condensed mat).
    lags: discrete lag values to estimate sample cov.
    tol: half-width of the lag interval (lag +/- tol).


Subset data domain (add NaNs).


If file is corruted or empty, return True.


Subset data domain (add NaNs to undesired values).


Filter NaNs using z var.


Time-series binning (w/overlapping windows).

    Args:
        x,y: time and value of time series.
        xmin,xmax: time span of returned binned series.
        dx: time step of binning.
        window: size of binning window.
        interp: interpolate binned values to original x points.


Bin data (Med), compute trend (OLS) on binned, detrend original data


Does the same as above but globally.


    i_invalid = stfilter2([time, x, y, obs], (xi,yi), radius=radius,
                         min_obs=min_obs, n_std=N_STD, step=STEP,
                         window=WINDOW)


Draws random samples from array


Sort array by distance


Function for wrapping longitude to 0 to 360 degrees.


Function for wrapping longitude to -180 to 180 degrees.


List files recursively.


    Transform coordinates from proj1 to proj2 (EPSG num).

    Examples EPSG proj:
        Geodetic (lon/lat): 4326
        Polar Stereo AnIS (x/y): 3031
        Polar Stereo GrIS (x/y): 3413


Fast moving average for 3D array along first dimension.

    Make out = cube.copy() to keep original values at the ends (half window).


Regrid Z1(t,y,x) onto Z2(y,x,t), keeping the original time steps.

    Args:
        x1/y1/x2/y2 are 2D arrays.
        z1 is a 3D array.

    Notes:
        This only works for coords in 2D (for 1D see interp3d).
        It reverses the time dimension (0-axis -> 2-axis).


Regrid Z1(y,x) onto Z2(y,x).

    Args:
        x1/y1/z1/x2/y2 are 2D arrays.

    Notes:
        This only works for coords in 2D (for 1D see interp2d).


Print arguments passed to argparse.


Generic HDF5 reader.

    vnames : ['var1', 'var2', 'var3']


Test if file is corruted or empty


Find index of 'nearest' value(s).

    Args:
        arr (nd array) : The array to search in (nd). No need to be sorted.
        val (scalar or array) : Value(s) to find.

    Returns:
        out (tuple or scalar) : The index (or tuple if nd array) of nearest
            entry found. If `val` is a list of values then a tuple of ndarray
            with the indices of each value is return.

    See also:
        find_nearest2


    Construct 2D-grid given input boundaries

    :param xmin: x-coord. min
    :param xmax: x-coord. max
    :param ymin: y-coors. min
    :param ymax: y-coord. max
    :param dx: x-resolution
    :param dy: y-resolution
    :param return_2d: if true return grid otherwise vector
    :return: 2D grid or 1D vector


    Transform coordinates from proj1 to proj2
    usgin EPSG number

    :param proj1: current projection (4326)
    :param proj2: target projection (3031)
    :param x: x-coord in current proj1
    :param y: y-coord in current proj1
    :return: x and y now in proj2


    Robust std.dev using median absolute deviation

    :param x: data values
    :param axis: target axis for computation
    :return: std.dev (MAD)


    2D median interpolation of scattered data

    :param x: x-coord (m)
    :param y: y-coord (m)
    :param z: values
    :param Xi: x-coord. grid (2D)
    :param Yi: y-coord. grid (2D)
    :param n: number of nearest neighbours
    :param d: maximum distance allowed (m)
    :return: 1D array of interpolated values


    2D interpolation using a gaussian kernel
    weighted by distance and error

    :param x: x-coord (m)
    :param y: y-coord (m)
    :param z: values
    :param s: obs. errors
    :param Xi: x-coord. interp. point(s) (m)
    :param Yi: y-coord. interp. point(s) (m)
    :param n: number of nearest neighbours
    :param d: maximum distance allowed (m)
    :param a: correlation length in distance (m)
    :return: 1D vec. of prediction, sigma and nobs


    2D interpolation using ordinary kriging/collocation
    with second-order markov covariance model.

    :param x: x-coord (m)
    :param y: y-coord (m)
    :param z: values
    :param s: obs. error added to diagonal
    :param Xi: x-coord. interp. point(s) (m)
    :param Yi: y-coord. interp. point(s) (m)
    :param d: maximum distance allowed (m)
    :param a: correlation length in distance (m)
    :param n: number of nearest neighbours
    :return: 1D vec. of prediction, sigma and nobs


    Spatial outlier editing filter

    :param x: x-coord (m)
    :param y: y-coord (m)
    :param z: values
    :param dx: filter res. in x (m)
    :param dy: filter res. in y (m)
    :param n_sigma: cutt-off value
    :param thres: max absolute value of data
    :return: filtered array containing nan-values


    Raster to point interpolation based on
    scipy.ndimage import map_coordinates

    :param x: x-coord. in 2D (m)
    :param y: x-coord. in 2D (m)
    :param z: values in 2D
    :param xi: interp. point in x (m)
    :param yi: interp. point in y (m)
    :param kwargs: see map_coordinates
    :return: array of interp. values


    Reading tif-file to memory

    :param ifile: path+name of tif file
    :return: X, Y, Z, dx, dy and proj


    Writing raster to a tif-file

    :param ofile: name of ofile
    :param X: x-coord of raster (2D)
    :param Y: y-coord of raster (2D)
    :param Z: values (2D)
    :param dx: grid-spacing x
    :param dy: grid-spacing y
    :param proj: projection (epsg number)
    :param dtype: save as 'int' or 'float'
    :return: written file to memory


Time-series binning (w/overlapping windows).

        Args:
        x,y: time and value of time series.
        xmin,xmax: time span of returned binned series.
        dx: time step of binning.
        window: size of binning window.
        interp: interpolate binned values to original x points.


    Hampel-filter for outlier editing

    :param x: values
    :param k: window size (int)
    :param t0: sigma threshold value
    :return: filtered array with nan's


Savitztky-Golay filter with support for NaNs.

    If time is given, interpolate NaNs otherwise pad w/zeros.
    If time is given, calculate dt as t[1]-t[0].

    Args:
        dt (int): spacing between samples (for correct units).

    Notes:
        Works with numpy, pandas and xarray objects.


Two dimensional data smoothing and least-square gradient estimate.

    Code from:
        http://scipy-cookbook.readthedocs.io/items/SavitzkyGolay.html

    Reference:
        A. Savitzky, M. J. E. Golay, Smoothing and Differentiation of
        Data by Simplified Least Squares Procedures. Analytical
        Chemistry, 1964, 36 (8), pp 1627-1639.


List files in dir recursively.


        [2] For postprocessing: The RMS error converged to about 0.25 m after
        removing the data with the 5% highest waveform misfits in each campaign, so we
        adopted that as a data-editing threshold, retaining 95% of the original data.


Make monthly vector


Set model parameters


Time-series binning (w/overlapping windows)
        and weights.

    Args:
        x,y,: time, value and weight of time series.
        xi  : time vector of returned binned series.
        dx  : time step of binning.
        window: size of binning window.


Partitions 'length' into (approximately) equal 'parts'.


Get corr coef between h and w/f params.


Get corr gradient (slope) between h and w/f params.


Compute variance change from x1 to x2 (magnitude and percentage).


Compute linear-trend change from x1 to x2 (magnitude and percentage).


Compute gradient using the Savitzky-Golay filter.

    Computes a smooth surface by piecewise 2D polynomial fit.

    For axis=None returns both deriv: dzdx, dzdy (reversed of numpy.gradient).

    dx is the grid spacing.


Compute gradient of a two-component vector field.

    dx, dy are grid spacings in x and y dimensions.


Find index for "nearest" value.

    Parameters
    ----------
    arr : array_like, shape nd
        The array to search in (nd). No need to be sorted.
    val : scalar or array_like
        Value(s) to find.

    Returns
    -------
    out : tuple
        The index (or tuple if nd array) of nearest entry found. If `val` is a
        list of values then a tuple of ndarray with the indices of each value
        is return.

    See also
    --------
    find_nearest2


Divergence of velocity: div(V) = (d/dx,d/dy)*(u,v)


Flux divergence: div(hv) = (d/dx, d/dy) * (hu, hv).

    Args:
        h : 2D thickness field.
        u, v : 2D velocity fields.


Stretching component: h * div(v) = h * [(d/dx, d/dy) * (u, v)].

    Args:
        h : 2D thickness field.
        u, v : 2D velocity fields.


Advection component: v * grad(h) = (u, v) * (dh/dx, dh/dy).

    Args:
        h : 2D thickness field.
        u, v : 2D velocity fields.


Remove all files from list with no points inside bbox.


List files in dir recursively.


        [2] For postprocessing: The RMS error converged to about 0.25 m after
        removing the data with the 5% highest waveform misfits in each campaign, so we
        adopted that as a data-editing threshold, retaining 95% of the original data.
        Also, filter out cloud-contaminated points using the 'cloud_flg' param.


Savitztky-Golay filter with support for NaNs

    If time is given, interpolate NaNs otherwise pad w/zeros.

    dt is spacing between samples.


    Regrid Z1(t,y,x) onto Z2(y,x,t), keeping the original time.

    x1/y1/x2/y2 are 2D arrays.
    z1 is a 3D array.


Coded by Ben Smith University of Washington


Map time (yr) to campaign to correction.


Design matrix padded with dummy variables


Fit a robust polynomial of n:th deg.


    ofile = ifile.replace('.h5', '_XCAL_FUSED.h5')
    with h5py.File(ofile, 'w') as f:
        f['h_res'] = zi.reshape(Xi.shape[0], Xi.shape[1], ti.shape[0])
        f['h_err'] = ei.reshape(Xi.shape[0], Xi.shape[1], ti.shape[0])
        f['n_obs'] = ni.reshape(Xi.shape[0], Xi.shape[1], ti.shape[0])
        f['x'] = Xi[0,:]
        f['y'] = Yi[:,0]
        f['t'] = tmed

    print 'out ->', ofile


Regrid height field (low res) onto velocity field (high res).


Filter outliers by evaluating the derivative.

    Take derivative and evaluate outliers in derivative.


Filter deviations from the median and from the gradient.


Filter end points by evaluating against the derivative.

    Take derivative and evaluate outliers in derivative,


Filter artifacts at the junction between velocity fields (Alex/Eric).

    params for 3km grid: blon=186, blat=-82.68, dlon=13, dlat=0.06


Function for interpolating nan-values.


    Time-series binning (w/overlapping windows).

    Args:
        x,y: time and value of time series.
        xmin,xmax: time span of returned binned series.
        dx: time step of binning.
        window: size of binning window.
        interp: interpolate binned values to original x points.


Iterative mode filter.

    Remove values repeated 'min_count' times.


Bin data (Med), compute trend (OLS) on binned, detrend original data.


Detrend (binned) data, remove 3 sigma from residual, repeat.


Bin data, remove binned, remove 3 sigma from residual, repeat.


    Fit a straight-line by robust regression (M-estimate: Huber, 1981).

    If `return_coef=True` returns the slope (m) and intercept (c).


If file is empty/corruted, return True.


    Use various filters to remove outliers.

    Replaces outliers with NaNs.


    Interpolate waveform params based on height-series valid entries.

    See also:
        interp_params2()


    Calculate scattering correction for height time series.

    The correction is given as a linear combination (multivariate fit) of
    waveform parameters. The correction time series is obtain in two steps:

        1) Fit the coefficients to the differenced/detrended series:

        det[h](t) = a det[Bs](t) + b det[LeW](t) + c det[TeS](t)

        2) Linear combination of original series using fitted coeffs:

        h_cor(t) = a Bs(t) + b LeW(t) + c TeS(t)

    where a, b, c are the "sensitivities" (or weights, or scaling factors)
    for each waveform-parameter time series.

    Args:
        t: time
        h: height change (residuals from mean topo)
        bs: backscatter coefficient
        lew: leading-edge width
        tes: trailing-edge slope


RMSE between (detrended) x1 and x2.


Variance change from (detrended) x1 to x2 (magnitude and percentage)


Linear-trend change from x1 to x2 (magnitude and percentage).


Create output containers


    1. Reference all time series
    2. Correc dh for dFAC
    3. Correct dh for SLT
    4. Compute h(t) time series: h_mean + dh(t)
    5. Compute freeboard: H_freeb = h(t) - MSL
    6. Compute thickness and draft


	Iterative weighted least-squares

	:param A: design matrix (NxM)
	:param y: observations (N)
	:param w: weights (N)
	:param n_iter: number of iterations
	:param n_sigma: outlier threshold (i.e. 3-sigma)
	:return: model coefficients
	:return: index of outliers


	Read geotiff file

	:param file: input file name
	:return x: coordinate array(2D)
	:return y: coordinate array(2D)
	:return z: value array (2D)
	:return dx: x-resolution
	:return dy: y-resolution
	:return proj: crs string


	Transform coordinates from proj1 to proj2
	usgin EPSG number

    :param proj1: current projection (4326)
    :param proj2: target projection (3031)
    :param x: x-coord in current proj1
    :param y: y-coord in current proj1
    :return: x and y now in proj2


	Time-series binning (w/overlapping windows) using the mean/median.
	Handles NaN values in computation
	:param x: reference values (time)
	:param y: values to bin (elevation)
	:param xmin: min-value of reference
	:param xmax: max-value of reference
	:param dx: step-size of referece values
	:param window: size of binning window
	:param median: median instead of mean for binning
	:return xb: reference value (center of bin)
	:return yb: binned value
	:return eb: standard deviation of bin
	:return nb: number of values in bin
	:return sb: sum of values in bin


	Wrapping array of values in degrees to 0-360 degrees

	:param arr: value in degress
	:return warr: wrapped value


	Wrapping array of values in degrees to -180 to 180 degrees

	:param arr: value in degress
	:return warr: wrapped value


	Robust Robust standard error (using MAD)
	:param x: data values
	:param axis: target axis for computation
	:return: standard error based on MAD


	Remove values greater than n * MAD (set to NaN)
	:param x: data values
	:param n: integer for editing (3*MAD)
	:return: edited x-values (contains NaN's)


    Detect peaks in data based on their amplitude and other features.

    Parameters
    ----------
    x : 1D array_like
        data.
    mph : {None, number}, optional (default = None)
        detect peaks that are greater than minimum peak height.
    mpd : positive integer, optional (default = 1)
        detect peaks that are at least separated by minimum peak distance (in
        number of data).
    threshold : positive number, optional (default = 0)
        detect peaks (valleys) that are greater (smaller) than `threshold`
        in relation to their immediate neighbors.
    edge : {None, 'rising', 'falling', 'both'}, optional (default = 'rising')
        for a flat peak, keep only the rising edge ('rising'), only the
        falling edge ('falling'), both edges ('both'), or don't detect a
        flat peak (None).
    kpsh : bool, optional (default = False)
        keep peaks with same height even if they are closer than `mpd`.
    valley : bool, optional (default = False)
        if True (1), detect valleys (local minima) instead of peaks.

    Returns
    -------
    ind : 1D array_like
        index of the peaks in `x`.


	Interpolates and fills NaN data using linear interpolation

	:param x: vector contaning NaN's
	:return: vector with filled NaN's


	box-filter for smoothing data using mean kernel

	:param x: vector of data to filter
	:param k: size of filter kernel/box
	:return: vector of filtered values


    spatial parametric filter using bi-quadratic surface model
    to and edits residuals. should accept lat/lon as coords.
    :param x : x-coord
    :param y : y-coord
    :param z : vector of data to filter
    :param dx: size of box x-direction
    :param dy: size of box y-direction
    :param niter: number of least-squares iterations
    :param sigma: outlier threshold for residuals
    :param thres: absolut threshold for residuals
    :return: vector of filtered values


Low-pass filter using kernel average


        Computes slope in x and y direction from DEM using the
        Zevenbergen & Thorne algorithm


Group files by key_number.


Join a set of subgrids into a mosaic.


Initialize resizable 1d arrays to hold the outputs.


Initialize resizable 2d array to hold the output.


Save 'data' columns as chunks in 1d arrays.


Save 'data' as a chunk in a 2d array.


Fast moving average for 3D array along first dimension.


Find index(es) of "nearest" value(s).

    Parameters
    ----------
    arr : array_like (ND)
        The array to search in (nd). No need to be sorted.
    val : scalar or array_like
        Value(s) to find.

    Returns
    -------
    out : tuple
        The index (or tuple if nd array) of nearest entry found. If `val` is a
        list of values then a tuple of ndarray with the indices of each value
        is return.

    See also
    --------
    find_nearest2


Fast moving average for 3D array along first dimension.

    Pass out = cube.copy() to keep original values at the ends (half window).


    Merge variables from several input files into a single file.

    Args:
        ifiles (list): input file names.
        ofile (str): output file name.
        vnames (list): name of vars to merge.


Sort files by numbers *after* the key in the file name.


Separate missions, smooth and cross-calibrate.

    Args:
        tcap, hcap, mcap: 1D arrays containing all missions
            (a single grid cell).
    Return:
        dict1, dict2, dict3: 3 dicts {mission_id: value} with
            time, calibrated h and h_smoothed.


Align time series in dicts into a matrix (t_uniq x n_sats).


Merge time series by median of overlap, and reference to epoch.

    Args:
        t_uniq: 1D array with continous (cube) full time.
        hh: 2D array with 1 sat/column (t_uniq.shape[0] == hh.shape[0]).


Covariance of x,y -> average of pair products.


Calculate sample distance convariance.

    x, y: pair of variables to compute covariance from.
    dists: distances between x and y (condensed matrix).
    lags: discrete lag values to estimate sample covariances.
    tol: margin to determine width of lag interval: width = lag +/- tol.


Expand (sub)strings into list of file names.


Subset data domain (add NaNs).


Remove NaNs and Zeros.


Calculate sample covariance.


Writes vars w/values as 1d arrays to file.


    Sort all 1d variables in an HDF5.

    Args:
        fname: HDF5 file with equal lenght 1d variables.
        varname: name of variable to use for sorting.


Fast moving average for 3D array along last dimension.

    Pass out = cube.copy() to keep original values at the ends (half window).


Merge 'files' into 'ofile' with suffix 'tile_num'.


Filter anomalous residuals w.r.t. the trend.

    1. Exclude constant values (dy/dx = 0) from the analysis.
    2. Detect gross outliers.
    3. Fit piece-wise polynomial trend ignoring gross outliers.
    4. Interpolate trend on gross outliers.
    5. Filter residuals w.r.t. to the trend.
    6. Interpolate residuals on outliers.
    7. Add back trend + residuals + constant values.


Calculate sample time covariance.


Convert irregularly lagged covs to evenly spaced lags.


    Remove polynomial trend from time series data.

    Return:
        y_resid, y_trend: residuals and trend.


Generate a regular grid.


Remove offset from each individual track (FOR TESTING ONLY).


Add correlated (off-diagonal) errors to C.

    If i,j belong to the same track (aij == bij)
    and they are not in the diagonal (i != j), then:
        cij += sigma


Draw random samples from array.


 Sample data at random within sectors.

    If n_samples == float -> total percent of sampled data.
    If n_samples == int -> number of samples drawn per sector.


Optimal Interpolation of spatial data to a 2d grid.


Crop tile according bbox in file name.


Set prediction grid.


Robust nonlinear regression.


    Convert sea-level pressure [Pa] to inverse barometer correction [m].

        h_ibe(x,y,t) = -1/(rho g) (P(x,y,t) - P_ref(x,y))

    Args:
        P: pressure at sea level [Pa = kg/m.s2]; P(t,y,x).
        rho: density of sea water [kg/m3].
        g: gravity [m/s2].
        P_ref: reference pressure, the climatological mean: P_ref(y,x).
            If P_ref is not None (e.g. the mean global pressure is given:
            1013.25 * 100 [Pa]), then P_ref = const.


    Convert seconds since epoch1 to hours since epoch2.

    If epoch2 is None, keeps epoch1 as the reference time.


Save data in a dictionary to HDF5 (1d arrays).


Fast 3D interpolation.

    Given a 3d-array (a cube) "v" with pixel coordinates "x","y","z"
    (0-, 1-, 2-axis), interpolate values "xi","yi","zi" using linear
    interpolation.

    Additional kwargs are passed on to ``scipy.ndimage.map_coordinates``.

    Note that in the case of "real-world" coordinates, we might have:
    x=time (0-axis), y=latitude (1-axis), z=longitude (2-axis) or
    x=bands, y=rows, z=cols. Example:

        interp_pts = interp3d(time, lat, lon, grid, t_pts, y_pts, x_pts)

    x,y,z and xi,yi,zi are 1d arrays.
    v is a 3d array.

    See:
        https://goo.gl/KmfnPk
        https://goo.gl/g7APAf


Map interpolation coordinates to pixel locations.


Wrapps longitude to -180 to 180 degrees.


List files (with pattern) in dir recursively.


Add prefix and/or suffix to file name.


List files in dir 'path' recursively.


Replace all occurrences of a 'text' in an ascii file.


Rename defined variables in HDF5 file.


Add time variable to HDF5 file.


Convert epoch as (Y,M,D,h,m,s) to datetime object.


Return (fractional) serial date number from datetime object.


Convert time on reference epoch1 to reference epoch2.


Convert seconds since epoch to datetime object.


Convert datetime object to seconds since epoch.


    Convert seconds since epoch1 to hours since epoch2.

    If epoch2 is None, keeps epoch1 as the reference.


    Convert date as Y,M,D[,H,M,S] to Matlab's serial date number.

    These are number of days from January 0, 0000.


    Partition time array into segments with breaks > tmax.

    Returns an array w/unique identifiers for each segment.


    Determines ascending and descending tracks.

    Defines unique tracks as segments with time breaks > tmax,
    and tests whether lat increases or decreases w/time.


Identify file's campaign and tag file name.


Load velocity grid from NetCDF4.


Load velocity grids from NetCDF4.


Load height grid from HDF5.


Regrid 2nd field onto 1st (i.e. regrid u/v onto h grid).


    Loads parameters for a given tidal constituent

    Arguments
    ---------
    c: tidal constituent ID

    Returns
    -------
    amplitude: amplitude of equilibrium tide in m for tidal constituent
    phase: phase of tidal constituent
    omega: angular frequency of constituent in radians
    alpha: load love number of tidal constituent
    species: spherical harmonic dependence of quadrupole potential


    Reads files for Richard Ray's Global Ocean Tide (GOT) models
    Makes initial calculations to run the tide program
    Spatially interpolates tidal constituents to input coordinates

    Arguments
    ---------
    ilon: longitude to interpolate
    ilat: latitude to interpolate
    directory: data directory for tide data files
    model_files: list of model files for each constituent

    Keyword arguments
    -----------------
    METHOD: interpolation method
        spline: scipy bivariate spline interpolation
        linear, nearest: scipy regular grid interpolations
    GZIP: input files are compressed
    SCALE: scaling factor for converting to output units

    Returns
    -------
    amplitude: amplitudes of tidal constituents
    phase: phases of tidal constituents


    Wrapper function to extend an array

    Arguments
    ---------
    input_array: array to extend
    step_size: step size between elements of array

    Returns
    -------
    temp: extended array


    Wrapper function to extend a matrix

    Arguments
    ---------
    input_matrix: matrix to extend

    Returns
    -------
    temp: extended matrix


    Read Richard Ray's Global Ocean Tide (GOT) model file

    Arguments
    ---------
    input_file: model file

    Returns
    -------
    hc: complex form of tidal constituent oscillation
    lon: longitude of tidal model
    lat: latitude of tidal model


    Predict tides at multiple times and locations using harmonic constants

    Arguments
    ---------
    t: days relative to 1992-01-01T00:00:00
    hc: harmonic constant vector (complex)
    constituents: tidal constituent IDs

    Keyword arguments
    -----------------
    DELTAT: time correction for converting to Ephemeris Time (days)
    CORRECTIONS: use nodal corrections from OTIS/ATLAS or GOT models

    Returns
    -------
    ht: tidal time series reconstructed using the nodal corrections


    Reads files for an OTIS-formatted tidal model
    Makes initial calculations to run the tide program
    Spatially interpolates tidal constituents to input coordinates

    Arguments
    ---------
    ilon: longitude to interpolate
    ilat: latitude to interpolate
    grid_file: grid file for model
    model_file: model file containing each constituent
    EPSG: projection of tide model data
    TYPE: tidal variable to run
        z: heights
        u: horizontal transport velocities
        v: vertical transport velocities

    Keyword arguments
    -----------------
    METHOD: interpolation method
        spline: scipy bivariate spline interpolation
        linear, nearest: scipy regular grid interpolations
    GRID: binary file type to read
        ATLAS: reading a global solution with localized solutions
        OTIS: combined global solution

    Returns
    -------
    amplitude: amplitudes of tidal constituents
    phase: phases of tidal constituents
    D: bathymetry of tide model
    constituents: list of model constituents


    Read grid file to extract model coordinates, bathymety, masks and indices

    Arguments
    ---------
    input_file: input grid file

    Returns
    -------
    x: x-coordinates of input grid
    y: y-coordinates of input grid
    hz: model bathymety
    mz: land/water mask
    iob: open boundary index
    dt: time step


    Read ATLAS grid file to extract model coordinates, bathymety, masks and
    indices for both global and local solutions

    Arguments
    ---------
    input_file: input ATLAS grid file

    Returns
    -------
    x: x-coordinates of input ATLAS grid
    y: y-coordinates of input ATLAS grid
    hz: model bathymety
    mz: land/water mask
    iob: open boundary index
    dt: time step
    pmask: global mask
    local: dictionary of local tidal solutions for grid variables
        depth: model bathymety


    Read the list of constituents from an elevation or transport file

    Arguments
    ---------
    input_file: input tidal file

    Returns
    -------
    constituents: list of tidal constituent IDs
    nc: number of constituents


    Read elevation file to extract real and imaginary components for constituent

    Arguments
    ---------
    input_file: input elevation file
    ic: index of consituent

    Returns
    -------
    h: tidal elevation


    Read elevation file with localized solutions to extract real and imaginary
    components for constituent

    Arguments
    ---------
    input_file: input ATLAS elevation file
    ic: index of consituent
    constituent: tidal constituent ID

    Returns
    -------
    h: global tidal elevation
    local: dictionary of local tidal solutions for elevation variables
        z: tidal elevation


    Read transport file to extract real and imaginary components for constituent

    Arguments
    ---------
    input_file: input transport file
    ic: index of consituent

    Returns
    -------
    u: zonal tidal transport
    v: meridional zonal transport


    Read transport file with localized solutions to extract real and imaginary
    components for constituent

    Arguments
    ---------
    input_file: input ATLAS transport file
    ic: index of consituent
    constituent: tidal constituent ID

    Returns
    -------
    u: global zonal tidal transport
    v: global meridional zonal transport
    local: dictionary of local tidal solutions for transport variables
        u: zonal tidal transport
        v: meridional zonal transport


    Creates a high-resolution grid mask from model variables

    Arguments
    ---------
    xi: input x-coordinates of global tide model
    yi: input y-coordinates of global tide model
    mz: global land/water mask
    local: dictionary of local tidal solutions

    Keyword arguments
    -----------------
    VARIABLE: key for variable within each local solution
        depth: model bathymety

    Returns
    -------
    x30: x-coordinates of high-resolution tide model
    y30: y-coordinates of high-resolution tide model
    m30: high-resolution land/water mask


    Combines global and local ATLAS tidal solutions into a single
    high-resolution solution

    Arguments
    ---------
    xi: input x-coordinates of global tide model
    yi: input y-coordinates of global tide model
    zi: global tide model data
    pmask: global mask
    local: dictionary of local tidal solutions

    Keyword arguments
    -----------------
    VARIABLE: key for variable within each local solution
        depth: model bathymety
        z: tidal elevation
        u: zonal tidal transport
        v: meridional zonal transport

    Returns
    -------
    x30: x-coordinates of high-resolution tide model
    y30: y-coordinates of high-resolution tide model
    z30: combined high-resolution tidal solution for variable


Construct masks for zeta, u and v nodes on a C-grid


Interpolate bathymety to zeta, u and v nodes on a C-grid


    Calculates the difference between universal time and dynamical time

    Arguments
    ---------
    delta_file: file containing the delta times
    t: input times to interpolate (days since 1992-01-01T00:00:00)

    Returns
    -------
    deltat: delta time at the input time


    Calculates the sum of a polynomial function of time

    Arguments
    ---------
    coefficients: leading coefficient of polynomials of increasing order
    t: delta time in units for a given astronomical longitudes calculation


    Computes the basic astronomical mean longitudes: s, h, p, N and PP

    Arguments
    ---------
    MJD: Modified Julian Day (MJD) of input date

    Keyword arguments
    -----------------
    MEEUS: use additional coefficients from Meeus Astronomical Algorithms
    ASTRO5: use Meeus Astronomical coefficients as implemented in ASTRO5

    Returns
    -------
    s: mean longitude of moon (degrees)
    h: mean longitude of sun (degrees)
    p: mean longitude of lunar perigee (degrees)
    N: mean longitude of ascending lunar node (degrees)
    PP: longitude of solar perigee (degrees)


    Converts lat/lon points to and from projected coordinates

    Arguments
    ---------
    i1: longitude ('F') or projection easting x ('B')
    i2: latitude ('F') or projection northing y ('B')
    PROJ: spatial reference system code for coordinate transformations
    BF: backwards ('B') or forward ('F') translations

    Keyword Arguments
    -----------------
    EPSG: spatial reference system code for input (F) and output (B) coordinates

    Returns
    -------
    o1: projection easting x ('F') or longitude ('B')
    o2: projection northing y ('F') or latitude ('B')


    Convert seconds since epoch1 to days since epoch2.

    If epoch2 is None, keeps epoch1 as the reference time.


    Calculates the nodal corrections for tidal constituents

    Arguments
    ---------
    MJD: modified julian day of input date
    constituents: tidal constituent IDs

    Keyword arguments
    -----------------
    DELTAT: time correction for converting to Ephemeris Time (days)
    CORRECTIONS: use nodal corrections from OTIS/ATLAS or GOT models

    Returns
    -------
    pu,pf: nodal corrections for the constituents
    G: phase correction in degrees


    Calculate the tidal corrections for minor constituents inferred using
    major constituents

    Arguments
    ---------
    t: days relative to 1992-01-01T00:00:00
    zmajor: Complex HC for given constituents/points
    constituents: tidal constituent IDs

    Keyword arguments
    -----------------
    DELTAT: time correction for converting to Ephemeris Time (days)
    CORRECTIONS: use nodal corrections from OTIS/ATLAS or GOT models

    Returns
    -------
    dh: height from minor constituents


    Reads files for a netCDF4 tidal model
    Makes initial calculations to run the tide program
    Spatially interpolates tidal constituents to input coordinates

    Arguments
    ---------
    ilon: longitude to interpolate
    ilat: latitude to interpolate
    directory: data directory for tide data files
    grid_file: grid file for model (can be gzipped)
    model_files: list of model files for each constituent (can be gzipped)
    TYPE: tidal variable to run
        z: heights
        u: horizontal transport velocities
        U: horizontal depth-averaged transport
        v: vertical transport velocities
        V: vertical depth-averaged transport

    Keyword arguments
    -----------------
    METHOD: interpolation method
        spline: scipy bivariate spline interpolation
        linear, nearest: scipy regular grid interpolations
    GZIP: input netCDF4 files are compressed
    SCALE: scaling factor for converting to output units

    Returns
    -------
    amplitude: amplitudes of tidal constituents
    phase: phases of tidal constituents
    D: bathymetry of tide model
    constituents: list of model constituents


    Read elevation file to extract real and imaginary components for constituent

    Arguments
    ---------
    input_file: input elevation file

    Keyword arguments
    -----------------
    GZIP: input netCDF4 files are compressed

    Returns
    -------
    h: tidal elevation
    con: tidal constituent ID


    Read transport file to extract real and imaginary components for constituent

    Arguments
    ---------
    input_file: input transport file

    Keyword arguments
    -----------------
    TYPE: tidal variable to run
        u: horizontal transport velocities
        U: horizontal depth-averaged transport
        v: vertical transport velocities
        V: vertical depth-averaged transport
    GZIP: input netCDF4 files are compressed

    Returns
    -------
    tr: tidal transport
    con: tidal constituent ID


Records a diagnostic image to the log directory


Record the input MODIS image to the log directory


Searches for a record with a particular date and returns it


Converts an input data record dictionary to a line of text


Extract the information from a single line in the log file in to a dictionary object