 compute a target mesh size (triangle side length) at the point (x,y).
        ARGS:
            x: x point to compute mesh size at
            y: y point to compute mesh size at
            _scale: a factor that determines how quickly mesh size should increase away from primitive boundaries. higher = more quickly.
            _power: another factor that determines how mesh size increases away from boundaries. default = 1 (linear increase). higher = more quickly.
            min_size: the minimum mesh size that the algorithm can choose
            max_size: the maximum mesh size that the algorithm can chooose


 construct a finite element mesh for the waveguide at current z (default 0).

        ARGS:
            writeto (str or None): filename for mesh (no extension). if None, no file is saved.


 construct a mesh with boundary refinement at material interfaces.

        ARGS:
            writeto (str or None): filename for mesh (no extension). if None, no file is saved.


 not currently used. construct a mesh around the union of Waveguide boundaries computed at z and z+dz.
            returns both the mesh and a custom dictionary mapping regions of the mesh to
            refractive indices. to advance the refractive index profile from z to z+dz
            use self.advance_IOR() to update the dictionary.


 build a dictionary which maps all material labels in the Waveguide mesh
            to the corresponding refractive index value


 plot a mesh and associated refractive index distribution

        ARGS:
            z: the z coordinate for the mesh we want to plot. if None, z=0.
            mesh: the mesh to be plotted. if None, we auto-compute a mesh using default values
            IOR_dict: dictionary that assigns each named region in the mesh to a refractive index value
            alpha: transparency of mesh lines
            ax: optionally, pass in a matplotlib axis for the plotter
            plot_points: controls if the mesh nodes will be plotted


 plot the boundaries of all prim3Dgroups. For unioned primitives, all boundaries of
            the original parts of the union are plotted in a lighter color.


 unvectorized version of transform(); this was the original version and is still
        here just for reference.


 spatial transformation that should work with most meshes. kinda slow to compute currently, maybe could be sped up.
        general idea: for a point (x0,y0) find the two nearest primitives at z0. this point, plus the two closest points to
        to it, each constrained to lie on a primitive boundary, define a triangle. At z, the primitive boundaries move, and so
        two of the triangle vertices move. this transformation places the third point of the triangle, which is (x,y), to
        preserve triangle similarity.

        ARGS:
            x0 : (scalar or vector, if self.vectorized_transform) x coord. at z0
            y0 : (scalar or vector, if self.vectorized_transform) y coord. at z0
            z0 : reference z coord.
            z : new z coord.

        RETURNS:
            (tuple) : a tuple containing:

                - x (scalar or vector): the transformed x coordinate at z.
                - y (scalar or vector): the transformed y coordinate at z.


 compute the derivative of the transformation law. default
        implementation uses finite differences, but an explit law
        can be written for inheriting classes (e.g. PhotonicLantern).

        ARGS:
            x0 : (scalar or vector, if self.vectorized_transform) x coord. at z0
            y0 : (scalar or vector, if self.vectorized_transform) y coord. at z0
            z0 : reference z coord.
            z : new z coord.
        RETURNS:
            x : the transformed x coordinate at z
            y : the transformed y coordinate at z


 use the transformation law to create a new, transformed
        mesh from the reference mesh.

        ARGS:
            mesh0: the reference mesh (meshio object).
            z0: the z coordinate corresponding to mesh0 (typically 0).
            z: the desired z coordinate of the transformed mesh.
            mesh: a mesh object to store the new mesh. if None, a new mesh
            object is generated.


 create a refractive index dictionary that sets all channels except one to the background index.
        'channels' are assumed to be stored in the last list of self.prim3Dgroups.
        override this if your waveguide is different.

        ARGS:
            k: index of the channel to isolate


plot the single-mode channel paths


 plot a real-valued finite element field, evaluated on the points of the mesh corresponding to the waveguide cross-section at z

    ARGS:
        field: the finite element field to plot, e.g. the output of make_field()
        mesh (opt.): the mesh object defining the points that field is evaluated on. If None, a mesh will be auto-generated
        ax (opt.): a matplotlib axis where the plot should go. if not None, you will need to call matplotlib.pyplot.show() manually
        show_mesh (opt.): whether or not to draw the mesh in the plot


 solve for waveguide modes at given z value. returns effective indices and eigenmodes.
        also stores the finite element mesh used to self.mesh

        ARGS:
            z (float): z coordinate along the waveguide for the solve, default 0
            mesh: FE mesh to solve on. if None, we make a mesh corresponding to the given z

        RETURNS:
            (tuple) : a tuple containing:

                - neff: an array of effective indices
                - v: an array of eigenmodes, dimensions NxM for N modes and M mesh points


 compute the modes and coupling coefficients of the currently loaded waveguide,
        and set things up for propagation. for reference, this function calls compute_modes()
        and then compute_cmat().

        ARGS:
            zi: initial z coordinate, default 0
            zf: final z coordinate. if None, use the waveguide length
            mesh: an initial mesh (z=zi) if you don't want to use the auto-generated, default mesh
            tag: a string identifier which will be attached to any saved files
            save: set True to save function output (z values, effective indices, modes)

        RETURNS:
            (tuple) : a tuple containing:

                - zs: array of z coordinates
                - neffs: array of effective indices computed on zs; 0th axis is "z axis"
                - vs: eigenmodes computed on zs; 0th axis is "z axis"
                - cmats: coupling coefficients computed on zs; 0th axis is "z axis"


 propagate a launch wavefront, expressed in the basis of initial eigenmodes, to z = zf

        ARGS:
            u0: the launch field, expressed as mode amplitudes of the initial eigenmode basis.
            zi: the initial z coordinate corresponding to u0. if None, use the initial z value used in characterize().
            zf: the final z coordinate to propagate through to. if None, use the final z value used in characterize().

        RETURNS:
            (tuple): a tuple containing:
                - zs: the array of z values used by the ODE solver
                - u: the mode amplitudes of the wavefront, evaluated along za, with :math:`e^{i\\beta_j z}` phase factored *out*.
                - uf: the final mode amplitudes of the wavefront, with :math:`e^{i\\beta_j z}` phase factored *in*.


 apply :math:`e^{i \\beta_j z}` phase variation to the mode amplitude of eigenmode j
        with propagation constant :math:`\\beta_j`.

        ARGS:
            u: mode amplitude vector
            z: z coord. that u is evaluated at
            zi (opt.) the starting z coordinate to measure the change in phase from.


propagate a wavefront from the back of the waveguide to the front


 compute the effective refractive indices through a waveguide, using an adaptive step scheme. also saves interpolation functions to self.neffs_funcs

        ARGS:
            zi: initial z coordinate, default 0
            zf: final z coordinate. if None, use waveguide's length
            mesh: a mesh object if you don't want to use the auto-generated, default mesh
            tag: string identifier to attach to saved files for computation results (if saving)
            save: whether or not to save the computation results

        RETURNS:
            (tuple): a tuple containing:
                - zs: array of z coordinates
                - neffs: array of effective indices computed on zs


 compute the modes through the waveguide, using an adaptive stepping scheme. this requires
        greater accuracy in z than get_neffs() since mode shapes may change rapidly even if
        eigenvalues do not. stores initial mesh to self.mesh

        ARGS:
            zi: initial z coordinate, if None zi=0
            zf: final z coordinate. if None, zf is the waveguide length
            mesh: an initial mesh (z=zi) if you don't want to use the auto-generated, default mesh
            tag: a string identifier which will be attached to any saved files
            save: set True to save function output (z values, effective indices, modes)
            init_modes: an initial mode basis to use for the computation
        RETURNS:
            zs: array of z coordinates
            neffs: array of effective indices computed on zs
            vs:modes


 load an eigenmode basis from init_prop as the initial basis for
        this propagator's calculations.

        ARGS:
            init_prop (Propagator): the Propagator object to load modes from
            z (float,None): the z value of the modes to load from init_prop. if None,
            use the last z value in init_prop.zs .


 compute the coupling coefficient matrices.

        ARGS:
            zs: array of z values for the mode array (next arg). if None, use self.zs
            vs: array of eigenmodes. if None, use self.vs
            mesh: finite element mesh of the modes. if None, use self.mesh
            tag: a string identifier which will be attached to any saved files
            save: set True to save function output (z values, effective indices, modes)

        RETURNS:
            cmats: coupling coefficient matrices calculated at each z value


 alter the eigenmodes _v, assumed to be similar to v, so that they
        have consistent overall sign with v.


 compute the inner product (or overlap integral) between fields v1 & v2, which are on the same mesh.
            this requires mesh information, either by passing in the mesh explicitly or by
            passing in the B matrix. this is the matrix on the RHS of the generalized
            eigenvalue problem and can be calculated e.g. with wavesolve.FEsolver.construct_B()

            the inner product is v1.T * B * v2 , where * is matrix mul.


 load the z values, effective indices, mode profiles, coupling coefficients, and mesh points
        saved to files specified by <tag>.


 construct interpolation functions for coupling matrices and mode effective indices,
            loaded into self.cmats and self.neffs, which were computed on an array of z values self.zs.

        ARGS:
            zs (None or array): the z values to use for interpolation. if none, use self.zs
            make_neff (bool): set True to make effective interpolation function
            make_cmat (bool): set True to make coupling matrix interpolation function
            make_v (bool): set True to make eigenmode interpolation function


 compute the (N x N) change of basis matrix between the current N-dimensional eigenbasis at z and a new basis

        ARGS:
            newbasis: MxN array of N eigenmodes computed over M mesh points, which we want to expand in
            z: z coordinate at which the currently loaded eigenbasis should be evaluated
            u: (optional) Nx1 modal vector to express in new basis

        RETURNS:
            cob, _u : Nmax x Nmax change of basis matrix and the vector u in the new basis, if u was provided.


 compute the eigenbasis corresponding to "isolated" channels of the waveguide.
        this only makes sense for waveguides such as PhotonicLantern, Dicoupler, and Tricoupler.

        ARGS:
            z: z coordinate of eigenbasis. if None, this defaults to the end of the waveguide.

        RETURNS:
            (array): the new basis


 convert mode amplitude vector to basis of channel eigenmodes.
        this only makes sense if the waveguide has defined output channels
        (i.e. the waveguide must have the isolate() function).

        ARGS:
            uf: mode amplitude vector (phase factored *in*)
            z: z coordinate. if None, z is set to the last value of self.zs
        RETURNS:
            (vector): the vector of mode amplitudes in output channel basis.


 construct the finite element field corresponding to the modal vector u and the eigenbasis at z.

        ARGS:
            mode_amps: the modal vector expressing the field with :math:`e^{i\beta_j z}` phase oscillation factored out
            z: the z coordinate corresponding to mode_amps
            plot (opt.): set True to auto-plot the norm of the field.
            apply_phase (bool): whether the :math:`e^{i\\beta_j z}` phase factor
                                needs to be applied to mode_amps; default True.

        RETURNS:
            (array): the field evaluated on the mesh nodes.


 from a field, make a complex mode amplitude vector by decomposing the
        field into the currently loaded basis. kind of like the opposite of make_field().

        ARGS:
            field: the finite element field to decompose into mode amplitudes
            z: the z coordinate of field; default is the first value of self.zs, or 0 if self.zs is not found


 permute _w so that it matches w as close as possible.
        permute _v in the same way.


 used least-squares minimization to transform modes _v so that they match v. mutates _v

        ARGS:
            group: a list of mode indexes setting which modes are to be considered degenerate.
            v: the mode basis we want to match
            _v: the mode basis we want to transform. We are allowed to apply a unitary transformation over the
                modes specified by group.
            q (opt.): if not None, q is taken as the transformation matrix. if None, q is computed through lsq min.

        RETURNS:
            (tuple): a tuple containing:
                - v: the original mode basis
                - _v: the transformed mode basis
                - q: the change-of-basis matrix


 compute the transfer matrix M corresponding to propagation through
        the waveguide. propagation of a mode vector v is equivalent to Mv.

        ARGS:
            channel_basis (bool): set True to force the output basis of this matrix to
            be the waveguide channel basis.
            zi (float or None): initial z value of propagation; if None, use self.zs[0]
            zf (float or None): ifnal z value of propagation; if None, use self.zs[-1]
        RETURNS:
            (array): an Nmax x Nmax complex-valued transfer matrix.


 generate a mesh for the loaded waveguide according to class attributes.

        ARGS:
            writeto (str or None): set to a str (the filename) to write the mesh to file.


 make the mesh corresponding to the waveguide cross-section at z.

        ARGS:
            z: z coordinate for the mesh.

        RETURNS:
            (meshio mesh): the corresponding mesh at z.


 plot the complex-valued wavefront through the waveguide. there
        may be some graphical glitches. mesh lines will be visible (issue with
        matplotlib's tripcolor).

        ARGS:
            zs: array of z values
            us: array of mode amplitudes corresponding to the field at each z value
            zi: initial z value for the plot
            fig: a matplotlib figure; if None, one will be made
            ax: a matplotlib axis; if None, one will be made

        RETURNS:
            (matplotlib.widgets.slider): the slider object. a reference to the slider needs to be kept to prevent garbage collection from removing it.


plot the effective indices of the eigenmodes


 plot the difference between the effective index of each mode and that of the fundamental.

        ARGS:
            yscale (str): either "lin" for linear scale or "log" for logarithmic scale. this affects only the
            y axis.


 plot a real-valued finite element field, evaluated on the points of the mesh corresponding to the waveguide cross-section at z.

        ARGS:
            field: the finite element field to plot, e.g. the output of make_field() or an eigenmode (a row of self.vs)
            z: the z coordinate corresponding to field
            mesh (opt.): the mesh object defining the points that field is evaluated on. If None, a mesh will be auto-generated
            ax (opt.): a matplotlib axis where the plot should go. if not None, you will need to call matplotlib.pyplot.show() manually
            show_mesh (opt.): whether or not to draw the mesh in the plot


plot coupling coefficient matrix vs z values.


 plot mode powers against :math:`z`.

        ARGS:
            zs: array of :math:`z` values.
            us: array of mode amplitudes, e.g. from propagate(). the first axis corresponds to z.


 plot a complex-valued field evaluated a finite element mesh. this function is a little
        slow because it resamples <field> onto a grid.

        ARGS:
            field: the complex field to be plotted
            z: the z value along the waveguide corresponding to ``field``. alternatively, explicitly pass the next arg
            mesh: the finite element mesh corresponding to ``field``
            fig: matplotlib figure object to receive the plot; if None, one will be made
            ax: matplotlib figure axis object; if None, one will be made
            show_mesh: shows the edges of the FE mesh in the plot
            res: the field will be evaluated on a grid with side length ``res``.
            xlim (tuple): (xmin,xmax) values for the plot - useful if you want to zoom in on the field
            ylim (tuple): (ymin,ymax) values for the plot.


 plot a real-valued eigenmode of the waveguide, from modes saved in self.vs.
        this plot comes with a slider which controls the z value.

        ARGS:
            i: the index of the mode to be plotted (mode 0,1,2...)
            zi: starting z value for the plot
            fig: matplotlib figure object; if None, one will be made
            ax: matplotlib axis objects; if None, one will be made

        RETURNS:
            (matplotlib.widgets.slider): the slider object. a reference to the slider needs to be kept to prevent garbage collection from removing it.


Define initial conditions and other background quantities from params.ini file


you may insert a method that sends a mail to your email when done.


            returns a tuple of the coefficients l1...l5,phi0 that have been stored in
            txt format as "l1;l2;l3;l4;l5;l6;phi0"

            Parameters
            -----------
            string the string to parse

            Returns
            -----------
            a 5 element list [l1,l2,l3,l4,l5,l6,phi0] of floats after parsing


        This method solves the cosmic evolution problem, given a set of initial condtions,
        as well as an inflationary potential.

        Parameters
        ----------
        None

        Returns
        -------
        solution:
            Tuple of arrays in this format: [t,H,phi,phidot,v,vd,epsilon,ERROR,a,eta,xisq]
                        t:
                            the time variable used to integrate over.
                        H:
                            the Hubble parameter
                        phi:
                            the phi coordinate
                        phidot:
                            coordinate velocity
                        v:
                            the value of the potential as a function of time
                        vd:
                            the value of d(V)/d(phi) as a function of time
                        epsilon:
                            the quantity 1/2 *(V'/V)^2
                        ERROR:
                            if selfcheck is active, yields the error between full step
                            and two half step integrations
                        a:
                            the logarithm of the scale factor,this is actually log(a(t)) (=N)
                        eta:
                            the quantity (V''/V) as a function of time
                        xisq:
                            the quantity (V'*V'''/V^2) as a function of time


generating function for q


Truncate a, phi,phidot, H, t to the correct size


            this should be a loop that solves all the modes and fills
            a pre-made empty UKT,
            as well as the K array
            and timing array


            this should be a loop that solves all the modes and fills
            a pre-made empty UKT,
            as well as the K array
            and timing array

            NEED TO PARALLELIZE THIS!!!!


            first calculate the Wsq for this mode
            and interpolate it


Define slice timing


            Parameters
            ----------
            h5_filename : TYPE
                DESCRIPTION.
            Xencoder : TYPE
                DESCRIPTION.
            Yencoder : TYPE
                DESCRIPTION.
            data_set : TYPE
                DESCRIPTION.

            Returns
            -------
            None.


Simple metropolis hastings sampler.

    :param x0: Initial array of parameters.
    :param lnprob_fn: Function to compute log-posterior.
    :param prop_fn: Function to perform jumps.
    :param prop_fn_kwargs: Keyword arguments for proposal function
    :param iterations: Number of iterations to run sampler. Default=100000

    :returns:
        (chain, acceptance, lnprob) tuple of parameter chain , acceptance rate
        and log-posterior chain.


Fast Lomb Scargle to calculate the periodogram (Press & Ribicky 1989)


Multi sine fit function with all the parameters of frequencies, amplitudes, phases and mean floats


Reading the .fits file to extract all data


Choosing between the SNR or the FAP stop criterion.
       SNR by default


 Function to detect the combination frequencies once all of them
        having been extracted


MRMR feature selection for a classification task
    Parameters
    ----------
    X: pandas.DataFrame
        A DataFrame containing all the features.
    y: pandas.Series
        A Series containing the (categorical) target variable.
    K: int
        Number of features to select.
    features: list of str (optional, default=None)
        List of numeric column names. If not specified, all numeric columns (integer and float) are used.
    relevance: str or callable
        Relevance method.
        If string, name of method, supported: "f" (f-statistic), "ks" (kolmogorov-smirnov), "rf" (random forest).
        If callable, it should take "X" and "y" as input and return a pandas.Series containing a (non-negative)
        score of relevance for each feature.
    redundancy: str or callable
        Redundancy method.
        If string, name of method, supported: "c" (Pearson correlation).
        If callable, it should take "X", "target_column" and "features" as input and return a pandas.Series
        containing a score of redundancy for each feature.
    denominator: str or callable (optional, default='mean')
        Synthesis function to apply to the denominator of MRMR score.
        If string, name of method. Supported: 'max', 'mean'.
        If callable, it should take an iterable as input and return a scalar.
    cat_features: list (optional, default=None)
        List of categorical features. If None, all string columns will be encoded.
    cat_encoding: str
        Name of categorical encoding. Supported: 'leave_one_out', 'james_stein', 'target'.
    only_same_domain: bool (optional, default=False)
        If False, all the necessary correlation coefficients are computed.
        If True, only features belonging to the same domain are compared.
        Domain is defined by the string preceding the first underscore:
        for instance "cusinfo_age" and "cusinfo_income" belong to the same domain, whereas "age" and "income" don't.
    return_scores: bool (optional, default=False)
        If False, only the list of selected features is returned.
        If True, a tuple containing (list of selected features, relevance, redundancy) is returned.
    n_jobs: int (optional, default=-1)
        Maximum number of workers to use. Only used when relevance = "f" or redundancy = "corr".
        If -1, use as many workers as min(cpu count, number of features).
    show_progress: bool (optional, default=True)
        If False, no progress bar is displayed.
        If True, a TQDM progress bar shows the number of features processed.
    Returns
    -------
    selected_features: list of str
        List of selected features.


MRMR feature selection for a regression task
    Parameters
    ----------
    X: pandas.DataFrame
        A DataFrame containing all the features.
    y: pandas.Series
        A Series containing the (categorical) target variable.
    K: int
        Number of features to select.
    features: list of str (optional, default=None)
        List of numeric column names. If not specified, all numeric columns (integer and float) are used.
    relevance: str or callable
        Relevance method.
        If string, name of method, supported: "f" (f-statistic), "rf" (random forest).
        If callable, it should take "X" and "y" as input and return a pandas.Series containing a (non-negative)
        score of relevance for each feature.
    redundancy: str or callable
        Redundancy method.
        If string, name of method, supported: "c" (Pearson correlation).
        If callable, it should take "X", "target_column" and "features" as input and return a pandas.Series
        containing a score of redundancy for each feature.
    denominator: str or callable (optional, default='mean')
        Synthesis function to apply to the denominator of MRMR score.
        If string, name of method. Supported: 'max', 'mean'.
        If callable, it should take an iterable as input and return a scalar.
    cat_features: list (optional, default=None)
        List of categorical features. If None, all string columns will be encoded.
    cat_encoding: str
        Name of categorical encoding. Supported: 'leave_one_out', 'james_stein', 'target'.
    only_same_domain: bool (optional, default=False)
        If False, all the necessary correlation coefficients are computed.
        If True, only features belonging to the same domain are compared.
        Domain is defined by the string preceding the first underscore:
        for instance "cusinfo_age" and "cusinfo_income" belong to the same domain, whereas "age" and "income" don't.
    return_scores: bool (optional, default=False)
        If False, only the list of selected features is returned.
        If True, a tuple containing (list of selected features, relevance, redundancy) is returned.
    n_jobs: int (optional, default=-1)
        Maximum number of workers to use. Only used when relevance = "f" or redundancy = "corr".
        If -1, use as many workers as min(cpu count, number of features).
    show_progress: bool (optional, default=True)
        If False, no progress bar is displayed.
        If True, a TQDM progress bar shows the number of features processed.
    Returns
    -------
    selected_features: list of str
        List of selected features.


Compute F-statistic of some variables across groups

    Compute F-statistic of many variables, with respect to some groups of instances.
    For each group, the input consists of the simple average, variance and count with respect to each variable.

    Parameters
    ----------
    avg: pandas.DataFrame of shape (n_groups, n_variables)
        Simple average of variables within groups. Each row is a group, each column is a variable.

    var: pandas.DataFrame of shape (n_groups, n_variables)
        Variance of variables within groups. Each row is a group, each column is a variable.

    n: pandas.DataFrame of shape (n_groups, n_variables)
        Count of instances for whom variable is not null. Each row is a group, each column is a variable.

    Returns
    -------
    f: pandas.Series of shape (n_variables, )
        F-statistic of each variable, based on group statistics.

    Reference
    ---------
    https://en.wikipedia.org/wiki/F-test


General function for mRMR algorithm.

    Parameters
    ----------
    K: int
        Maximum number of features to select. The length of the output is *at most* equal to K

    relevance_func: callable
        Function for computing Relevance.
        It must return a pandas.Series containing the relevance (a number between 0 and +Inf)
        for each feature. The index of the Series must consist of feature names.

    redundancy_func: callable
        Function for computing Redundancy.
        It must return a pandas.Series containing the redundancy (a number between -1 and 1,
        but note that negative numbers will be taken in absolute value) of some features (called features)
        with respect to a variable (called target_variable).
        It must have *at least* two parameters: "target_variable" and "features".
        The index of the Series must consist of feature names.

    relevance_args: dict (optional, default={})
        Optional arguments for relevance_func.

    redundancy_args: dict (optional, default={])
        Optional arguments for redundancy_func.

    denominator_func: callable (optional, default=numpy.mean)
        Synthesis function to apply to the denominator of MRMR score.
        It must take an iterable as input and return a scalar.

    only_same_domain: bool (optional, default=False)
        If False, all the necessary redundancy coefficients are computed.
        If True, only features belonging to the same domain are compared.
        Domain is defined by the string preceding the first underscore:
        for instance "cusinfo_age" and "cusinfo_income" belong to the same domain, whereas "age" and "income" don't.

    return_scores: bool (optional, default=False)
        If False, only the list of selected features is returned.
        If True, a tuple containing (list of selected features, relevance, redundancy) is returned.

    show_progress: bool (optional, default=True)
        If False, no progress bar is displayed.
        If True, a TQDM progress bar shows the number of features processed.

    Returns
    -------
    selected_features: list of str
        List of selected features.


    Propogates light complex amplitude using an angular spectrum algorithm

    Parameters:
        inputComplexAmp (ndarray): Complex array of input complex amplitude
        wvl (float): Wavelength of light to propagate
        inputSpacing (float): The spacing between points on the input array in metres
        outputSpacing (float): The desired spacing between points on the output array in metres
        z (float): Distance to propagate in metres

    Returns:
        ndarray: propagated complex amplitude


    Fresnel propagation using a one step Fresnel propagation method.

    Parameters:
        Uin (ndarray): A 2-d, complex, input array of complex amplitude
        wvl (float): Wavelength of propagated light in metres
        d1 (float): spacing of input plane
        z (float): metres to propagate along optical axis

    Returns:
        ndarray: Complex ampltitude after propagation


    Fresnel propagation using a two step Fresnel propagation method.

    Parameters:
        Uin (ndarray): A 2-d, complex, input array of complex amplitude
        wvl (float): Wavelength of propagated light in metres
        d1 (float): spacing of input plane
        d2 (float): desired output array spacing
        z (float): metres to propagate along optical axis

    Returns:
        ndarray: Complex ampltitude after propagation


    Propagates from the pupil plane to the focal
    plane for an object placed against (and just before)
    a lens.

    Parameters:
        Uin (ndarray): Input complex amplitude
        wvl (float): Wavelength of light in metres
        d1 (float): spacing of input plane
        f (float): Focal length of lens

    Returns:
        ndarray: Output complex amplitude


    A Class to zoom 2-dimensional arrays using interpolation

    Uses the scipy `Interp2d` interpolation routine to zoom into an array. Can cope with real of complex data.

    Parameters:
        array (ndarray): 2-dimensional array to zoom
        newSize (tuple): the new size of the required array
        order (int, optional): Order of interpolation to use (1, 3, 5). default is 3

    Returns:
        ndarray : zoom array of new size.


    A Class to zoom 2-dimensional arrays using RectBivariateSpline interpolation

    Uses the scipy ``RectBivariateSpline`` interpolation routine to zoom into an array. Can cope with real of complex data. May be slower than above ``zoom``, as RBS routine copies data.

    Parameters:
        array (ndarray): 2-dimensional array to zoom
        newSize (tuple): the new size of the required array
        order (int, optional): Order of interpolation to use. default is 3

    Returns:
        ndarray : zoom array of new size.


    Bins one or more images down by the given factor
    bins. n must be a factor of data.shape, who knows what happens
    otherwise......


    A properly scaled 1-D FFT

    Parameters:
        data (ndarray): An array on which to perform the FFT
        delta (float): Spacing between elements

    Returns:
        ndarray: scaled FFT


    Scaled inverse 1-D FFT

    Parameters:
        data (ndarray): Data in Fourier Space to transform
        delta_f (ndarray): Frequency spacing of grid

    Returns:
        ndarray: Scaled data in real space


    A properly scaled 2-D FFT

    Parameters:
        data (ndarray): An array on which to perform the FFT
        delta (float): Spacing between elements

    Returns:
        ndarray: scaled FFT


    Scaled inverse 2-D FFT

    Parameters:
        data (ndarray): Data in Fourier Space to transform
        delta_f (ndarray): Frequency spacing of grid

    Returns:
        ndarray: Scaled data in real space


    A properly scaled real 1-D FFT

    Parameters:
        data (ndarray): An array on which to perform the FFT
        delta (float): Spacing between elements

    Returns:
        ndarray: scaled FFT


    Scaled real inverse 1-D FFT

    Parameters:
        data (ndarray): Data in Fourier Space to transform
        delta_f (ndarray): Frequency spacing of grid

    Returns:
        ndarray: Scaled data in real space


    A properly scaled, real 2-D FFT

    Parameters:
        data (ndarray): An array on which to perform the FFT
        delta (float): Spacing between elements

    Returns:
        ndarray: scaled FFT


    Scaled inverse real 2-D FFT

    Parameters:
        data (ndarray): Data in Fourier Space to transform
        delta_f (ndarray): Frequency spacing of grid

    Returns:
        ndarray: Scaled data in real space


Calculates the seperations between the phase points in the stencil and the new phase vector


Makes the covariance matrices required for adding new phase


        Calculates the "A" matrix, that uses the existing data to find a new
        component of the new phase vector.


Calculates the "B" matrix, that turns a random vector into a component of the new phase.


Makes the initial screen usign FFT method that can be extended


Adds a new row to the phase screen and removes old ones.


The current phase map held in the PhaseScreen object in radians.


    Finds the next largest "allowed size" for the Fried Phase Screen method

    Parameters:
        nx_size (int): Requested size

    Returns:
        int: Next allowed size


    Calculates the temporal power spectra of the loaded centroid data.

    Calculates the Fourier transform over the number frames of the centroid
    data, then returns the square of the  mean of all sub-apertures, for x
    and y. This is a temporal power spectra of the slopes, and should adhere
    to a -11/3 power law for the slopes in the wind direction, and -14/3 in
    the direction tranverse to the wind direction. See Conan, 1995 for more.

    The phase slope data should be split into X and Y components, with all X data first, then Y (or visa-versa).

    Parameters:
        slope_data (ndarray): 2-d array of shape (..., nFrames, nCentroids)

    Returns:
        ndarray: The temporal power spectra of the data for X and Y components.


    Generates a plot of the temporal power spectrum/a for a data set of phase gradients

    Parameters:
        slope_data (ndarray):  2-d array of shape (..., nFrames, nCentroids)
        frame_rate (float): Frame rate of detector observing slope gradients (Hz)

    Returns:
        tuple: The computed temporal power spectrum/a, and the time axis data


    Runs minimization routines to get t0.

    Parameters:
        tps (ndarray): The temporal power spectrum to fit
        axis (str): fit parallel ('par') or perpendicular ('per') to wind direction
        D (float): (Sub-)Aperture diameter

    Returns:


    Calculate the phase covariance between two points seperated by `r`,
    in turbulence with a given `r0 and `L0`.
    Uses equation 5 from Assemat and Wilson, 2006.

    Parameters:
        r (float, ndarray): Seperation between points in metres (can be ndarray)
        r0 (float): Fried parameter of turbulence in metres
        L0 (float): Outer scale of turbulence in metres


        Calculate and build the covariance matrix

        Returns:
            ndarray: Covariance Matrix


    Calculates the covariance between 2 WFSs

    Parameters:
        n_subaps1 (int): number of sub-apertures in WFS 1
        n_subaps2 (int): number of sub-apertures in WFS 1
        wfs1_positions (ndarray): Central position of each sub-apeture from telescope centre for WFS 1
        wfs2_positions (ndarray): Central position of each sub-apeture from telescope centre for WFS 2
        wfs1_diam: Diameter of WFS 1 sub-apertures
        wfs2_diam: Diameter of WFS 2 sub-apertures
        r0: Fried parameter of turbulence
        L0: Outer scale of turbulence

    Returns:
        slope covariance of X with X , slope covariance of Y with Y, slope covariance of X with Y


    Calculates the seperation between all sub-apertures in two WFSs

    Parameters:
        n_subaps1 (int): Number of sub-apertures in WFS 1
        n_subaps2 (int): Number of sub-apertures in WFS 2
        wfs1_positions (ndarray): Array of the X, Y positions of the centre of each sub-aperture with respect to the centre of the telescope pupil
        wfs2_positions (ndarray): Array of the X, Y positions of the centre of each sub-aperture with respect to the centre of the telescope pupil

    Returns:
        ndarray: 2-D Array of sub-aperture seperations


    Computes the Von Karmon structure function of atmospheric turbulence

    Parameters:
        seperation (ndarray, float): float or array of data representing seperations between points
        r0 (float): Fried parameter for atmosphere
        L0 (float): Outer scale of turbulence

    Returns:
        ndarray, float: Structure function for seperation(s)


        Compute the Kolmogorov phase structure function

        Parameters:
            separation (ndarray, float): float or array of data representing
                separations between points
            r0 (float): Fried parameter for atmosphere

        Returns:
            ndarray, float: Structure function for separation(s)


        Compute the structure function of an 2D array, along the first dimension.
        SF defined as sf[j]= < (phase - phase_shifted_by_j)^2 >
        Translated from a YAO function.

        Parameters:
            phase (ndarray, 2d): 2d-array
            nbOfPoint (int): final size of the structure function vector. Default is phase.shape[1] / 4
            step (int): step in pixel when computing the sf. (step * sampling_phase) gives the sf sampling in meters. Default is 1

        Returns:
            ndarray, float: values for the structure function of the data.


    Mirrors a covariance matrix around the axis of the diagonal.

    Parameters:
        cov_mat (ndarray): The covariance matrix to mirror
        n_subaps (ndarray): Number of sub-aperture in each WFS


    Creates a random phase screen with Von Karmen statistics with added
    sub-harmonics to augment tip-tilt modes.
    (Schmidt 2010)

    .. note::
        The phase screen is returned as a 2d array, with each element representing the phase
        change in **radians**. This means that to obtain the physical phase distortion in nanometres,
        it must be multiplied by (wavelength / (2*pi)), (where `wavellength` here is the same wavelength
        in which r0 is given in the function arguments)

    Args:
        r0 (float): r0 parameter of scrn in metres
        N (int): Size of phase scrn in pxls
        delta (float): size in Metres of each pxl
        L0 (float): Size of outer-scale in metres
        l0 (float): inner scale in metres
        seed (int, optional): seed for random number generator. If provided,
            allows for deterministic screens

    Returns:
        ndarray: numpy array representing phase screen in radians


    Creates a random phase screen with Von Karmen statistics.
    (Schmidt 2010)

    Parameters:
        r0 (float): r0 parameter of scrn in metres
        N (int): Size of phase scrn in pxls
        delta (float): size in Metres of each pxl
        L0 (float): Size of outer-scale in metres
        l0 (float): inner scale in metres
        seed (int, optional): seed for random number generator. If provided,
            allows for deterministic screens

    .. note::
        The phase screen is returned as a 2d array, with each element representing the phase
        change in **radians**. This means that to obtain the physical phase distortion in nanometres,
        it must be multiplied by (wavelength / (2*pi)), (where `wavellength` here is the same wavelength
        in which r0 is given in the function arguments)

    Returns:
        ndarray: numpy array representing phase screen in radians


    Wrapper for inverse fourier transform

    Parameters:
        G: data to transform
        delta_f: pixel seperation
        FFT (FFT object, optional): An accelerated FFT object


    Equivalent layers method of profile compression (Fusco 1999).

    Splits the profile into L "slabs", then sets the height of each slab as the
    effective height ((integral cn2(h) * h^{5/3} dh) / integral cn2(h) dh)^(3/5)
    and the cn2 as the sum of cn2 in that slab.

    Can also provide wind speed per layer, in which case the wind speeds are calculated
    per layer in a similar fashion ((integral cn2(h) * w^{5/3} dh) / integral cn2(h) dh)^(3/5)
    for wind speed w. This conserves coherence time as well as isoplanatic angle.

    Parameters
        h (numpy.ndarray): heights of input profile layers
        p (numpy.ndarray): cn2dh values of input profile layers
        L (int): number of layers to compress down to
        w (numpy.ndarray, optional): wind speeds of input profile layers

    Returns
        h_L (numpy.ndarray): compressed profile heights
        cn2_L (numpy.ndarray): compressed profile cn2dh per layer
        w (numpy.ndarray, optional): compressed profile wind speed per layer


    Python implementation of algorithm 2 from Saxenhuber et al (2017). Performs the
    "optimal grouping" algorithm , which finds the grouping that minimises the
    cost function given in Eq. 7 of that paper.

    Parameters
        R (int): number of random starting groupings (recommended 10?)
        L (int): number of layers to compress down to
        h (numpy.ndarray): input profile heights
        p (numpy.ndarray): input profile cn2dh per layer

    Returns
        h_L (numpy.ndarray): compressed profile heights
        cn2_L (numpy.ndarray): compressed profile cn2dh per layer


    Generalised Conservation of Turbulence Moments compression method, from
    Saxenhuber et al 2017. This compresses the profile whilst conserving 2L-1
    moments of the profile, where a moment N is ((integral cn2(h) h^N)/integral cn2(h))^{1/N}.

    Parameters
        h (numpy.ndarray): heights of input profile layers
        p (numpy.ndarray): cn2dh values of input profile layers
        L (int): number of layers to compress down to
        h_scaling[optional] (float): scaling of heights to avoid overflow
        cn2_scaling[optional] (float): scaling of cn2 values to avoid overflow

    Returns
        h_L (numpy.ndarray): compressed profile heights
        cn2_L (numpy.ndarray): compressed profile cn2


Creates a random grouping of N elements into L groups


Calculate the vicinity of a grouping, see Saxenhuber (2017)


Convert indices of splits into explicit groupings


Optimal Grouping cost function (slow version)


Optimal Grouping cost function (fast numba version)


Minimisation of G


Generalised turbulence moments function for GCTM


    Minimisation function for GCTM. Minimises the sum of square difference between
    2L-1 moments (see Saxenhuber et al 2017).


    Calculates the seeing angle from the integrated Cn2 value

    Parameters:
        cn2 (float): integrated Cn2 value in m^2/3
        lamda : wavelength

    Returns:
        seeing angle in arcseconds


    Calculates the integrated Cn2 value from the seeing

    Parameters:
        seeing (float): seeing in arcseconds
        lamda : wavelength

    Returns:
        integrated Cn2 value in m^2/3


    Calculates r0 from the integrated Cn2 value

    Parameters:
        cn2 (float): integrated Cn2 value in m^2/3
        lamda : wavelength

    Returns:
        r0 in m


    Calculates integrated Cn2 value from r0

    Parameters:
        r0 (float): r0 in m
        lamda : wavelength

    Returns:
        cn2 (float): integrated Cn2 value in m^2/3


    Calculates the seeing angle from r0

    Parameters:
        r0 (float): Freid's parameter in m
        lamda : wavelength

    Returns:
        seeing angle in arcseconds


    Calculates r0 from seeing

    Parameters:
        seeing (float): seeing angle in arcseconds
        lamda : wavelength

    Returns:
        r0 (float): Freid's parameter in cm


    Calculates the coherence time from profiles of the Cn2 and wind velocity

    Parameters:
        cn2 (array): Cn2 profile in m^2/3. >1D arrays are supported (i.e. multiple
            profiles), in which case the default assumption is that the turbulent
            layers are along the final (-1) axis.
        v (array): profile of wind velocity, same altitude scale as cn2
        lamda : wavelength
        axis (int, optional): axis over which to integrate (for >1D inputs)

    Returns:
        coherence time in seconds


    Calculates the isoplanatic angle from the Cn2 profile

    Parameters:
        cn2 (array): Cn2 profile in m^2/3.  >1D arrays are supported (i.e. multiple
            profiles), in which case the default assumption is that the turbulent
            layers are along the final (-1) axis.
        h (Array): Altitude levels of cn2 profile in m
        lamda : wavelength
        axis (int, optional): axis over which to integrate (for >1D inputs)

    Returns:
        isoplanatic angle in arcseconds


    Calculates plane wave Rytov variance from the Cn2 profile

    Parameters:
        cn2 (numpy.ndarray): Cn2 profile in m^2/3.  >1D arrays are supported (i.e. multiple
            profiles), in which case the default assumption is that the turbulent
            layers are along the final (-1) axis.
        h (numpy.ndarray): Altitude levels of cn2 profile in m
        lamda (float, optional): wavelength, default 500 nm
        axis (int, optional): axis over which to integrate (for >1D inputs)

    Returns:
        Rytov variance (float)


    Measures the value of R0 from a set of WFS slopes.

    Uses the equation in Saint Jaques, 1998, PhD Thesis, Appendix A to calculate the value of atmospheric seeing parameter, r0, that would result in the variance of the given slopes.

    Parameters:
        slopes (ndarray): A 3-d set of slopes in radians, of shape (dimension, nSubaps, nFrames)
        wavelength (float): The wavelegnth of the light observed
        subapDiam (float) The diameter of each sub-aperture

    Returns:
        float: An estimate of r0 for that dataset.


    Uses the equation in Saint Jaques, 1998, PhD Thesis, Appendix A to calculate the slope variance resulting from a
    value of r0.

    Parameters:
        r0 (float): Fried papamerter of turubulence in metres
        wavelength (float): Wavelength of light in metres (where 1e-9 is 1nm)
        subapDiam (float): Diameter of the aperture in metres

    Returns:
        The expected slope variance for a given r0 ValueError


    Finds the subapertures which are "seen" be through the
    pupil function. Returns the coords of those subapertures

    Parameters:
        subaps (int): The number of subaps in x (assumes square)
        mask (ndarray): A pupil mask, where is transparent when 1, and opaque when 0
        threshold (float): The mean value across a subap to make it "active"
        returnFill (optional, bool): Return an array of fill-factors

    Returns:
        ndarray: An array of active subap coords


    Calculate the fill factor of a set of sub-aperture co-ordinates with a given
    pupil mask.

    Parameters:
        mask (ndarray): Pupil mask
        subapPos (ndarray): Set of n sub-aperture co-ordinates (n, 2)
        subapSpacing: Number of mask pixels between sub-apertures

    Returns:
        list: fill factor of sub-apertures


    Fills in a pupil shape with 2-d sub-apertures

    Parameters:
        data (ndarray): slope data, of shape, (frames, 2, nSubaps)
        mask (ndarray): 2-d array of shape (nxSubaps, nxSubaps), where 1 indicates a valid subap position and 0 a masked subap


    Calculates the 'Michelson' contrast.

    Uses a method by Michelson (Michelson, A. (1927). Studies in Optics. U. of Chicago Press.), to calculate the contrast ratio of an image. Uses the formula:
        (img_max - img_min)/(img_max + img_min)

    Parameters:
        image (ndarray): Image array

    Returns:
        float: Contrast value


    Calculates the RMS contrast - basically the standard deviation of the image

    Parameters:
        image (ndarray): Image array

    Returns:
        float: Contrast value


    Correlation Centroider, currently only works for 3d im shape.
    Performs a simple thresholded COM on the correlation.

    Args:
        im: sub-aperture images (t, y, x)
        ref: reference image (y, x)
        threshold: fractional threshold for COM (0=all pixels, 1=brightest pixel)
        padding: factor to zero-pad arrays in Fourier transforms
    Returns:
        ndarray: centroids of im (2, t), given in order x, y


    Centroids an image, or an array of images.
    Centroids over the last 2 dimensions.
    Sets all values under "threshold*max_value" to zero before centroiding
    Origin at 0,0 index of img.

    Parameters:
        img (ndarray): ([n, ]y, x) 2d or greater rank array of imgs to centroid
        threshold (float): Percentage of max value under which pixels set to 0

    Returns:
        ndarray: Array of centroid values (2[, n])


    2D convolution using FFT, use to generate cross-correlations.

    Args:
        x (array): subap image
        y (array): reference image
        padding (int): Factor to zero-pad arrays in Fourier transforms
    Returns:
        ndarray: cross-correlation of x and y


    Centroider to be used for 2x2 images.

    Parameters:
        img: 2d or greater rank array, where centroiding performed over last 2 dimensions

    Returns:
        ndarray: Array of centroid values


    Measure the azimuthal average of a 2d array

    Args:
        data (ndarray): A 2-d array of data

    Returns:
        ndarray: A 1-d vector of the azimuthal average


        Return the encircled energy diameter for a given fraction
        (default is ee50d).
        Can also return the encircled energy function.
        Translated and extended from YAO.

        Parameters:
            data : 2-d array
            fraction : energy fraction for diameter calculation
                default = 0.5
            center : default = center of image
            eeDiameter : toggle option for return.
                If False returns two vectors: (x, ee(x))
                Default = True
        Returns:
            Encircled energy diameter
            or
            2 vectors: diameters and encircled energies


    Generates 2D gaussian distribution

    Args:
        size (tuple, float): Dimensions of Array to place gaussian (y, x)
        width (tuple, float): Width of distribution.
                                Accepts tuple for x and y values in order (y, x).
        amplitude (float, optional): Amplitude of guassian distribution. default is 1.
        cent (tuple, optional): Centre of distribution on grid in order (y, x). Default is middle


Rebin an array to a new shape.
    See scipy cookbook.
    It is intended to be similar to 'rebin' of IDL


Kolmogorov structure function with r = (D/r0)


        von Karman structure function with r = (D / r0)
        L0 is in unit of telescope diameter, typically a few (3; or 20m)


    Generate n points evenly spaced in r^2 between r_i^2 and 1

    Parameters
    -----------
        nr : int
            number of resolution elements
        ri : float
            radius of central obscuration radius (normalized; <1)

    Returns
    -------
        r: 1d-array, float
            grid of point to calculate the appropriate kernels.
            correspond to 'sqrt(s)' wrt the paper.


    Calculation of the kernel L^p

    The kernel constructed here should be simply a discretization
    of the continuous kernel.
    It needs rescaling before it is treated as a matrix for finding
    the eigen-values

    Parameters
    ----------
        ri : float
            radius of central obscuration radius (normalized by D/2; <1)
        nr : int
            number of resolution elements
        rad : 1d-array
            grid of points where the kernel is evaluated
        stfunc : string
            string tag of the structure function on which the kernel are
            computed
        outerscale : float
            in unit of telescope diameter.
            Outer-scale for von Karman structure function.

    Returns
    -------
        L^p : ndarray
            kernel L^p of dimension (nr, nr, nth), where nth is the
            azimuthal discretization (5 * nr)


    Unitary matrix used to filter out piston term.
    Eq. 19 in Cannon 1996.

    Parameters
    ----------
    nr : int
        number of resolution elements

    Returns
    -------
    U : 2d array
        Unitary matrix


    Computation of the radial eigenvectors of the KL basis.

    Obtained by taking the eigenvectors from the matrix L^p.
    The final function corresponds to the 'nfunc' largest eigenvalues.
    See eq. 16-18 in Cannon 1996.

    Parameters
    ----------
        ri : float
            radius of central obscuration radius (normalized by D/2; <1)
        kernels : ndarray
            kernel L^p of dimension (nr, nr, nth), where nth is the
            azimuthal discretization (5 * nr)
        nfunc : int
            number of final KL functions
    Returns
    -------
        evals : 1darray
            eigenvalues
        nord : int
            resulting number of azimuthal orders
        npo : int
        ord : 1darray
        rabas : ndarray
            radial eigenvectors of the KL basis


    Compute the azimuthal function of the KL basis.

    Parameters
    ----------
        nord : int
            number of azimuthal orders
        npp : int
            grid of point sampling the azimuthal coordinate
    Returns
    -------
        gklazi: ndarray
            azimuthal function of the KL basis.


    Wrapper to create the radial and azimuthal K-L functions.

    Parameters
    ----------
        ri : float
            normalized internal radius
        nr : int
            number of radial resolution elements
        np : int
            number of azimuthal resolution elements
        nfunc : int
            number of generated K-L function
        stf : string
            structure function tag describing the atmospheric statistics
    Returns
    -------
        gklbasis: dic
            dictionary containing the radial and azimuthal basis + other
            relevant information


    return the i'th function from the generalized KL basis 'bas'.
    'bas' must be generated by 'gkl_basis'


    Use to generate a polar coordinate system.

    Generate an nr x npp array with npp copies of the radial coordinate
    array.
    Radial coordinate span the range from r=ri to r=1 with
    successive annuli having equal areas.

    ie, the area between ri and 1 is divided into nr equal rings, and
    the points are positioned at the half-area mark on each ring;
    there are no points on the border

    see also
    --------
    polang


        Generate an array with the same dimensions as r, but containing the
        azimuthal values for a polar coordinate system.


    This routine builds a geom dic.

    Parameters
    ----------
        px, py : int
            the x, y coordinates of points in the polar arrays.
        cr, cp :
            the r, phi coordinates of points in the cartesian grids.
        ncmar :
            allows the possibility that there is a margin of ncmar points in the
            cartesian arrays outside the region of interest.


    Polar to cartesian conversion.

    (points not in the aperture are treated as though they were at
    the first or last radial polar value...)


    Main routine to generatre a KL basis of dimension [nmax, dim, dim].

    For Kolmogorov statistics, e.g. ::

        kl, _, _, _ = make_kl(150, 128, ri = 0.2, stf='kolmogorov')

    | As a rule of thumb
    |     nr x npp = 50 x 250 is fine up to 500 functions
    |     60 x 300 for a thousand
    |     80 x 400 for three thousands.

    Parameters
    ----------
    nmax : int
        number of KL function to generate
    dim : int
        size of the KL arrays
    ri : float
        radial central obscuration normalized by D/2
    nr : int
        number of point on radius. npp (number of azimuthal pts) is  =2 pi * nr
    stf : string
        structure function tag. Default is 'kolmogorov'
    outerscale : float
        outer scale in units of telescope diameter. Releveant if von vonKarman
        stf. (not implemented yet)
    mask : bool
        pupil masking. Default is True

    Returns
    -------
    kl : ndarray (nmax, dim, dim)
        KL basis in cartesian coordinates
    varKL : 1darray
        associated variance
    pupil : 2darray
        pupil
    polar_base : dictionary
        polar base dictionary used for the KL basis computation.
        as returned by 'gkl_basis'

    SEE ALSO
    --------
    gkl_basis, set_pctr, pol2car


        Get values of circular (standard) Zernike polynomials.

        Return: zern_value


        Calculate elliptical orthonormal polynomials as a product of the conversion matrix and circular zernike polynomials.

        Return: E


        Calculate the conversion matrix.

        Return: M


        Calculate C_zern matrix which is a symmetric matrix of inner products of Zernike polynomials
        over the domain of a noncircular pupil (elliptical).

        Return: C


        Generate a wavefront map on an elliptical pupil.
        Parameters:
        coeff (array): coefficients for the polynomial terms. Must be the same length as the number of elliptical modes.

        Return: phi


    Create a 2-D array: elements equal 1 within a circle and 0 outside.

    The default centre of the coordinate system is in the middle of the array:
    circle_centre=(0,0), origin="middle"
    This means:
    if size is odd  : the centre is in the middle of the central pixel
    if size is even : centre is in the corner where the central 4 pixels meet

    origin = "corner" is used e.g. by psfAnalysis:radialAvg()

    Examples: ::

        circle(1,5) circle(0,5) circle(2,5) circle(0,4) circle(0.8,4) circle(2,4)
          00000       00000       00100       0000        0000          0110
          00100       00000       01110       0000        0110          1111
          01110       00100       11111       0000        0110          1111
          00100       00000       01110       0000        0000          0110
          00000       00000       00100

        circle(1,5,(0.5,0.5))   circle(1,4,(0.5,0.5))
           .-->+
           |  00000               0000
           |  00000               0010
          +V  00110               0111
              00110               0010
              00000

    Parameters:
        radius (float)       : radius of the circle
        size (int)           : size of the 2-D array in which the circle lies
        circle_centre (tuple): coords of the centre of the circle
        origin (str)  : where is the origin of the coordinate system
                               in which circle_centre is given;
                               allowed values: {"middle", "corner"}

    Returns:
        ndarray (float64) : the circle array


    Creates an array of the sum of zernike polynomials with specified coefficeints

    Parameters:
        zCoeffs (list): zernike Coefficients
        size (int): Diameter of returned array
        norm (string, optional): The normalisation of Zernike modes. Can be ``"noll"``, ``"p2v"`` (peak to valley), or ``"rms"``. default is ``"noll"``.
        rot (float) : Rotates the Zernike mode by rot radians around its centre. Defaults to zero.
    Returns:
        ndarray: a `size` x `size` array of summed Zernike polynomials


     Creates the Zernike polynomial with mode index j,
     where j = 1 corresponds to piston.

     Args:
        j (int): The noll j number of the zernike mode
        N (int): The diameter of the zernike more in pixels
        rot (float): Rotates the Zernike mode by rot radians around its centre. Defaults to zero.
     Returns:
        ndarray: The Zernike mode


     Creates the Zernike polynomial with radial index, n, and azimuthal index, m.

     Args:
        n (int): The radial order of the zernike mode
        m (int): The azimuthal order of the zernike mode
        N (int): The diameter of the zernike more in pixels
        rot (float): Rotates the zernike by rot radians around its centre. Defaults to 0.
     Returns:
        ndarray: The Zernike mode


    Fucntion to calculate the Zernike radial function

    Parameters:
        n (int): Zernike radial order
        m (int): Zernike azimuthal order
        r (ndarray): 2-d array of radii from the centre the array

    Returns:
        ndarray: The Zernike radial function


    Find the [n,m] list giving the radial order n and azimuthal order
    of the Zernike polynomial of Noll index j.

    Parameters:
        j (int): The Noll index for Zernike polynomials

    Returns:
        list: n, m values


    Creates an array of Zernike Polynomials

    Parameters:
        maxJ (int or list): Max Zernike polynomial to create, or list of zernikes J indices to create
        N (int): size of created arrays
        norm (string, optional): The normalisation of Zernike modes. Can be ``"noll"``, ``"p2v"`` (peak to valley), or ``"rms"``. default is ``"noll"``.
        rot (float): Rotates the zernike modes by rot radians around their centre. Defaults to 0.

    Returns:
        ndarray: array of Zernike Polynomials


    Make "Gamma" matrices which can be used to determine first derivative
    of Zernike matrices (Noll 1976).

    Parameters:
        nzrad: Number of Zernike radial orders to calculate Gamma matrices for

    Return:
        ndarray: Array with x, then y gamma matrices


    Calculates the photon flux for a given aperture, star magnitude and wavelength band

    Parameters:
        mag (float): Star apparent magnitude
        mask (ndarray): 2-d pupil mask array, 1 is transparent, 0 opaque
        pixel_scale (float): size in metres of each pixel in mask
        wvlBand (float): length of wavelength band in nanometres
        exposure_time (float): Exposure time in seconds

    Returns:
        float: number of photons


        Calculates the photon flux for a given aperture, star magnitude and wavelength band

        Parameters:
            mag (float): Star apparent magnitude
            mask (ndarray): 2-d pupil mask array, 1 is transparent, 0 opaque
            pxlScale (float): size in metres of each pixel in mask
            expTime (float): Exposure time in seconds
            waveband (string): Waveband

        Returns:
            float: number of photons


    Converts apparent magnitude to a flux of photons

    Parameters:
        magnitude (float): Star apparent magnitude
        waveband (string): Waveband of the stellar magnitude, can be U, B, V, R, I, J, H, K, g, r, i, z

    Returns:
        float: Number of photons emitted by the object per second per meter squared


    Converts incident flux of photons to the apparent magnitude

    Parameters:
        flux (float): Number of photons received from an object per second per meter squared
        waveband (string): Waveband of the measured flux, can be U, B, V, R, I, J, H, K, g, r, i, z

    Returns:
        float: Apparent magnitude


Compute the IR-filters X and Y.


Compute the spherical Bessel transform in the IR correction of order n given [XY]^n


 Given a correlation function cf,
            - if fullresum, return cf
            - if optiresum, extract the BAO peak


Compute the bulk coefficients Q^{ll'}_{||N-j}(n, \alpha, f)


Compute the IR corrections in configuration space by spherical Bessel transforming the IR corrections in Fourier space.


Perform IR-resummation for both power spectrum and correlation function.

        This is the main method that applies IR-resummation to both the power spectrum
        and correlation function, handling the bulk flow effects on the BAO feature.

        Parameters
        ----------
        bird : Bird
            Bird object containing the power spectrum and correlation function
        makeIR : bool, optional
            Whether to compute IR-resummed power spectrum, by default True
        makeQ : bool, optional
            Whether to compute the Q factors, by default True
        setIR : bool, optional
            Whether to set IR-resummed components, by default True
        setPs : bool, optional
            Whether to set power spectrum components, by default True
        setCf : bool, optional
            Whether to set correlation function components, by default True

        Notes
        -----
        This method orchestrates the complete IR-resummation procedure, including
        computing Q factors, IR filters, and applying resummation to both Fourier
        and configuration space quantities.


Apply IR-resummation to the power spectrum.

        Computes the IR-resummed power spectrum by applying bulk flow corrections
        to the BAO feature using the IR-resummation formalism.

        Parameters
        ----------
        bird : Bird
            Bird object containing the power spectrum to be resummed
        makeIR : bool, optional
            Whether to compute IR-resummed components, by default True
        makeQ : bool, optional
            Whether to compute Q factors for resummation, by default True
        setIR : bool, optional
            Whether to set IR components in the bird object, by default True
        setPs : bool, optional
            Whether to set final power spectrum components, by default True

        Notes
        -----
        The IR-resummation process involves:
        1. Computing Q factors from the growth rate
        2. Computing IR-resummed power spectrum components
        3. Setting the resummed components in the bird object


This is the main method of the class. Compute the IR corrections in Fourier space.


Display information about available configuration and cosmology parameters.

        Parameters
        ----------
        description : bool, optional
            Whether to include parameter descriptions and defaults, by default True

        Notes
        -----
        This method prints two catalogs:
        - Configuration commands: parameters for .set(config_dict)
        - Cosmology commands: parameters for .compute(cosmo_dict)


Compute cosmological correlations based on provided parameters.

        Parameters
        ----------
        cosmo_dict : dict, optional
            Dictionary of cosmological parameters for PyBird inputs
        cosmo_module : str, optional
            Name of Boltzmann solver to call internally (e.g., 'classy', 'camb')
        cosmo_engine : object, optional
            External Boltzmann solver engine object
        do_core : bool, optional
            Whether to perform core EFT calculations, by default True
        do_survey_specific : bool, optional
            Whether to apply survey-specific effects, by default True

        Notes
        -----
        You must provide either:
        - cosmo_dict with PyBird parameters, or
        - cosmo_dict with cosmological parameters + cosmo_module, or
        - cosmo_module + cosmo_engine for external Boltzmann solver

        The method handles cosmological parameter processing, validates inputs,
        and performs the main EFT calculations for power spectra or correlation functions.


Load and initialize computational engines.

        Parameters
        ----------
        load_engines : bool, optional
            Whether to actually load the engines, by default True

        Notes
        -----
        This method initializes all the computational engines needed for PyBird:
        - Common: shared parameters and utilities
        - NonLinear: one-loop calculations
        - Resum: IR resummation
        - Projection: multipole projections and survey effects
        - Matching: UV/IR matching (if needed)
        - Emulator: neural network emulator (if enabled)


        Load pre-saved IntegratedModel attributes' from an h5 file.
        Parameters:
            h5_filename (str): filename of the .h5 file where model was saved


Fiber collision effective window method auxiliary function


        AP integration
        Credit: Jerome Gleyzes


        Apply the AP effect to the bird power spectrum or correlation function
        Credit: Jerome Gleyzes


Convolve the window functions to a power spectrum P


Apply the survey window function to the bird power spectrum


        Compute the uncorrelated contribution of fiber collisions

        kPS : a cbird wavenumber output, typically a (39,) np array
        fs : fraction of the survey affected by fiber collisions
        Dfc : angular distance of the fiber channel Dfc(z = 0.55) = 0.43Mpc

        Credit: Thomas Colas


        Compute the correlated contribution of fiber collisions

        kPS : a cbird wavenumber output, typically a (39,) np array
        PS : a cbird power spectrum output, typically a (3, 39) np array
        ktrust : a UV cutoff
        fs : fraction of the survey affected by fiber collisions
        Dfc : angular distance of the fiber channel Dfc(z = 0.55) = 0.43Mpc

        Credit: Thomas Colas


Apply window effective method correction to fiber collisions to the bird power spectrum


Create the bins of the data k's


Integrate over each bin of the data k's


Apply binning in k-space for linear-spaced data k-array


Interpolate the bird power spectrum on the data k-array


Rotate multipoles to wedges


Compute the spline coefficients for a given x.


Analytic nth derivative of the spline.

        The spline has derivatives up to its order k.


Computes the antiderivative of first order of this spline


        Compute a definite integral over a piecewise polynomial.
        Parameters
        ----------
        a : float
            Lower integration bound
        b : float
            Upper integration bound
        Returns
        -------
        ig : array_like
            Definite integral of the piecewise polynomial over [a, b]


For option: which='all'. Regroups terms that share the same EFT parameter(s) (more generally, the same time functions)


For option: which='all'. Subtract the constant stochastic term from the (22-)loop


For Taylor expansion of the theory prediction: concatenate in 1D vector


For Taylor expansion of the theory prediction: unravel in attributes with native shapes


Recursively save a Python dictionary to an HDF5 group.

    Args:
        group (h5py.Group): HDF5 group to write to.
        data (dict): Dictionary to save to HDF5.
        none_flag (float, optional): Value to use when saving None values.
            Defaults to float("nan").


Run a single-chain BlackJAX NUTS sampler (JIT-compiled).

                Parameters
                ----------
                initial_pos : array-like
                    Starting point of the Markov chain.
                num_samples : int
                    Number of *post-warm-up* samples to draw.
                num_warmup : int | None
                    Number of warm-up (adaptation) steps.  Defaults to 10 % of ``num_samples``.
                target_accept : float
                    Dual-averaging target acceptance probability.
                max_num_doublings : int
                    Maximum tree depth used by NUTS *after* warm-up (controls max leapfrog steps).
                verbose : bool
                    Print basic diagnostics if ``True``.


JAX-compatible interpolation function.


Compute the spherical Bessel transform from Ps to Cf


Compute the spherical Bessel transform from Cf to Ps


    Compute the emulated linear matter power spectrum by combining the Eisenstein & Hu model, an approximation for the growth factor D,
    the fit from Bartlett et al. (2023), and corrections to both the present-day linear power spectrum and the growth factor.

    Args:
        :k (ndarray): k values to evaluate P(k) at [h / Mpc]
        :As (float): 10^9 times the amplitude of the primordial P(k)
        :Om (float): The z=0 total matter density parameter, Om
        :Ob (float): The z=0 baryonic density parameter, Omega_b
        :h (float): Hubble constant, H0, divided by 100 km/s/Mpc
        :ns (float): Spectral tilt of primordial power spectrum
        :mnu (float): Sum of neutrino masses [eV / c^2]
        :w0 (float): Time independent part of the dark energy EoS
        :wa (float): Time dependent part of the dark energy EoS
        :a (float, default=1): The scale factor to evaluate P(k) at

    Returns:
        :pk_lin (ndarray): The emulated linear P(k) [(Mpc/h)^3]


    Compute the emulated logarithm of the ratio between the true linear
    power spectrum and the Eisenstein & Hu 1998 fit. Here we use the fiducial exprssion
    given in Bartlett et al. 2023.

    Args:
        :k (ndarray): k values to evaluate P(k) at [h / Mpc]
        :Om (float): The z=0 total matter density parameter, Omega_m
        :Ob (float): The z=0 baryonic density parameter, Omega_b
        :h (float): Hubble constant, H0, divided by 100 km/s/Mpc
        :ns (float): Spectral tilt of primordial power spectrum

    Returns:
        :logF (ndarray): The logarithm of the ratio between the linear P(k) and the
            Eisenstein & Hu 1998 zero-baryon fit


    Compute the emulated logarithm of the ratio between the true linear
    power spectrum and the Eisenstein & Hu 1998 fit. Here we use the mosy precide
    exprssion given in Bartlett et al. 2023.

    Args:
        :k (ndarray): k values to evaluate P(k) at [h / Mpc]
        :Om (float): The z=0 total matter density parameter, Omega_m
        :Ob (float): The z=0 baryonic density parameter, Omega_b
        :h (float): Hubble constant, H0, divided by 100 km/s/Mpc
        :ns (float): Spectral tilt of primordial power spectrum
        :extrapolate (bool, default=False): If True, then extrapolates the Bartlett
            et al. 2023 fit outside range tested in paper. Otherwise, uses E&H with
            baryons for k < kmin and k > kmax

    Returns:
        :logF (ndarray): The logarithm of the ratio between the linear P(k) and the
            Eisenstein & Hu 1998 zero-baryon fit


    Compute the emulated logarithm of the ratio between the true linear power spectrum
    and the Eisenstein & Hu 1998 fit for LCDM as given in Bartlett et al. 2023.

    This calls the logF_fiducial function from symbolic_pofk.linear but extrapolates
    to all k considered

    Args:
        :k (ndarray): k values to evaluate P(k) at [h / Mpc]
        :As (float): 10^9 times the amplitude of the primordial P(k)
        :Om (float): The z=0 total matter density parameter, Omega_m
        :Ob (float): The z=0 baryonic density parameter, Omega_b
        :h (float): Hubble constant, H0, divided by 100 km/s/Mpc
        :ns (float): Spectral tilt of primordial power spectrum
        :mnu (float): Sum of neutrino masses [eV / c^2]
        :w0 (float): Time independent part of the dark energy EoS
        :wa (float): Time dependent part of the dark energy EoS
        :a (float): Scale factor to consider

    Returns:
        :logF (ndarray): The emulated logarithm of the ratio between the true linear power spectrum


    Corrections to the present-day linear power spectrum

    Args:
        :k (ndarray): k values to evaluate P(k) at [h / Mpc]
        :As (float): 10^9 times the amplitude of the primordial P(k)
        :Om (float): The z=0 total matter density parameter, Omega_m
        :Ob (float): The z=0 baryonic density parameter, Omega_b
        :h (float): Hubble constant, H0, divided by 100 km/s/Mpc
        :ns (float): Spectral tilt of primordial power spectrum
        :mnu (float): Sum of neutrino masses [eV / c^2]
        :w0 (float): Time independent part of the dark energy EoS
        :wa (float): Time dependent part of the dark energy EoS
        :a (float): Scale factor to consider

    Returns:
        :result (ndarray): Corrections to the present-day linear power spectrum


FFTLog auxiliary function: window sending the FFT coefficients to 0 at the edges. Adapted from fast-pt


    Reshape 1D concatenated array back to the original arrays (P11l, Pctl, Ploopl).

    Parameters:
        - array: The input array (1D for original, higher dimensions for derivatives)
        - L: The object that contains correlator_sky objects and original shapes

    Returns:
        - A list of reshaped tuples (P11l, Pctl, Ploopl) for each correlator_sky


Load all pre-trained emulator models from disk.

        Notes
        -----
        This method loads neural network models for:
        - Loop corrections (monopole, quadrupole, hexadecapole)
        - IR resummation terms (P11, counterterms, loop terms)

        Models are stored as HDF5 files and compiled for JAX execution.


Prepare input parameters for emulator predictions.

        Parameters
        ----------
        kk : ndarray
            k-array in h/Mpc
        pk : ndarray
            Linear power spectrum in (Mpc/h)^3
        f : float, optional
            Growth rate for RSD effects, by default 1.0
        time : bool, optional
            Whether to include time dependence, by default False
        ir : bool, optional
            Whether this is for IR resummation, by default False
        pca : bool, optional
            Whether to use PCA compression, by default False

        Returns
        -------
        ndarray
            Formatted input parameters for the emulator models


Compute the log-likelihood for a given set of EFT parameters.

        This method is the core function that calculates the log-likelihood given a set of
        EFT parameters while handling cosmological dependencies. It reconstructs theory predictions,
        calculates chi-squared values (marginalized or non-marginalized), and computes
        prior contributions.

        Args:
            free_b (ndarray): Array of free EFT parameters, potentially including rs_marg parameter
                at the beginning followed by parameters for each sky patch.
            free_b_name (list): List of names corresponding to free_b parameters.
            cosmo_engine (object, optional): Boltzmann solver instance (CLASS, CPJ, or Symbolic).
                Defaults to None.
            cosmo_module (str, optional): Type of cosmology calculation ('class', 'taylor', etc.).
                Defaults to 'class'.
            need_cosmo_update (bool, optional): Whether to update cosmological quantities.
                Defaults to True.
            cosmo_dict (dict, optional): Dictionary of precomputed cosmological quantities.
                Defaults to None.
            hessian_type (str, optional): Type of Hessian calculation ('H', 'F', or 'FH').
                Defaults to None.

        Returns:
            float: Log-likelihood value (including priors).

        Notes:
            - The free_b array is reshaped into per-sky parameters after extracting any global
              parameters like alpha_rs if with_rs_marg is True.
            - For marginalized likelihood, parameters specified in bg_name are analytically
              marginalized over using Gaussian priors.
            - When get_maxlkl is True, the marginalized parameters are calculated and stored.
            - BAO reconstruction alphas are included if with_bao_rec is True.
            - Loop corrections are included if with_loop_prior is True.


 Perform the FFTLog (i.e. calculate the coefficients of the FFTLog) of the input linear power spectrum in the given a Bird().

        Parameters
        ----------
        bird : class
            an object of type Bird()


 Compute the loop power spectrum given a Bird(). Perform the FFTLog and the matrix multiplications.

        Parameters
        ----------
        bird : class
            an object of type Bird()


Compute the loop correlation function given a Bird().

        Performs the FFTLog spherical Bessel transform and matrix multiplications
        to compute the one-loop correlation function multipoles.

        Parameters
        ----------
        bird : Bird
            Bird object containing cosmological parameters and linear power spectrum

        Notes
        -----
        This method computes C11, C22l, and C13l terms, which are the correlation
        function multipoles corresponding to linear, 22-loop, and 13-loop contributions.
        The results are stored in the bird object.


Compute both power spectrum and correlation function loop terms.

        This is the main method that computes both the one-loop power spectrum
        and correlation function multipoles for a given Bird object.

        Parameters
        ----------
        bird : Bird
            Bird object containing cosmological parameters and linear power spectrum

        Notes
        -----
        This method combines Ps() and Cf() calculations, computing all one-loop
        terms (P22, P13, C11, C22l, C13l) and counterterms efficiently.


Run all Correlator tests.


Create a simple cosmology setup without CLASS.

        Args:
            nk: Number of k points
            z: Redshift

        Returns:
            Dictionary with cosmology data


Create mock data vector and covariance matrix.

        Args:
            nk: Number of k bins
            multipoles: Number of multipoles (0, 2, 4)

        Returns:
            Tuple of (data_vector, covariance_matrix)


Check if output has expected shape.

        Args:
            output: Array to check
            expected_shape: Expected shape
            name: Name for error messages

        Returns:
            True if shape matches, False otherwise


Check if output contains NaN or infinite values.

        Args:
            output: Array to check
            name: Name for error messages

        Returns:
            True if no NaN/inf, False otherwise


Check if output values are within reasonable bounds.

        Args:
            output: Array to check
            min_val: Minimum allowed value
            max_val: Maximum allowed value
            name: Name for error messages

        Returns:
            True if values are reasonable, False otherwise


Check which optional packages are available.

    Returns:
        Tuple of (jax_available, class_available, emulator_available)


Run utility tests.


Run all Bird tests.


Run all Emulator tests.


Check if JAX requirements are available.


Run tests for a single class.


Print test summary.


Main test runner.


Run all Likelihood tests.


Build the documentation using Python sphinx module.


Copy the brightness ditribution of the input IMFITS object


 Converts angles currently in degrees to radians
    which is needed to use the von Mises distribution correctly


Calculate the modelled angles


 Finds the locations that meet the lineation formation criteria and
    the total area of


Calculates the likelihood of the lineations forming at the given locations


 Function to calculate the directional likelihood
    at each location and time


    Fixture sets up by reverting the PersistentConfigurationManager state and
    setting a new temporary path for the configuration file directory


Unset any active session

        Returns:
            str: Name of unset session if any, otherwise None


Submit expansion logic to an Aerie instance

        Args:
            expansion_logic (str): String contents of the expansion file
            activity_name (str): Name of the activity
            model_id (str): Aerie model ID
            parcel_id (str): Aerie sequencing parcel ID
            name (str, Optional): Name of the expansion rule
            description (str, Optional): Description of the expansion rule

        Returns:
            int: Expansion Rule ID in Aerie


Create an Aerie expansion set given a list of activity IDs

        Args:
            parcel_id (int): Aerie sequencing parcel ID
            model_id (int): ID of Aerie mission model
            expansion_ids (List[int]): List of expansion IDs to include in the set
            name (str): Name of the expansion set
            description (str, Optional): Freeform description field

        Returns:
            int: Expansion set ID


Create a sequence on a given simulation dataset

        Args:
            seq_id (str): ID of the new sequence
            simulation_dataset_id (int): ID of the parent simulation dataset


List all expansion rules

        Returns:
            List[ExpansionRule]


Expand simulated activities from a simulation dataset given an expansion set

        Args:
            simulation_dataset_id (int): Dataset of activities to be expanded
            expansion_set_id (int): ID of expansion set to use

        Returns:
            int: Expansion Run ID


List all expansion runs from a given simulation dataset.


Link a set of simulated activities to a sequence for expansion

        Take a set of simulated activities (not plan activities) of a given
        simulation dataset and link them to an existing sequence so that
        expansion outputs from the given activities are included in the
        sequence.

        Args:
            seq_id (str): ID of the sequence to which activities will be linked
            simulation_dataset_id (int): Dataset which contains the activities being linked
            simulated_activity_ids (List[int]): IDs of simulated activities to be linked


List all sequences tied to a simulation dataset

        Args:
            simulation_dataset_id (int): ID on the Aerie host

        Returns:
            List[str]: Sequence IDs


Delete a command sequence

        Args:
            seq_id (str): Sequence ID
            simulation_dataset_id (int): ID of Simulation Dataset where the sequence exists


Upload an AMPCS command, channel, or parameter dictionary to an Aerie instance

        Args:
            dictionary (str): Contents from XML dictionary file (newlne-delimited)
            persist (bool, optional): Persist the uploaded source dictionary in Aerie. Defaults to True.

        Returns:
            int: Dictionary ID


List all command, parameter, and channel dictionaries

        Returns:
            List[DictionaryMetadata]


Delete AMPCS dictionary

        Args:
            id (int): _description_
            dictionary_type (Union[str, DictionaryType]): _description_


Upload Phoenix Editor sequence adaptation

        Args:
            adaptation (str): String contents of adaptation JS file

        Returns:
            int: ID of sequence adaptation


List Phoenix Editor sequence adaptations

        Returns:
            List[SequenceAdaptationMetadata]: Metadata for all existing sequence adaptations


Update Phoenix Editor sequence adaptation

        Args:
            adaptation (str): String contents of adaptation JS file
            id (int): ID of sequence adaptation to update


Delete Phoenix Editor sequence adaptation

        Args:
            id (int): ID of adaptation to delete


Create sequencing parcel

        Inserts parcel entry with command dictionary, channel dictionary, and sequencing adaptation IDs.
        Links parameter dictionaries to that parcel.

        Args:
            parcel (Parcel): Contents of parcel to create

        Returns:
            int: ID of created parcel


List sequencing parcels

        Returns:
            List[Parcel]:


Delete sequencing parcel

        Args:
            id (int): ID of parcel to delete


        Bulk upload operation for uploading scheduling goals.
        @param upload_object should be JSON-like with a definition key and metadata containing the goal name and model id
        [
            {
                definition: str
                metadata: {
                    name: str,
                    models_using: {
                        data: {
                            model_id: int
                        }
                    }
                }
            },
            ...
        ]


        Bulk operation to add goals to specification.
        @param upload_object should be JSON-like with keys goal_id, specification_id
        [
            {
                goal_id: int,
                specification_id: int
            },
            ...
        ]


        Add a constraint to a plan's constraint specification.
        @param constraint_id The constraint ID to add to the given plan
        @param plan_id The plan ID to add this constraint to


Add metadata schemas

        The schema format should follow the documentation [here](https://nasa-ammos.github.io/aerie-docs/planning/activity-directive-metadata/).

        Args:
            schemas (list): a list of the schemas to add

        Returns:
            list: a list of the metadata keys and schemas that were added


Delete metadata schemas

        Returns:
            list: a list of the metadata keys that were deleted


List plan collaborators

        Args:
            plan_id (int): ID of Plan to list collaborators of

        Returns:
            list[str]: List of collaborator usernames


Add a plan collaborator

        Args:
            plan_id (int): ID of plan to add collaborator to
            user (str): Username of collaborator


Delete a plan collaborator

        Args:
            plan_id (int): ID of the plan to delete a collaborator from
            user (str): Username of the collaborator


Throw a RuntimeError if the Gateway response is malformed or contains errors

    Args:
        resp (requests.Response): from a request to the gateway

    Returns:
        dict: Contents of response JSON


Issue a post request to the Aerie instance GraphQL API

        Args:
            query (str): GraphQL query text
            kwargs: keyword arguments for named variables for the query

        Raises:
            RuntimeError

        Returns:
            Dict: Query response data


Issue a post request to upload a file via the Aerie gateway

        Args:
            file_name (str): Name of the file being uploaded
            file_contents (bytes): File contents

        Raises:
            RuntimeError: Raised if the request receives an error response

        Returns:
            Dist: JSON response


Change role for Aerie interaction

        Args:
            new_role (str): String name of new role.


Checks if session is correctly authenticated with Aerie host

        Looks for errors received after pinging GATEWAY_URL/auth/session.
        Also returns False if the session has not yet been authenticated (no JWT).

        Returns:
            bool: True if there were no errors in a ping against GATEWAY_URL/auth/session, False otherwise


Check if authentication is enabled on an Aerie host

        Returns:
            bool: False if authentication is disabled, otherwise True


Assert that the Aerie host is a compatible version

        Raises a `RuntimeError` if the host appears to be incompatible.


Activate a session with an Aerie host using a given configuration


Deactivate any active session


Change Aerie permissions role for the active session


Returns information about the current Aerie session.


Convert a string to timedelta.

    If the input is of type timedelta, does nothing and returns the input.
    This is used in certain fields to accept both strings and timedeltas.


Find a configuration by name or path.

    configuration_identifier (str): The name or path of a configuration. Paths should be to a configuration json file.

    Raises:
        ValueError
        FileNotFoundError

    Returns:
        AerieHostConfiguration


Authenticate requests.Session object with an external service

    Send a post request with static and secret variables defined in `configuration` to `auth_url`.
    Cookies returned from the request are stored in the returned requests.Session object.

    Args:
        configuration (ProxyConfiguration): Proxy server configuration
        secret_post_vars (Dict[str, str], optional): Optionally provide values for some or all secret post request variable values. Defaults to None.

    Raises:
        RuntimeError: Failure to authenticate with proxy

    Returns:
        requests.Session: Session with any cookies acquired for proxy authentication


Start and authenticate an Aerie Host session, with prompts if necessary

    If username is not provided, it will be requested via CLI prompt.

    If password is not provided but the Aerie instance has authentication enabled, it will be requested via CLI prompt.
    If the Aerie instance has authentication disabled, a password is not necessary.

    If external authentication is specified in the configuration, `secret_post_vars` can be used to pass in
    credentials. If external auth is specified with secrets and matching credentials aren't provided, they will be
    requested via CLI prompt.

    Args:
        configuration (AerieHostConfiguration): Configuration of host to connect
        username (str, optional): Aerie username.
        password (str, optional): Aerie password.
        secret_post_vars (Dict[str, str], optional): Optionally provide values for some or all secret post request variable values. Defaults to None.
        force (bool, optional): Force connection to Aerie host and ignore version compatibility. Defaults to False.

    Returns:
        AerieHost:


Parse a Postgres inteval to a `timedelta` object

    Modified from Django interval parsing cited above.

    Args:
        interval (str): Postgres interval string

    Raises:
        ValueError: Unable to match patterns in the interval

    Returns:
        timedelta


Convert a postgres interval string to an integer number of microseconds

    Both `timedelta` and Postgres intervals have a precision of 1us, so this conversion shouldn't introduce any rounding errors


Constructs a PostgreSQL interval from a `timedelta`


Parse the string format returned by timedelta.__str__


Define a configuration for an Aerie host


Load one or more configurations from a JSON file


List available Aerie host configurations


Delete an Aerie host configuration


Remove all persistent aerie-cli files


Upload new scheduling goal


Upload an update to a scheduling goal


Delete scheduling goal


    Bulk deploy command expansion rules and sets to an Aerie instance according to a JSON configuration file.

    The configuration file contains a list of rules and a list of sets:

    ```
    {
        "rules": [...],
        "sets": [...]
    }
    ```

    Each rule must provide a unique rule name, the activity type name, and the name of the file with expansion logic:

    ```
    {
        "name": "Expansion Rule Name",
        "activity_type": "Activity Type Name",
        "file_name": "my_file.ts"
    }
    ```

    Each set must provide a unique set name and a list of rule names to add:

    ```
    {
        "name": "Expansion Set Name",
        "rules": ["Expansion Rule Name", ...]
    }
    ```


Run command expansion on a simulation dataset


    List expansion runs for a given plan or simulation dataset

    Runs are listed in reverse chronological order.


    List sequences for a given plan or simulation dataset

    Sequences are listed in alphabetical order.


Create a sequence on a simulation dataset


Delete sequence on a simulation dataset


Download a SeqJson file from an Aerie sequence


List all expansion sets


    Create an expansion set

    Uses the newest expansion rules for each given activity type.
    Specify either a list of activity type names or rule IDs. If activity type
    names are given, rules are filtered to only those designated for the given
    mission model and sequencing parcel, then the highest rule ID is used for
    each activity type named.


Add to the metadata schema from a .json file.

    JSON file contents should include a list schemas, each containing a key for its name and value for its type.


Delete a metadata schema by its name.


List uploaded metadata schemas.


Delete all metadata schemas.


    Utility function to create metadata for a given constraint.
    @param name The constraint name
    @param description The constraint description
    @param model_id The model ID that will be using this constraint
    @param plan_id The plan ID that will be using this constraint


Upload a constraint


Associate a constraint with a plan's constraint specification.


Delete a constraint


Update a constraint


Download a plan and save it locally as a JSON file.


Download simulated activity instances and save to a JSON file


    Download resource timelines from a simulation and save to either JSON or CSV.

    JSON resource timelines are formatted as lists of time-value pairs. Relative timestamps are milliseconds since
    plan start time. Absolute timestamps are of the form YYYY-DDDTh:mm:ss.sss

    CSV resource timeline relative timestamps are seconds since plan start time. Absolute timestamps are formatted the
    same as the JSON outputs.


Create a plan from an input JSON file.


Duplicate an existing plan.