    Divide the image by a flat field frame.

    Parameters
    ----------
    image : `~astropop.framedata.FrameData` compatible
        Image to perform the flat field correction. `~astropy.units.Quantity`,
        numerical values and `~astropy.nddata.CCDData` are also suported.
    master_flat : `~astropop.framedata.FrameData` compatible
        Master flat field image to be subtracted from the ``image``.
    min_value : float, optional
    norm_value : float, optional
    inplace : bool, optional
        If True, the operations will be performed inplace in the `image`.

    Returns
    -------
    `~astropop.framedata.FrameData`:
        New flat field corrected `FrameData` instance if ``inplace``, else the
        ``image`` `~astropop.framedata.FrameData` instance.


Trim an image to a given section. Uses python slice standard.

    Parameters
    ----------
    image : `~astropop.framedata.FrameData` compatible
        Image to be trimmed. `~astropy.units.Quantity`, numerical values and
        `~astropy.nddata.CCDData` are also suported.
    x_slice, y_slice : `slice`
        Section to be trimmed in x and y axes.
    inplace : bool, optional
        If True, the operations will be performed inplace in the `image`.

    Returns
    -------
    `~astropop.framedata.FrameData`:
        Trimmed `FrameData` instance.


Merge headers.

    Parameters
    ----------
    headers: list of `astropy.io.fits.Header`
        Headers to be merged.
    method: {'only_equal', 'first', 'selected_keys', 'no_merge'}
        Method to merge the headers. 'only_equal' will merge only the keywords
        with the same value in all headers. 'first' will use the first
        header as the result. 'selected_keys' will merge only the keywords
        in the list `header_merge_keys`, prioritizing the first appearence.
        'no_merge' will return an empty header.
    selected_keys: list of str
        List of keywords to be merged. Used only if method is
        'selected_keys'.

    Returns
    -------
    header: `dict`
        Merged header.

    Notes
    -----
    - All headers must have normalized keywords.


Merge flags from images.

    Parameters
    ----------
    flags: list of `numpy.ndarray`
        Flags to be merged.
    method: {'or', 'and', 'no_merge'}
        Method to merge the flags. 'or' will merge using the logical or
        operation. 'and' will merge using the logical and operation.
        'sum' will merge using the sum operation.

    Returns
    -------
    flag: `numpy.ndarray`
        Merged flag.


Remove the cache folder.


Add a TempFile to this folder.

        Parameters
        ----------
        basename: str
            Base name of the file to be created.
        delete_on_remove: bool
            Keep the file after the program exits.

        Returns
        -------
        TempFile:
            The created TempFile instance.


Add a TempFolder to this folder.

        Parameters
        ----------
        basename: str
            Base name of the file or folder to be created.
        delete_on_remove: bool
            Keep the file after the program exits.

        Returns
        -------
        TempDir:
            The created TempDir instance.


Delete this folder and all its contents.


This folder can be removed and all its contents.


Delete this file.


Create a memory map to an array data.

    Parameters
    ----------
    filename : `string`, `~pathlib.Path`
        Name of memmap file to be created.
    data : array_like
        Data to be stored in the memmap.
    dtype : `string`, `~numpy.dtype` or `None` (optional)
        `~numpy.dtype` compilant data type. If `None`, `data.dtype` will be
        used.

    Returns
    -------
    memmap : `~numpy.memmap`
        Memmap object of cached data.


Delete a memmap and read the data to a np.ndarray.

    Parameters
    ----------
    memmap : array_like or `None`
        MemMap array to be deleted.
    read : `bool` (optional)
        Read the data to memory before delete.
    remove : `bool` (optional)
        Delete the memmap file.

    Returns
    -------
    data : array_like or `None`
        Data read from memmap.


Reset a memmap array to a new data.

    Parameters
    ----------
    array : array_like
        MemMap array to be reseted.
    data : array_like
        Data to be stored in the memmap.

    Returns
    -------
    memmap : `~numpy.memmap`
        Memmap object of cached data.


Remove the SIP keys. (Too complex fixing).


Get a header (or dict) and extract a WCS based on the keys.

    Parameters
    ----------
    header: `~astropy.fits.Header` or dict_like
        Header to extract the WCS.
    logger: `~logging.Logger` (optional)
        Logger instance to log warnings.

    Returns
    -------
    header: `~astropy.fits.Header`
        Header cleaned from WCS keys.
    wcs: `~astropy.wcs.WCS` os `None`
        World Coordinate Sistem extracted from the header.


Normalize meta keys and remove the protected ones.


Extract data and meta from FITS files and HDUs.


Extract data and meta from CCDData objects.


Translate a FrameData to a CCDData.


Translate a FrameData to an HDUList.


Write a framedata to a fits file.


Read an object to a FrameData container.

    Parameters
    ----------
    obj: any compatible, see notes
      Object that will be readed to the FrameData.
    copy: bool (optional)
      If the object is already a FrameData, return a copy instead of the
      original one.
      Default: False

    Returns
    -------
    frame: `FrameData`
      The readed FrameData object.

    Notes
    -----
    - If obj is a string or `~pathlib.Path`, it will be interpreted as a file.
      File types will be checked. Just FITS format supported now.
    - If obj is `~astropy.io.fits.HDUList`, `~astropy.io.fits.HDUList` or
      `~astropy.nddata.CCDData`, they will be properly translated to
      `FrameData`.
    - If numbers or `~astropop.math.physical.QFloat`,
      `~astropy.units.Quantity`, they will be translated to a `FrameData`
      without metadata.


Check shape consistency across `data`, `uncertaitny` and `mask`.


Extract and compare units if they are consistent.


Check if an uncertainty can be set based on its unit.

    Parameters
    ----------
    unit: string or `~astropy.units.Unit`
        Target uncertainty unit. Mainly, this is the FrameData unit.
    uncertainty: array_like
        Uncertainty object. If it has units, it will be converted to the
        target.

    Returns
    -------
    uncertainty: `numpy.ndarray`
        Uncertainty converted to the target unit.


Add a given flag to the pixels in the given positions.

        Parameters
        ----------
        flag : `PixelMaskFlags`
            Flag to be added.
        where : `~numpy.ndarray`
            Positions where the flag will be added.


Get a mask pixels with an specific flag.

        Parameters
        ----------
        flags: list of `PixelMaskFlags` or `PixelMaskFlags`

        Returns
        -------
        mask: `~numpy.ndarray`
            Masked pixels. True for masked pixels.


Mask pixels.

        Parameters
        ----------
        pixels: `~numpy.ndarray` or tuple
            Pixels to be masked. Can be a tuple of (y, x) positions or a
            boolean array where True means masked. Uses the same standard as
            `~numpy.ndarray`[pixels] access.


Enable array file memmapping.

        Parameters
        ----------
        filename : str, optional
            Custom memmap file name.
        cache_folder : str, optional
            Custom folder to cache data.


Disable frame file memmapping (load to memory).


Update the memmap files.


Copy the current FrameData to a new instance.

        Parameters
        ----------
        - dtype: `~numpy.dtype` (optional)
            Data type for the copied FrameData. If `None`, the data type will
            be the same as the original Framedata.
            Default: `None`


Compute and return the median of the data.


Compute and return the mean of the data.


Compute and return the std dev of the data.


Compute minimum value of the data.


Compute general statistics ofthe image.


Generate an HDUList from this FrameData.

        Parameters
        ----------
        wcs_relax: `bool`, optional.
            Allow non-standard WCS keys.
            Default: `True`
        no_fits_standard_units: `bool`, optional
            Skip FITS units standard for units. If this options is choose,
            the units will be printed in header as `~astropy.units.Unit`
            compatible string.
            Default: `True`
        **kwargs:
            hdu_uncertainty: string, optional
                Extension name to store the uncertainty in 2D image format.
            hdu_flags: string, optional
                Extension name to store the pixel list flags in table format.
            unit_key: string, optional
                Header key for physical unit.

        Returns
        -------
        `~astropy.fits.HDUList` :
            HDU storing all FrameData informations.


Convert actual FrameData to CCDData.

        Returns
        -------
        `~astropy.nddata.CCDData` :
            CCDData instance with actual FrameData informations.


Write frame to a fits file.

        Parameters
        ----------
        filename: str
            Name of the file to write.
        overwrite: bool, optional
            If True, overwrite the file if it exists.
        wcs_relax: `bool`, optional.
            Allow non-standard WCS keys.
            Default: `True`
        no_fits_standard_units: `bool`, optional
            Skip FITS units standard for units. If this options is choose,
            the units will be printed in header as `~astropy.units.Unit`
            compatible string.
            Default: `True`
        **kwargs:
            hdu_uncertainty: string, optional
                Extension name to store the uncertainty in 2D image format.
            hdu_flags: string, optional
                Extension name to store the pixel list flags in table format.
            unit_key: string, optional
                Header key for physical unit.


Compute theta using Q and U, considering quadrants and max 180 value.


Estimate the displacement between the two beams.

    To compute the displacement between the ordinary and extraordinary
    beams, this function computes the most common distances between the
    sources in image, using clipped histograms around the peak.

    Parameters
    ----------
    x, y: array_like
        Arrays of x and y positions of the sources.
    steps: list of int
        Number of pixels, around the mode, to clip the histogram in each step.
    bins: int
        Number of bins to use in the histogram.
    dist_limit: float
        Maximum distance between the pairs of sources to consider.

    Return
    ------
    dx, dy: float
        Displacement between the ordinary and extraordinary beams.


Match the pairs of ordinary/extraordinary points (x, y).

    This function matches the pairs of ordinary and extraordinary points
    (x, y) using the displacement (dx, dy) between the two beams.

    Parameters
    ----------
    x, y: array_like
        Arrays of x and y positions of the sources.
    dx, dy: float
        Displacement between the ordinary and extraordinary beams.
    tolerance: float
        Tolerance for the matching.

    Return
    ------
    `numpy.ndarray`:
        Array of the indexes of the matched pairs. Column 'o' contains the
        indexes of the ordinary points, column 'e' the indexes of the
        extraordinary points.


Compute polarimetry z(psi) model for quarter wavelength retarder.

    Z(psi) = Q*cos(2psi)**2 + U*sin(2psi)*cos(2psi) - V*sin(2psi)

    Parameters
    ----------
    psi: array_like
        Array of retarder positions in degrees.
    q, u, v: float
        Stokes parameters
    zero: float
        Zero position of the retarder in degrees.

    Return
    ------
    z: array_like
        Array of polarimetry values.


Compute polarimetry z(psi) model for half wavelength retarder.

    Z(psi) = Q*cos(4*psi) + U*sin(4*psi)

    Parameters
    ----------
    psi: array_like
        Array of retarder positions in degrees.
    q, u: float
        Stokes parameters
    zero: float (optional)
        Zero angle of the retarder position.

    Return
    ------
    z: array_like
        Array of polarimetry values.


Angle between Stokes parameters.


Root mean square of the fitting.


Callable model of the modulation (zi).


Theoretical error of stokes parameters from the fluxes SNR.


Check if positions are in the correct order.


Estimate the normalization factor for halfwave retarder.


Estimate the normalization factor for quarterwave retarder.


Compute the Stokes params for halfwave retarder.


Compute the Stokes params for quarterwave retarder.


Compute the Stokes params from ordinary and extraordinary fluxes.

        Parameters
        ----------
        psi : array_like
            Retarder positions in degrees. Must be multiple of 22.5 degrees.
        f_ord : array_like
            Fluxes of ordinary beam. If `~astropop.math.QFloat`, the errors
            will be considered in the parameters computation.
        f_ext : array_like
            Fluxes of extraordinary beam. If `~astropop.math.QFloat`, the
            errors will be considered in the parameters computation.
        f_ord_error : array_like, optional
            Errors of the ordinary fluxes. Conflicts with the error of `f_ord`
            if it is a `~astropop.math.QFloat`.
        f_ext_error : array_like, optional
            Errors of the extraordinary fluxes. Conflicts with the error of
            `f_ext` if it is a `~astropop.math.QFloat`.

        Returns
        -------
        `~astropop.polarimetry.StokesParameters`:
            Instances containing the computed Stokes Parameters.


Get the fitter function.


Fit the model for halfwave retarder.


Find sources using `~photutils.segmentation`.

    Parameters
    ----------
    data: array_like
        2D array containing the image to extract the sources.
    threshold: `int` or `float`
        Minumim number of standard deviations above the background level where
        the algorithm will start to consider the sources.
    background: `float` or `~numpy.ndarray`
        Background level estimation. Can be a single global value, or a 2D
        array with by-pixel values.
    noise: `float` or `~numpy.ndarray`
        RMS or any other noise estimation to use in the detection. Can be a
        single global value, or a 2D array with by-pixel values.
    mask: array_like (optional)
        Boolean mask where 1 pixels are masked out in the background
        calculation.
        Default: `None`
    fwhm: `float` (optional)
        FWHM to generate the convolution kernel. If `None`, no convolution
        will be performed.
        Default: `None`
    npix: `int` (optional)
        Minimum number of connected pixels to consider a source.
        Default: `5`
    deblend: `bool` (optional)
        If `True`, the algorithm will try to deblend the sources.
        Default: `True`

    Returns
    -------
    sources: `astropy.table.Table`
        Table with the sources found. The table will contain the following
        columns:
        - ``id``: source ID
        - ``x``, ``y``: x and y coordinates of the source centroid
        - ``xcentroid``, ``ycentroid``: same as ``x`` and ``y``
        - ``peak``: value of the source peak
        - ``flux``: integrated (background-subtracted) source flux within the
          segment
        - ``sigma_x``, ``sigma_y``: standard deviation of the source elipsoid
          along x and y
        - ``theta``: rotation angle of the source elipsoid (degrees) from the
          positive x axis
        - ``fwhm``: FWHM of circular gaussian fit of the source
        - ``eccentricity``: The eccentricity of the 2D Gaussian function that
          has the same second-order moments as the source.
        - ``elongation``: The ratio of the lengths of the semimajor and
          semiminor axes.
        - ``ellipticity``: 1.0 minus the elongation.
        - ``cxx``, ``cyy``, ``cxy``: SourceExtractor ellipse parameters.
          See [SourceExtractor docs]_
        - ``area``: area of the segment, in pixels
        - ``label``: label identifying the segment to which the source belongs.
          Can be used as y-sorted index.

    References
    ----------
    .. [SourceExtractor docs] Ellipse parameters
       (https://sextractor.readthedocs.io/en/latest/Position.html\
        #ellipse-parameters-cxx-cyy-cxy)


Return the circular cotouts segment masks.


Find sources using DAOfind algorithm.

    Parameters
    ----------
    data: array_like
        2D array containing the image to extract the sources.
    threshold: `int` or `float`
        Minumim number of standard deviations above the background level where
        the algorithm will start to consider the sources.
    background: `float` or `~numpy.ndarray`
        Background level estimation. Can be a single global value, or a 2D
        array with by-pixel values.
    noise: `float` or `~numpy.ndarray`
        RMS or any other noise estimation to use in the detection. Can be a
        single global value, or a 2D array with by-pixel values. Due to
        limitations of photutils, if a 2D array is provided, it will be
        converted to a scalar using the median.
    fwhm: `float`
        Full width at half maximum: to be used in the convolve filter.
    sharp_limit: array_like or `None` (optional)
        Low and high cutoff for the sharpness statistic. `None` will disable
        the sharpness filtering.
        Default: (0.2, 1.0)
    round_limit : array_like or `None` (optional)
        Low and high cutoff for the roundness statistic. `None` will disable
        the roundness filtering.
        Default: (-1.0,1.0)
    mask: array_like (optional)
        Boolean mask where 1 pixels are masked out in the background
        calculation.
        Default: `None`
    exclude_border: `bool` (optional)
        If `True`, sources found within half the size of the convolution
        kernel from the image borders are excluded.
        Default: `True`
    positions: array_like (optional)
        List of (x, y) positions where to look for sources. If provided, the
        source finding step will be ignored and the centroids will be refined
        and filtered.
        Default: `None`

    Returns
    -------
    sources: `astropy.table.Table`
        Table with the sources found. The table will contain the following
        columns:
        - ``id``: source ID
        - ``x``, ``y``: x and y coordinates of the source centroid
        - ``xcentroid``, ``ycentroid``: same as ``x`` and ``y``
        - ``peak``: value of the source peak
        - ``flux``: integrated (background-subtracted) source flux within the
          segment
        - ``fwhm``: FWHM of circular gaussian fit of the source
        - ``sharpness``: The source DAOFIND sharpness statistic.
        - ``roundness``: The source DAOFIND roundness statistic. Maximum
          between ``g_roundness`` and ``r_roundness``.
        - ``g_roundness``: The DAOFIND roundness statistic based on Gaussian
          marginal fit. Good for assymetries aligned with the x or y axis.
        - ``s_roundness``: The DAOFIND roundness statistic based on symmetry
          of the source. Good for assymetries aligned with the diagonal.
        - ``sigma_x``, ``sigma_y``: standard deviation of the source elipsoid
          along x and y
        - ``theta``: rotation angle of the source elipsoid (degrees) from the
          positive x axis
        - ``fwhm``: FWHM of circular gaussian fit of the source
        - ``eccentricity``: The eccentricity of the 2D Gaussian function that
          has the same second-order moments as the source.
        - ``elongation``: The ratio of the lengths of the semimajor and
          semiminor axes.
        - ``ellipticity``: 1.0 minus the elongation.
        - ``cxx``, ``cyy``, ``cxy``: SourceExtractor ellipse parameters.
          See [SourceExtractor docs]_
        - ``area``: area of the segment, in pixels


Find stars using daofind AND sepfind.

    Parameters
    ----------
    data: array_like
        2D array containing the image to extract the sources.
    threshold: `int` or `float`
        Minumim number of standard deviations above the background level where
        the algorithm will start to consider the sources.
    background: `float` or `~numpy.ndarray`
        Background level estimation. Can be a single global value, or a 2D
        array with by-pixel values.
    noise: `float` or `~numpy.ndarray`
        RMS or any other noise estimation to use in the detection. Can be a
        single global value, or a 2D array with by-pixel values. Due to
        limitations of photutils, if a 2D array is provided, it will be
        converted to a scalar using the median.
    fwhm: `float` (optional)
        Initial guess of the FWHM to be used in the convolve filter. No need to
        be precise. Will be recomputed in the function.
        Default: `None`
    sharp_limit: array_like or `None` (optional)
        Low and high cutoff for the sharpness statistic. `None` will disable
        the sharpness filtering.
        Default: (0.2, 1.0)
    round_limit : array_like or `None` (optional)
        Low and high cutoff for the roundness statistic. `None` will disable
        the roundness filtering.
        Default: (-1.0,1.0)
    mask: array_like (optional)
        Boolean mask where 1 pixels are masked out in the background
        calculation.
        Default: `None`
    exclude_border: `bool` (optional)
        If `True`, sources found within half the size of the convolution
        kernel from the image borders are excluded.
        Default: `True`

    Returns
    -------
    sources: `astropy.table.Table`
        Table with the sources found. The table will contain the following
        columns:
        - ``id``: source ID
        - ``x``, ``y``: x and y coordinates of the source centroid
        - ``xcentroid``, ``ycentroid``: same as ``x`` and ``y``
        - ``peak``: value of the source peak
        - ``flux``: integrated (background-subtracted) source flux within the
          segment
        - ``fwhm``: FWHM of circular gaussian fit of the source
        - ``sharpness``: The source DAOFIND sharpness statistic.
        - ``roundness``: The source DAOFIND roundness statistic. Maximum
          between ``g_roundness`` and ``r_roundness``.
        - ``g_roundness``: The DAOFIND roundness statistic based on Gaussian
          marginal fit. Good for assymetries aligned with the x or y axis.
        - ``s_roundness``: The DAOFIND roundness statistic based on symmetry
          of the source. Good for assymetries aligned with the diagonal.
        - ``sigma_x``, ``sigma_y``: standard deviation of the source elipsoid
          along x and y
        - ``theta``: rotation angle of the source elipsoid (degrees) from the
          positive x axis
        - ``fwhm``: FWHM of circular gaussian fit of the source
        - ``eccentricity``: The eccentricity of the 2D Gaussian function that
          has the same second-order moments as the source.
        - ``elongation``: The ratio of the lengths of the semimajor and
          semiminor axes.
        - ``ellipticity``: 1.0 minus the elongation.
        - ``cxx``, ``cyy``, ``cxy``: SourceExtractor ellipse parameters.
          See [SourceExtractor docs]_
        - ``area``: area of the segment, in pixels
        - ``label``: label identifying the segment to which the source belongs.
          Can be used as y-sorted index.


    Parameters
    ----------
    model: `str`
        Choose a Gaussian or Moffat model.
    data: array_like
        2D array containing the image to extract the source.
    x, y: array_like
        x and y indexes ofthe pixels in the image.
    xc, yc: array_like
        x and y initial guess positions of the source.

    Returns
    -------
    fwhm: `float`
        FWHM of the source.

    Notes
    -----
    The sigma of the gaussian is capped to 100 pixels. The same as the Moffat
    width.


Calculate the median FWHM of the image with Gaussian or Moffat fit.

    Parameters
    ----------
    data: array_like
        2D array containing the image to extract the source.
    x, y: array_like
        x, y centroid position.
    box_size: `int` (optional)
        Size of the box, in pixels, to fit the model.
        Default: 25
    model: {`gaussian`, `moffat`}
        Choose a Gaussian or Moffat model.
        Default: `gausiann`
    min_fwhm: float
        Minimum value for FWHM.
        Default: 3.0


Detect when the aperture goes out of the image bounds.


Detect when a pixel is flagged. Pixel flags is a 2D image flags.


Compute the background annulus for aperture photometry.


Recenter the sources using photutils.centroids.


Perform aperture photometry using sep. Output units (ADU or e-) will
    be the considered the same as input.

    This method just wraps the `~photutils.ApertureStats` method
    from photutils, assuming standard arguments and performing extra steps:

    - Calculate the total error (bkg+poisson) from input data, based on data
      and bkg_error.
    - It assumes the `'exact'` method of subpixel sampling.
    - Compute an optimal aperture radius, considering only the gaussian
      background-only error. This radius is defined as r=0.6731*GFWHM.
    - Use sigma clipping for annulus background calculation.
    - Perform photometry flags generation. See
      `~astropop.photometry.PhotometryFlags`.
    - Sources recentering using `~photutils.centroids` methods. Only performed
      if `recenter_limit` is not None.

    Most of the reduction is based on Astropy workshop sample notebooks [1]_.

    Parameters
    ----------
    data : `~numpy.ndarray`
        2D image data for photometry
    x, y : array_like
        Positions of the sources
    r : float, `'auto'` (optional)
        Aperture radius, in pixels. If 'auto', the value will be estimated
        based in the median gaussian FWHM of the sources in the image
        (r=0.6731*GFWHM).
        Default: 'auto'
    r_ann : array_like([float, float]), `'auto'` `None` (optional)
        Annulus radii (r_in, r_out) for local background extraction in pixels.
        If 'auto', the annulus will be set based on aperture as (4*r, 6*r).
        If None, no local background subtraction will be performed.
        Default: 'auto'
    recenter_limit : float (optional)
        Maximum distance allowed to recenter the apertures. If None, no
        recentering will be performed.
        Default: `None`
    recenter_method : 'com', 'gaussian' or 'quadratic' (optional)
        Algorithm to recenter the apertures. If None, no recentering will be
        performed. `'com'` method will use the center of mass of the aperture,
        `'gaussian'` will use a gaussian fit to the aperture and `'quadratic'`
        will use a quadratic fit to the aperture. See `~photutils.centroids`
        for more information.
        Default: 'com'
    gain : float (optional)
        Gain to correctly calculate the error.
        Default: 1.0
    bkg_error : float or `~numpy.ndarray` (optional)
        1-sigma gaussian error of the background-only error of input data.
        If None, zero will be used.
        Default: `None`
    mask : `~numpy.ndarray` (optional)
        Mask badpixels and problematic ccd areas.
        Default: `None`
    pixel_flags : `~numpy.ndarray` (optional)
        Array with flags for each pixel. If None, no flags will be used.
        Flags must follow the `~astropop.frametada.PixelMaskFlags` standard.
        Default: `None`
    bkg_method : 'mmm', 'mode', 'median' or 'mean' (optional)
        Algorith to calculate the background value. `'mode'` or `'mmm'`
        (mean, median, mode) are computed as (3*median - 2*mean) and
        should be better for populated fields. `'median'` and `'mean'`
        just compute these values in the annulus. All algorithms can use sigma
        clipping if ``bkg_sigma_clip`` is not None.
        Default: 'mmm'
    bkg_sigma_clip : float, tuple(float, float) or `None` (optional)
        Sigma clipping values for background calculation. If a tuple is
        provided, the first value will be used as lower sigma and the second
        as upper sigma. Only used if ``sky_algorithm='sigmaclip'``.
        Default: 3.0
    box_size : int (optional)
        Box size for median FWHM computation. Default is 11.

    Returns
    -------
    res_ap : `~astropy.table.Table`
        Table containing all aperture photometry informations.
        - ``x``, ``y``: centroids of the sources. If recentering is performed,
            these values will be different from input.
        - ``aperture``: aperture radius. Same for all sources.
        - ``flux``: flux of the sources with bkg subtracted
        - ``flux_error``: flux error of the sources with bkg subtracted
        - ``aperture_area``: effective aperture (considering mask) of the
          sources.
        - ``bkg``: background value by pixel
        - ``bkg_stddev``: background standard deviation inside the annulus
        - ``bkg_area``: effective area of the annulus (considering mask and
          clipping)
        - ``flags``: flag for the sources
        - ``original_x``, ``original_y``: original input positions
        The metadata of the table will contain the following information:
        - ``photutils``: photutils version used
        - ``astropy``: astropy version used
        - ``astropop``: astropop version used
        - ``fwhm``: median FWHM of the sources
        - ``r``: aperture radius used
        - ``r_in``: inner annulus radius used
        - ``r_out``: outer annulus radius used

    Notes
    -----
    - The input data is divided by the gain prior to any calculation.
    - The centroid of the sources is computed within a circular footprint with
      radius ``2*r+1``. See `~photutils.centroids.centroid_sources` for more
      information.
    - Local background subtraction is performed entirely by photutils. So,
      we do not touch it or compute any errors here.

    References
    ----------
    .. [1] Astropy workshop sample notebook
        (https://github.com/astropy/astropy-workshop/blob/9eec8aeb04cec0de4ae\
         8a5056449b92ca4019e16/09-Photutils/03-aperture_local_bkgsub.ipynb)


Estimate the background and noise values in a image.

    The used algorithm is described by `photutils.background.Background2D`. It
    splits the image into boxes of size `box_size` and calculate the
    background and noise in each box. The final background and noise values
    are interpolated using `filter_size` neighboring boxes.

    Parameters
    ----------
    data: array_like
        2D array containing the image to extract the background.
    box_size: `int` (optional)
        Size of background boxes in pixels.
        Default: 64
    filter_size: `int` (optional)
        Filter size in boxes unit.
        Default: 3
    mask: array_like (optional)
        Boolean mask where 1 pixels are masked out in the background
        calculation.
        Default: `None`
    sigma_clip: `float` or `tuple` (optional)
        Sigma clipping value. If a tuple is given, the first value is the
        lower sigma and the second is the upper sigma.
    bkg_method: ``'mode'``, ``'mean'``, ``'median'`` (optional)
        Method to calculate the background. By ``'mode'`` it uses the
        `~photutils.background.SExtractorBackground` algorithm. ``'mean'`` and
        ``'median'`` uses `~photutils.background.MeanBackground` and
        `~photutils.background.MedianBackground` respectively.
        Default: ``'mode'``
    rms_method: ``'std'``, ``'mad_std'`` (optional)
        Method to calculate the rms. ``'std'`` uses the standard deviation
        and ``'mad_std'`` uses the median absolute deviation.
        Default: ``'std'``
    global_bkg: `bool`
        If True, the algorithm returns a single value for background and rms,
        else, a 2D image with local values will be returned. The global value
        is computed as the median of the 2D local values.
        Default: True

    Returns
    -------
    background: `float` or `~numpy.ndarray`
        Background value or image.
    rms: `float` or `~numpy.ndarray`
        RMS value or image.


Partial derivative of x**y in x.


Partial derivative of x**y in y.


Partial derivative of x%y in y.


Propagate errors using function derivatives.

    Parameters
    ----------
    func: string
        Function name to perform error propagation. Must be in derivatives
        keys.
    fx: float or array_like
        Numerical result of f(x, y).
    x: float or array_like
        Variable of the function.
    sx: float or array_like
        1-sigma errors of the function variable.

    Returns
    -------
    sf: float or array_like
        1-sigma uncorrelated error associated to the operation.


Propagate errors using function derivatives.

    Parameters
    ----------
    func: string
        Function name to perform error propagation. Must be in derivatives
        keys.
    fxy: float or array_like
        Numerical result of f(x, y).
    x, y: float or array_like
        Variables of the function.
    sx, sy: float or array_like
        1-sigma errors of the function variables.

    Returns
    -------
    sf: float or array_like
        1-sigma uncorrelated error associated to the operation.


Create a function to compute a numerical derivative of func.

    Parameters
    ----------
    func: callable
        The function to compute the numerical derivative.
    arg_ref: int or string
        Variable to be used for diferentiation. If int, a position will be
        used. If string, a variable name will be used.
    step: float (optional)
        Epsilon to compute the numerical derivative, using the
        (-epsilon, +epsioln) method.

    Returns
    -------
    derivative_wrapper: callable
        Partial derivative function.

    Notes
    -----
    - Implementation based on `uncertainties` package.


        Partial derivative, calculated with the (-epsilon, +epsilon)
        method, which is more precise than the (0, +epsilon) method.


Simple function to generate a SHA1 hash of a string.

    Parameters:
        - string : string or bytes
            The string to be hashed.
        - size : int
            Size of the output hash string.

    Returns:
        - h : string
            Hash string trunked to size.


Register an __array_function__ implementation for QFloat objects.


Register an ufunc implementation for QFloat objects.


Convert a value to QFloat.

    Notes
    -----
    - The `unit` is extracted from a `unit` attribute in the number.
      If this attribute is not present, the number is considered dimensionless.
    - Compilant classes now are:
        * Python standard numbers;
        * Numpy simple arrays.


Require qfloat as argument decorator.


Round the numbers to the first digit of the error.


Format a qfloat number.


Create an array of _FormaterElements.


Put 2 qfloats in the same unit.


Check if two QFloats are equal within errors.

    Parameters
    ----------
    qf1, qf2: `~astropop.math.QFloat`, `float` or `np.ndarray`
        QFloats to compare.

    Returns
    -------
    bool:
        `True` if the numbers are equal within the uncertainties,
        (the difference is smaller then the sum of errors). `False`
        if they are different.

    Notes
    -----
    - We consider two numbers equal within errors when
      number1 - number2 <= error1 + error2
    - Incompatible units means different numbers.


Create a QFloat from the values.

    Parameters
    ----------
    value: number or array_like
        Nominal value(s) of the quantity.
    uncertainty : number, array_like or `None` (optional)
        Uncertainty value of the quantity. If `None`, the quantity will be
        considered with no errors. Must match `value` shape.
    unit: `~astropy.units.Unit` or string (optional)
        The data unit. Must be `~astropy.units.Unit` compliant.

    Returns
    -------
    f: `~astropop.math.physical.QFloat`
        The QFloat created.


Reset all the data.

        Parameters
        ----------
        value : number or array_like
            Nominal value(s) of the quantity.
        uncertainty : number, array_like or `None` (optional)
            Uncertainty value of the quantity. If `None`, the quantity will be
            considered with no errors. Must match `value` shape.
        unit : `~astropy.units.Unit` or string (optional)
            The data unit. Must be `~astropy.units.Unit` compliant.


Convert this QFloat to another unit.

        Parameters
        ----------
        - unit: string or `~astropy.units.UnitBase`
            Unit to converto to.

        Returns
        -------
        - QFloat:
            A new instance of this class, converted to the new unit.


Wraps simple array functions.

    Notes
    -----
    - Functions elegible for these are that ones who applies for nominal and
      std_dev values and return a new QFloat with the applied values.
    - No conversion or special treatment is done in this wrapper.
    - Only for one array ate once.


Implement np.round for qfloats.


Implement np.append for qfloats.


Implement np.insert for qfloats.


Implement np.sum for qfloats.


Implement np.mean for qfloats.


Implement np.median for qfloats.


Wraps ufuncs only on the nominal value and don't return QFloat.


General implementation for exp and log functions.


Compute the arctangent of qf1/qf2.


Implement ufuncs for general math operations.

    Notes
    -----
    - These functions will not operate with kwarg.
    - These functions will just wrap QFloat math methods.


Return the first argument with the sign of the second argument.


Radial Moffat model.

        Parameters:
        r: float or array
            Radial distance from the center.
        width: float
            Moffat width parameter.
        power: float
            Moffat power parameter.
        flux: float
            Total integrated flux parameter.
        sky: float
            Sky level parameter.

        Returns:
        float or array
            Values of the model at r.


1D Moffat model.

        Parameters:
        x: float or array
            X coordinates to evaluate.
        x0: float
            Center coordinates of the model.
        width: float
            Moffat width parameter.
        power: float
            Moffat power parameter.
        flux: float
            Total integrated flux parameter.
        sky: float
            Sky level parameter.

        Returns:
        float or array
            Values of the model at x.


2D Moffat model.

        Parameters:
        x, y: float or array
            X and Y coordinates to evaluate.
        x0, y0: float
            Center coordinates of the model.
        width: float
            Moffat width parameter.
        power: float
            Moffat power parameter.
        flux: float
            Total integrated flux parameter.
        sky: float
            Sky level parameter.

        Returns:
        float or array
            Values of the model at (x, y).


Radial Gaussian model.

        Parameters:
        r: float or array
            Radial distance from the center.
        flux: float
            Total integrated flux parameter.
        sigma: float
            Gaussian standard deviation parameter.
        sky: float
            Sky level parameter.

        Returns:
        float or array
            Values of the model at r.


1D Gaussian model.

        Parameters:
        x: float or array
            X coordinates to evaluate.
        x0: float
            Center coordinates of the model.
        flux: float
            Total integrated flux parameter.
        sigma: float
            Gaussian standard deviation parameter.
        sky: float
            Sky level parameter.

        Returns:
        float or array
            Values of the model at x.


2D Gaussian model.

        Parameters:
        x, y: float or array
            X and Y coordinates to evaluate.
        x0, y0: float
            Center coordinates of the model.
        sigma_x, sigma_y: float
            Gaussian standard deviation parameters.
        flux: float
            Total integrated flux parameter.
        sky: float
            Sky level parameter.

        Returns:
        float or array
            Values of the model at (x, y).


Trim a numpy array around a position.


Create (x, y) index arrays from a data matrix using IRAF convention.

    Iraf convention means (0, 0) on the center of bottom-left pixel.


Return the version of the solve-field command.


Transform angle in float.


Parse filed center coordinates.


Parse plate scale.


Correspondece `~astropy.table.Table` between image stars and
        ``astrometry.net`` index objects.

        This property is not so smart. It just returns a copy of the table
        passed as input. If this is an ``astrometry.net`` correspondences
        table, it will have the following columns:

        - field_x and field_y
            Image coordinates of each star in the solved image.
        - index_x and index_y
            X and Y coordinates of matched stars in the index file used to
            solve the image.
        - field_ra and field_dec
            Physical RA and DEC solved coordinates of each star in the image.
        - index_ra and index_dec
            Physical RA and DEC of the matched star in the index file used to
            solve the image.


Try to solve an image using the astrometry.net.

        Parameters
        ----------
        filename : str
            Name of the file to be solved. Can be a fits image or a xyls
            sources file.
        options : `dict` (optional)
            Dictionary of ``solve-field`` options. See
            `~astropop.astrometry.astrometrynet.get_options_help` for all
            available options. The most useful are:
            - center or ra and dec: field center
            - radius: maximum search radius
            - scale: pixel scale in arcsec/pixel
            - tweak-order: SIP order to fit
        output_dir : str
            Directory to output all solved files.
        **kwargs :
            Additional keyword arguments to be passed to
            `~astropop.py_utils.run_command`.

        Returns
        -------
        solution : `~astropop.astrometry.AstrometricSolution`
            Astrometric solution class containing the solved header,
            the `~astropy.wcs.WCS` solved class and the correspondence table
            between the sources and the catalog.


Check output directory and create the temporary directory.


Parse and check all known options.


Run the astrometry.net localy using the given params.

        STDOUT and STDERR can be stored in variables for better check after
        using kwargs.


Create and save the xyls file to run in astrometry.net

    Parameters
    ----------
    fname: str
        The path to save the .xyls file.
    x: array_like
        X coordinates of the sources.
    y: array_like
        Y coordinates of the sources.
    flux: array_like
        Estimated flux of the sources.
    imagew: float or int
        Width of the original image. `IMAGEW` header field of .xyls
    imageh: float or int
        Height of the original image. `IMAGEH` header field of .xyls
    dtype: `~numpy.dtype`, optional
        Data type of the fields. Default: 'f8'


Solve astrometry from a (x,y) sources list using astrometry.net.

    Parameters
    ----------
    x: array-like
        x positions of the sources in the image.
    y: array-like
        y positions of the sources in the image.
    flux: array_like
        Estimated fluxes of the sources. A higher value indicates a brighter
        star.
    width: int
        Image width.
    height: int
        Image height.
    image_header: `~astropy.fits.Header` (optional)
        Original image header.
    options: dict
        Dictionary of ``solve-field`` options. See
        `~astropop.astrometry.astrometrynet.print_options_help` for all
        available options. The most useful are:
        - center or ra and dec: field center
        - radius: maximum search radius
        - scale: pixel scale in arcsec/pixel
        - tweak-order: SIP order to fit
        - index-dir: path to index files
    command: str
        Full path of astrometry.net ``solve-field`` command.

    Returns
    -------
    `~astropop.astrometry.AstrometricSolution`
        Astrometric solution ot the field.


Solve astrometry from a `~astropop.framedata.FrameData`.

    Parameters
    ----------
    frame: `~astropop.framedata.FrameData`
        Image to be solved.
    options: dict
        Dictionary of ``solve-field`` options. See
        `~astropop.astrometry.astrometrynet.print_options_help` for all
        available options. The most useful are:
        - center or ra and dec: field center
        - radius: maximum search radius
        - scale: pixel scale in arcsec/pixel
        - tweak-order: SIP order to fit
        - index-dir: path to index files
    command: str
        Full path of astrometry.net ``solve-field`` command.

    Returns
    -------
    `~astropop.astrometry.AstrometricSolution`
        Astrometric solution ot the field.


Solve astrometry from an image using astrometry.net.

    Parameters
    ----------
    filename: str
        Path to the image to solve.
    options: dict
        Dictionary of ``solve-field`` options. See
        `~astropop.astrometry.astrometrynet.print_options_help` for all
        available options. The most useful are:
        - center or ra and dec: field center
        - radius: maximum search radius
        - scale: pixel scale in arcsec/pixel
        - tweak-order: SIP order to fit
        - index-dir: path to index files
    command: str
        Full path of astrometry.net ``solve-field`` command.

    Returns
    -------
    `~astropop.astrometry.AstrometricSolution`
        Astrometric solution ot the field.


Solve astrometry from a `~astropy.fits.ImageHDU` using astrometry.net.

    Parameters
    ----------
    hdu: `astropy.fits.ImageHDU`
        FITS hdu containing the image to solve.
    options: dict
        Dictionary of ``solve-field`` options. See
        `~astropop.astrometry.astrometrynet.print_options_help` for all
        available options. The most useful are:
        - center or ra and dec: field center
        - radius: maximum search radius
        - scale: pixel scale in arcsec/pixel
        - tweak-order: SIP order to fit
        - index-dir: path to index files
    command: str
        Full path of astrometry.net ``solve-field`` command.

    Returns
    -------
    `~astropop.astrometry.AstrometricSolution`
        Astrometric solution ot the field.


Try to guess the format or ra and dec passed.


Create WCS based on coordinates and plate scale.

    x, y: float, pixel coordinates in image
    ra, dec: float, sky coordinates

    plate_scale in arcsec/pix

    north direction can be angles ('cw', from top axis) or
    ['right', 'top', 'left', 'bottom'] to angles [270, 0, 90, 180].

    flip means if some direction is mirrored in image.
    Can be 'ra', 'dec', 'all' or None
    The standard coordinates are ra and dec in the following order, ccw:
    W - N - E - S

    Coordinate values grow to E and N.

    Problems:
    This algorith is not good for coordinates far from crpix. But is useful
    when you cannot solve with other algorithms. (Like just one star in field).


Print the help for a catalog.


Get the available filters.


Get the qfloat magnitudes.


Get the SkyCoord coordinates.


Get the id names for the objects.


Get the epoch for the coordinates.


Retry a function until MAX_RETRIES_TIMEOUT is reached.


Fix bytes and objects columns to strings.


Translate center coordinates to SkyCoord object.

    Notes
    -----
    - The supported formats are:
        - `str` or `bytes`: can be an object  name or
          `~astropy.coordinates.SkyCoord` compatible RA/DEC string.
        - `list`, `tuple` or `~numpy.array`: pair (RA, DEC) coordinates.
          Must be `~astropy.coordinates.SkyCoord` compatible.
        - `~astropy.coordinates.SkyCoord` object it self.


Convert several types of values to angle radius.

    Notes
    -----
    - Current supported types are:
      - Numbers (float or int) are interpreted as decimal degree
      - `str` or `bytes` that can be converted to `astropy.coordinates.Angle`.


Query an region using astroquery.


Query name ids for a star in Simbad. See simbad_query_id.

    Parameters
    ----------
    ra, dec : `float`
        RA and DEC decimal degrees coordinates to query.
    limit_angle : string, float, `~astropy.coordinates.Angle`
        Maximum radius for search. If a string value is passed, it must be
        readable by astropy.coordinates.Angle. If a float value is passed,
        it will be interpreted as a decimal degree radius.
    name_order : `list`, optional
        Order of priority of name prefixes to query. None will use the default
        order of ['MAIN_ID', 'NAME', 'HD', 'HR', 'HYP', 'TYC', 'AAVSO'].
        Default: None

    Returns
    -------
    `str` or list(`str`)
        The ID of each object queried. If a single object is queried,
        a string is returned. If a list of objects is queried, a list
        of strings is returned.


Query name ids for a star in Simbad.

    Parameters
    ----------
    ra, dec : `float` or list(`float`)
        RA and DEC decimal degrees coordinates to query. If more than one
        object is queried, ra and dec must be lists of the same length.
    limit_angle : string, float, `~astropy.coordinates.Angle`
        Maximum radius for search.
    name_order : `list`, optional
        Order of priority of name prefixes to query. None will use the default
        order of ['MAIN_ID', 'NAME', 'HD', 'HR', 'HYP', 'TYC', 'AAVSO'].
        Default: None

    Returns
    -------
    `str` or list(`str`)
        The ID of each object queried. If a single object is queried,
        a string is returned. If a list of objects is queried, a list
        of strings is returned.


Add a mag to the magnitude dict.


Ensure there is a mags_table and band is in it.


Get the sources magnitude in QFloat format.

        Parameters
        ----------
        band : str
            The band name.

        Returns
        -------
        mag : float
            The sources magnitude in QFloat format.


Get the sources photometric mag in [(mag, mag_error)] format.

        Parameters
        ----------
        band : str
            The band name.

        Returns
        -------
        mag_list : list
            List of tuples of (mag, mag_error).


Extract coordinates in the form of a table.

        Nulls is a list of indexes to be set to a nan value.


Find catalog objects matching the given coordinates.

        The matching is performed by getting the nearest catalog object from
        the ra, dec coordinate within the limit angle. No additional matching
        criteria is used.

        Parameters
        ----------
        ra, dec: float or array-like
            RA and Dec coordinates of the objects to be matched to this
            catalog. All coordinates in decimal degree format.
        limit_angle: string, float, `~astropy.coordinates.Angle`
            Angle limit for matching indexes. If string, if must be
            `~astropy.coordinates.Angle` compatible. If float, it will be
            interpreted as a decimal degree.
        obstime: `~astropy.time.Time` (optional)
            Observation time. If passed, it will be used to apply the proper
            motion to the coordinates, if available.
            Default: None


This catalog in a `~astropy.table.Table` instance.


Setup and check available filters.


Return the parallax for the sources.


Return the radial velocity for the sources.


Construct the query and launch job. Good for max_g_mag filtering.


Writes a fits file and adds header and metadata when necessary.

    Parameters
    ----------
    data : ndarray
        image to save
    filepath : string
        path to save the file, include filename
    header : astropy hdu.header
        astropy hdu.header
    metadata : list
        list of MetaDataEntry objects that will get added to header

    Returns
    -------
    filepath : string


Write all fits files in a directory to an image cube.

    Directory can *only* contain fits files, and only files that you want in the cube. Subdirectories will be ignored.

    Parameters
    ----------
    path : string
        path to directory that contains all fits files that should be put into cube; cube gets saved into that same directory


Create a circle on array im centered on xc, yc with radius rcirc; inside circle equals 1.


Cut out a square box from image im centered on (x,y) with half-box size bb.

    Parameters
    ----------
    im : ndarray
        image from which box will be taken
    x : int
        x coordinate of center of box
    y : int
        y coordinate of center of box
    bb : int
        half-box size

    Returns
    -------
    ndarray
        zoomed-in version of input image


Cut out a square box from the image center with half-box size bb.

    Parameters
    ----------
    im : ndarray
        image from which box will be taken
    bb : int
        half-box size

    Returns
    -------
    ndarray
        zoomed-in version of input image


Create a dark hole on pupil image pup_im.

    Parameters
    ----------
    pup_im : ndarray
        pupil image
    iwa : float
        inner working angle in lambda/D
    owa : float
        outer working angle in lambda/D
    samp : float
        sampling factor

    Returns
    -------
    dh_area : ndarray
        DH mask


Return the dark hole contrast.

    Calculate the mean intensity in the dark hole area dh of the image im.
    im and dh have to have the same array size and shape.

    Parameters
    ----------
    im : ndarray or Field
        normalized (by direct PSF peak pixel) image
    dh : ndarray or Field
        dark hole mask

    Returns
    -------
    con : float
        DH mean contrast


Calculate the contrast with PASTIS matrix model.

    Parameters
    ----------
    aber : ndarray of astropy quantities
        aberration vector, its length is number of segments, WFE aberration coefficients in NANOMETERS
    matrix_pastis : ndarray
        PASTIS matrix, in contrast/nm^2

    Returns
    -------
    float
        mean contrast in DH for segments aberrated with 'aber'


Analytically calculate the *statistical* mean contrast for a set of segment requirements.

    Parameters
    ----------
    pastismatrix : ndarray
        PASTIS matrix [segs, modes]
    cov_segments : ndarray
        segment-space covariance matrix Ca
    coro_floor : float
        coronagrpah contrast in absence of aberrations

    Returns
    -------
    mean_c_stat : float
        Statistical mean contrast for set of segment reuqirements.


Analytically calculate the variance of the *statistical* mean contrast for a set of segment requirements.

    Parameters
    ----------
    pastismatrix : ndarray
        PASTIS matrix [segs, modes]
    cov_segments : ndarray
        segment-space covariance matrix Ca

    Returns
    -------
    var : float
        variance of statistical mean contrast for set of segment requirements


Apply a PASTIS mode to the segmented mirror (SM) and return the propagated wavefront "through" the SM.

    This function first flattens the segmented mirror and then applies all segment coefficients from the input mode
    one by one to the segmented mirror.

    Parameters
    ----------
    pmode : ndarray
        a single PASTIS mode [nseg] or any other segment phase map in NANOMETERS WFE
    luvoir : LuvoirAPLC
        LuvoirAPLC instance

    Returns
    -------
    hcipy.Wavefront
        wavefront of the segmented mirror
    hcipy.Wavefront
        wavefront of the detector plane


Return a generator with all possible segment pairs, including repeating ones.

    E.g. if segments are 0, 1, 2, then the returned pairs will be:
    00, 01, 02, 10, 11, 12, 20, 21, 22

    Parameters
    ----------
    nseg : int
        number of segments

    Returns
    -------
    generator
        all possible segment pairs, including repeating ones


Return a generator with all possible non-repeating segment pairs.

    E.g. if segments are 0, 1, 2, then the returned pairs will be:
    00, 01, 02, 11, 12, 22

    Parameters
    ----------
    nseg : int
        number of segments

    Returns
    -------
    generator
        all possible non-repeating segment pairs


Calculate the total number of measurements needed for a PASTIS matrix with nseg segments

    Parameters
    ----------
    nseg : int
        total number of segments

    Returns
    -------
    int
        total number of measurements


    Return a symmetrized version of NumPy array a.

    Values 0 are replaced by the array value at the symmetric
    position (with respect to the diagonal), i.e. if a_ij = 0,
    then the returned array a' is such that a'_ij = a_ji.
    Diagonal values are left untouched.
    :param array: square NumPy array, such that a_ij = 0 or a_ji = 0,
    for i != j.

    Source:
    https://stackoverflow.com/a/2573982/10112569


Read the coro floor as float from the output file in the data directory.

    Parameters
    ----------
    datadir : string
        path to data directory

    Returns
    -------
    float
        coronagraph floor read from file


Manual root-mean-square calculation, assuming a zero-mean

    Parameters
    ----------
    ar : ndarray
        data to calculate the rms for

    Returns
    -------
    rms : float
        rms value


Calculate a set of random segment aberration values scaled to a total WFE rms (input: total_rms).

    Also subtracts global piston.

    Parameters
    ----------
    nb_seg : int
        number of segments in the pupil
    total_rms : astropy quantity
        WFE rms that the aberration array will be scaled to

    Returns
    -------
    aber : ndarray
        array of segment aberration values in nm (astropy units) of WFE rms, scaled to input rms value (total_rms)


Convert phase aberration in rad to OPD in meters.

    Parameters
    ----------
    aber_rad : float
        phase aberration in radians
    wvln : float
        wavelength in meters

    Returns
    -------
    aber_m : float
        OPD in meters


Transform a Noll Zernike index into a JWST WSS framework Zernike index.

    Parameters
    ----------
    zern : int
        Noll Zernike index

    Returns
    -------
    wss_ind : int
        WSS Zernike index


Transform a JWST WSS framework Zernike index into a Noll Zernike index.

    Parameters
    ----------
    zern : int
        WSS Zernike index

    Returns
    -------
    noll_ind : int
        Noll Zernike index


Get the name of the Zernike with input index in input framework (Noll or WSS).

    Parameters
    ----------
    index : int
        Zernike index
    framework : string, default 'Noll'
        'Noll' or 'WSS' for Zernike ordering framework

    Returns
    -------
    zern_name : string
        name of the Zernike in the chosen framework


Change form Noll to WSS Zernike index.


Change from WSS to Noll Zernike index.


Will create a timestamp and join it to the output_path found in the INI.

    Parameters
    ----------
    initial_path : string
        output directory as defined in the configfile
    telescope : string
        telescope name that gets added to data path name; somewhat redundant with suffix
    suffix : string
        appends this to the end of the timestamp (ex: 2017-06-15T121212_suffix), also read from config

    Returns
    -------
    full_path : string
        path with the final folder containing a timestamp of the current datetime


Copy the config_local, or if non-existent, config_pastis.ini to outdir

    Parameters
    ----------
    outdir : string
        target location of copied configfile


Write the title page as PDF to disk.

    Parameters
    ----------
    instrument : string
        'LUVOIR' or 'HiCAT'
    datadir : string
        read data location
    itemlist : list
        list of strings to add to the title page


Collect all the items from the data directory and return as list of strings for title page.

    Will skip README if none exists.

    Parameters
    ----------
    datadir : string
        read data location
    c_target : float
        target contrast

    Returns
    -------
    read_list : list
        list of files as string


Create and write to disk a PDF file with all PDF figures and a title page.

    Parameters
    ----------
    datadir : string
        read data directory
    c_target : float
        target contrast - beware of formatting differences (usually good: e.g. 1e-07, 1e-10, etc.)


Read one of the custom text files that contain a mean value and variance from a custom text file
    and return the mean and variance.

    Parameters
    ----------
    filename : string
        full path including file name of the txt file to be read

    Returns
    -------
    mean_value : float
        mean
    variance_value : float
        variance


Find absolute path to repository location on disk

    Taken from hicat-package/hicat/util.py

    Parameters
    ----------
    package : string
        name of package within the repository whose path we are looking for

    Returns
    -------
    string
        absolute path to repository location on disk


Convert single index of DM actuator to x|y DM coordinates.

    This assumes the actuators to be arranged on a square grid.

    Parameters
    ----------
    actuator_total : int
        total number of actuators in each line of the (square) DM
    segment : int
        single-index actuator number on the DM, to be converted to x|y coordinate

    Returns
    -------
    int
        x coordinate
    int
        y coordinate


Sorts one-dimensional multi-mode coefficients into 'nmodes-multimode' groups.

    The result sorts the mode coefficients in a 2D array, with the dimensions representing the number of modes
    and number of segments, respectively.

    The input mode coefficients 'mus' need to be grouped by segment, meaning the array holds
    the mode coefficients as:
        mode1 on seg1, mode2 on seg1, ..., mode'nmodes' on seg1, mode1 on seg2, mode2 on seg2 and so on.

    Parameters
    ----------
    mus : 1d-array
        1d array of standard deviations for all modes on each segment, in nm
    nmodes : int
        number of individual modes per segment
    nseg : int
        number of segments

    Returns
    -------
    coeffs_table : 2d-array
        groups of single-mode coefficients for all segments.


Sorts one-dimensional multi-mode tolerance values into an actuator array for the internal simulators.

    The resulting array sorts the mode coefficients into a 2D array, with the dimensions representing the number of
    input mode and number of actuators, respectively. Each row of the 2D output array (first index) is a valid array to
    be passed directly to the actuators of a segmented mirror of an internal simulator.
    Following the convention of the internal simulators, the number of actuators is calculated as the product of local
    modes times all segments.

    The input mode coefficients 'mus' need to be grouped by segment, meaning the array holds
    the mode coefficients as:
        mode1 on seg1, mode2 on seg1, ..., mode'nmodes' on seg1, mode1 on seg2, mode2 on seg2 and so on.

    Parameters
    ----------
    mus : 1d-darray
        1d array of standard deviations for all modes on each segment, in nm
    nmodes : int
        number of individual modes per segment
    nseg : int
        number of segments

    Returns
    -------
    coeffs_mumaps : 2d-darray
        actuator holding mode coefficients array whose rows (first index) can be directly passed to the actuators of a
        segmented mirror of an internal simulator


Save results from matrix calculation to class attributes.


Calculate the contrast for an RMS WFE with image PASTIS, matrix PASTIS

    Parameters
    ----------
    matdir : string
        data directory to use for matrix and calibration coefficients from
    matrix_mode : string, default "analytical"
        Whether to use "analytical" or "numerical" matrix
    rms : float
        RMS wavefront error in pupil to calculate contrast for; in NANOMETERS
    im_pastis : bool, default Fals
        whether to also calculate contrast from image PASTIS
    plotting : bool, default False
        whether to save E2E and PASTIS DH PSFs; works only if im_pastis=True

    Returns
    -------
    contrast_webbpsf, contrast_am, contrast_matrix : float


Compute the contrast for a random IrisAO misalignment on the HiCAT simulator.

    Parameters
    ----------
    coro_floor : float
        coronagraph contrast floor
    norm : float
        normalization factor for PSFs: peak of unaberrated direct PSF
    matrix_dir : string
        read directory of saved matrix
    rms : astropy quantity
        E2E and matrix contrast, both floats

    Returns
    -------
    contrast_hicat, contrast_matrix : float


Compute the contrast for a random segmented mirror misalignment on the LUVOIR simulator.

    Parameters
    ----------
    coro_floor : float
        coronagraph contrast floor
    norm : float
        normalization factor for PSFs: peak of unaberrated direct PSF
    design : string
        which LUVOIR APLC design to use, "small", "medium" or "large"
    matrix_dir : string
        read directory of saved matrix
    rms : astropy quantity
        WFE rms (OPD) to be put randomly over the entire segmented mirror

    Returns
    -------
    contrast_luvoir : float
        E2E contrast
    contrast_matrix : float
        matrix contrast


Compute the contrast for a random segmented OTE misalignment on the JWST simulator.

    Parameters
    ----------
    coro_floor : float
        coronagraph contrast floor
    norm : float
        normalization factor for PSFs: peak of unaberrated direct PSF
    matrix_dir : string
        read directory of saved matrix
    rms : astropy quantity
        WFE rms (OPD) to be put randomly over the entire segmented mirror

    Returns
    -------
    contrast_jwst : float
        E2E contrast
    contrast_matrix : float
        matrix contrast


Compute the contrast for a random aberration over all DM actuators in the RST simulator.

    Parameters
    ----------
    coro_floor : float
        coronagraph contrast floor
    norm : float
        normalization factor for PSFs: peak of unaberrated direct PSF
    matrix_dir : string
        read directory of saved matrix
    rms : astropy quantity
        WFE rms (OPD) to be put randomly over the entire continuous mirror

    Returns
    -------
    contrast_rst : float
        E2E contrast
    contrast_matrix : float
        matrix contrast


Calculate the mode weight sigma assuming a single-mode error budget.

    Parameters
    ----------
    c_target : float
        overall target contrast
    c_floor : float
        coronagraph contrast floor
    evalue : float
        PASTIS eigenvalue of the mode weight to be calculated

    Returns
    -------
    sigma : float
        mode weight


Calculate the contrast stemming from one weighted PASTIS mode.

    Parameters
    ----------
    sigma : float
        mode weight for the mode with index single_mode
    pmodes : ndarray
        all PASTIS modes
    single_mode : int
        mode index of mode to weight and calculate contrast for
    luvoir : LuvoirAPLC
        LuvoirAPLC simulator instance

    Returns
    -------
    float
        DH mean contrast for weighted PASTIS mode


Calculate and plot single-mode error budget, for onde PASTIS mode.

    Calculate the mode weight and consecutive contrast for a range of target contrasts
    and plot the recovered contrasts against the target contrasts.

    Parameters
    ----------
    design : string
        "small", "medium" or "large" LUVOIR-A APLC design
    run_choice : string
        read path to data
    c_target : float, default 1e-1-
        target contrast
    single_mode : int, default None
        mode index for single mode error budget

    Returns
    -------


Plot a PASTIS matrix.

    Parameters
    ----------
    pastis_matrix : ndarray
        PASTIS matrix in units of contrast/nm**2
    wvln : float, default None
        Wavelength at which the PASTIS matrix was generated in nm. If provided, converts PASTIS matrix to units of
        contrast/wave^2, if None it stays in contrast/nm^2.
    out_dir : string
        output path to save the figure to if save=True
    fname_suffix : string
        optional, suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Plot a hockeystick curve comparing the optical propagation between semi-analytical PASTIS and end-to-end simulator.

    Parameters
    ----------
    rms_range : ndarray or list
        list of RMS values in nm
    pastis_matrix_contrasts : ndarray or list
        contrast values from SA PASTIS
    e2e_contrasts : ndarray or list
        contrast values from E2E simulator
    wvln : float, default None
        Wavelength at which the PASTIS matrix was generated in nm. If provided, converts rms_range (x-axis) to units
        of waves, if None it stays in nm.
    out_dir : string
        output path to save the figure to if save=True
    fname_suffix : string, default empty
        suffix to add to the saved file name
    xlim : tuple, default None
        limits of x-axis
    ylim : tuple, default None
        limits of y-axis
    save : bool, default False
        whether to save to disk


Plot PASTIS eigenvalues as function of PASTIS mode index.

    Parameters
    ----------
    eigenvalues : ndarray or list
        list of eigenvalues of the PASTIS matrix, in units of contrast/nm**2
    nseg : int
        number of segments/modes
    wvln : float, default None
        Wavelength at which the PASTIS matrix was generated in nm. If provided, converts eiganvalues to units of
        contrast/wave^2, if None they stay in contrast/nm^2.
    out_dir : string
        output path to save the figure to if save=True
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save to disk


Plot mode weights against mode index, with mode weights in units of waves.

    Parameters
    ----------
    sigmas : ndarray or list or tuple
        array or list, or tuple of arrays or lists of mode weights, in nm
    c_target : float
        target contrast for which the mode weights have been calculated
    wvln : float, default None
        Wavelength at which the PASTIS matrix was generated in nm. If provided, converts mode weights (sigmas) to units
        of waves, if None they stay in nm.
    out_dir : string
        output path to save the figure to if save=True
    fname_suffix : string, default empty
        suffix to add to the saved file name
    labels : tuple, default None
        labels for the different lists of sigmas provided
    save : bool, default False
        whether to save plot to disk


Plot mode weights against mode index, both in units of nm and waves, on a double y-axis.

    Parameters
    ----------
    sigmas : ndarray or list or tuple
        array or list, or tuple of arrays or lists of mode weights, in nm
    wvln : float
        wavelength at which the PASTIS matrix was generated, in nm
    out_dir : string
        output path to save the figure to if save=True
    c_target : float
        target contrast for which the mode weights have been calculated
    fname_suffix : string, default empty
        suffix to add to the saved file name
    labels : tuple, default None
        labels for the different lists of sigmas provided
    alphas : tuple, default None
        transparency factors (0-1) for the different lists of sigmas provided
    linestyles : tuple, default None
        matplotlib linestyles for the different lists of sigmas provided
    colors : tuple, default None
        colors for the different lists of sigmas provided
    save : bool, default False
        whether to save plot to disk


Returns WFE in waves given the wavelength.


Update second axis according with first axis.


Plot cumulative contrast plot to verify accuracy between SA PASTIS propagation and E2E propagation.

    Parameters
    ----------
    cumulative_c_pastis : ndarray or list
        contrast values from SA PASTIS
    cumulative_c_e2e : ndarray or list
        contrast values from E2E simulator
    out_dir : string
        output path to save the figure to if save=True
    coro_floor : float
        contrast floor in absence of aberrations
    c_target : float
        target contrast for which the mode weights have been calculated
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Plot cumulative contrast plot, comparing segment-based and uniform error budget.

    Parameters
    ----------
    segment_based_cumulative_c : ndarray or list
        contrast values from segment-based error budget
    uniform_cumulative_c_e2e : ndarray or list
        contrast values from uniform error budget
    out_dir : string
        output path to save the figure to if save=True
    c_target : float
        target contrast for which the mode weights have been calculated
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Plot covariance matrix of a particular error budget and for a particular target contrast.

    Parameters
    ----------
    covariance_matrix : ndarray
        covariance matrix in contrast/nm^2
    out_dir : string
        output path to save the figure to if save=True
    c_target : float
        target contrast for which the covariance matrix has been calculated
    segment_space : bool, default True
        is this a segment-space covariance matrix or not (if not, then it is mode-space)
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Plot segment weights against segment index, in units of picometers (converted from input).

    Parameters
    ----------
    mus : ndarray or list
        array or list of arrays, segment requirements in nm
    out_dir : string
        output path to save the figure to if save=True
    c_target : float
        target contrast for which the mode weights have been calculated
    labels : list, default None
        labels for the different lists of sigmas provided
    fname : string, default None
        file name to save plot to
    save : bool, default False
        whether to save plot to disk


Plot the segment requirement map for a specific target contrast.

    Parameters
    ----------
    instrument : string
        "LUVOIR", "HiCAT" or "JWST"
    mus : ndarray or list
        segment requirements (standard deviations) in nm WFE
    sim_instance : instance of the simulator for "instrument"
        instance of the simulator for "instrument"
    out_dir : string
        output path to save the figure to if save=True
    c_target : float
        target contrast for which the segment requirements have been calculated
    limits : tuple or list, default None
        colorbar limits
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Calculate the phase maps in radians of a set of PASTIS modes.

    Parameters
    ----------
    pastis_modes : ndarray
        PASTIS modes [seg, mode] in nm
    design : string
        "small", "medium", or "large" LUVOIR-A APLC design

    Returns
    -------
    all_modes : ndarray
        array of phase pupil images


Plot all PATIS modes onto a grid.

    Parameters
    ----------
    pastis_modes : ndarray
        PASTIS modes [seg, mode] in nm
    out_dir : string
        output path to save the figure to if save=True
    design : string
        "small", "medium", or "large" LUVOIR-A APLC design
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Plot a single PASTIS mode.

    Parameters
    ----------
    mode_nr : int
        mode index
    pastis_modes : ndarray
        PASTIS modes [seg, mode] in nm
    out_dir : string
        output path to save the figure to if save=True
    design : string
        "small", "medium", or "large" LUVOIR-A APLC design
    figsize : tuple, default=(8.5,8.5)
        size of figure
    vmin : float, default None
        matplotlib min extent of image
    vmax : float, default None
        matplotlib max extent of image
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Plot histogram of Monte Carlo simulation for contrasts.

    Parameters
    ----------
    random_contrasts : ndarray or list
        contrasts calculated by random WFE realizations
    out_dir : string
        output path to save the figure to if save=True
    c_target : float
        target contrast for which the Monte Carlo simulation was run
    segments : bool, default True
        whether run with segment (True) or mode requirements (False)
    stddev : float, default None
        analytically calculated standard deviation of the contrast distribution
    plot_empirical_stats : bool, default False
        whether to plot the empirical mean and standard deviation from the data
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Plot contrast per mode, after subtracting the coronagraph floor.

    Parameters
    ----------
    contrasts_per_mode : ndarray or list
        contrast contribution per mode from optical propagation
    coro_floor : float
        contrast floor in absence of aberrations
    c_target : float
        target contrast for which the mode weights have been calculated
    nmodes : int
        number of modes/segments
    out_dir : string
        output path to save the figure to if save=True
    fname_suffix : string, default empty
        suffix to add to the saved file name
    save : bool, default False
        whether to save plot to disk


Create animation of the contrast matrix generation and save to MP4 file.

    Parameters
    ----------
    data_path : string
        absolute path to main PASTIS directory containing all subdirs, e.g. "matrix_numerical"
    instrument : string
        "LUVOIR" or "HiCAT"
    design : string, default 'small'
        necessary if instrument='LUVOIR', defaults to "small" - LUVOIR APLC design choice
    display_mode : string, default 'stretch'
        'boxy' for two panels on top, one on bottom, 'stretch' for all three panels in one row


Create animation of the drawing of a random WFE map following the my map, and save to MP4 file.

    Parameters
    ----------
    data_path : string
        absolute path to the directory that contains the segment requirements txt file
    c_target : float
        target contrast the segment constraints were calculated for
    instrument : string
        "LUVOIR"
    design : string, default 'small'
        necessary if instrument='LUVOIR', defaults to "small" - LUVOIR APLC design choice
    display_mode : string, default 'stretch'
        'boxy' for two panels on top, one on bottom, 'stretch' for all three panels in one row


Read OTE fits files from a PASTIS matrix calculation and return as list of arrays.

    Parameters
    ----------
    data_path : string
        path to PASTIS folder containing subdir "matrix_numerical" ff

    Returns
    -------
    all_ote_images : list
        list of image arrays


Read PSF fits files from a PASTIS matrix calculation and return as list of arrays.

    Parameters
    ----------
    data_path : string
        path to PASTIS folder containing subdir "matrix_numerical" ff

    Returns
    -------
    all_psf_images : list
        list of image arrays


Creates surface deformation maps (not WFE) for localized wavefront aberrations.

    The input mode coefficients 'mus' are in units of *WFE* and need to be grouped by segment, meaning the array holds
    the mode coefficients as:
        mode1 on seg1, mode2 on seg1, ..., mode'nmodes' on seg1, mode1 on seg2, mode2 on seg2 and so on.

    Parameters:
    -----------
    tel : class instance of internal simulator
        the simulator to plot the surface maps for
    mus : 1d array
        1d array of standard deviations for all modes on each segment, in nm WFE
    num_modes : int
        number of local modes used to poke each segment
    mirror : str
        'harris_seg_mirror' or 'seg_mirror', segmented mirror of simulator 'tel' to use for plotting
    cmin : float
        minimum value for colorbar
    cmax : float
        maximum value for colorbar
    data_dir : str, default None
        path to save the plots; if None, then not saved to disk
    fname : str, default None
        file name for surface maps saved to disk


Construct a PASTIS hockeystick contrast curve for validation of the PASTIS matrix for JWST.

    The aberration range is a fixed parameter in the function body since it depends on the coronagraph (and telescope)
    used. We define how many realizations of a specific rms error we want to run through, and also how many points we
    want to fill the aberration range with. At each point we calculate the contrast for all realizations and plot the
    mean of this set of results in a figure that shows contrast vs. rms phase error.

    Parameters
    ----------
    range_points : int, default 3
        How many points of rms error (OPD) to use in the predefined aberration range.
    no_realizations : int, default 3
        How many realizations per rms error (OPD) should be calculated; the mean of the realizations is used.
    matrix_mode : string, default 'analytical'
        Choice of PASTIS matrix to validate: 'analytical' or 'numerical'.


Construct a PASTIS hockeystick contrast curve for validation of the PASTIS matrix, for one particular instrument.

    The aberration range is a fixed parameter in the function body since it depends on the coronagraph (and telescope)
    used. We define how many realizations of a specific WFE rms error we want to run through, and also how many points we
    want to fill the aberration range with. At each point we calculate the contrast for all realizations and plot the
    mean of this set of results in a figure that shows contrast vs. WFE rms error.

    Parameters
    ----------
    instrument : string
        'LUVOIR', 'HiCAT' or 'JWST'
    apodizer_choice : string, default None
        needed if instrument='LUVOIR'; use "small", "medium" or "large" FPM coronagraph
    matrixdir : string
        read path to pastis matrix
    resultdir : string
        path to directory where results will be saved
    range_points : int, default 3
        How many points of WFE rms error to use in the predefined aberration range.
    no_realizations : int, default 3
        How many realizations per WFE rms error should be calculated; the mean of the realizations is used in the plot


Calculate mode basis and singular values from PASTIS matrix using an SVD.

    In the case of the PASTIS matrix, this is equivalent to using an eigendecomposition, because the matrix is
    symmetric. Note how the SVD orders the modes and singular values in reverse order compared to an eigendecomposition.

    Parameters
    ----------
    instrument : string
        "LUVOIR", "HiCAT" or "JWST"
    datadir : string
        path to overall data directory containing matrix and results folder
    saving : bool, default True
        whether to save singular values, modes and their plots or not

    Returns
    -------
    pmodes : ndarray
        pastis modes (which are the singular vectors/eigenvectors)
    svals : ndarray
        singular values/eigenvalues


Read mode basis and singular values of a PASTIS matrix from file.

    Parameters
    ----------
    datadir : string
        path to overall data directory containing matrix and results folder

    Returns
    -------
    pmodes : ndarray
        pastis modes (which are the singular vectors/eigenvectors)
    svals : ndarray
        singular values/eigenvalues


Put all modes onto the segmented mirror in the pupil and get full 2D pastis modes, in pupil plane and focal plane.

    Take the pmodes array of all modes (shape [segnum, modenum] = [nseg, nseg]) and apply them onto a segmented mirror
    in the pupil. This phase gets returned both as an array of 2D arrays.
    Both the pupl plane and the focal plane modes get save into a PDF grid, and as a cube to fits. Optionally, you can
    save the pupil plane modes individually to PDF files by setting saving=True.

    Parameters
    ----------
    instrument : string
        'LUVOIR', 'HiCAT' or 'JWST'
    pmodes : ndarray
        array of PASTIS modes [segnum, modenum], in nanometers
    datadir : string
        path to overall data directory containing matrix and results folder
    sim_instance : instance of the simulator for "instrument"
        instance of the simulator for "instrument"
    saving : bool, default False
        whether to save the individual pupil plane modes as PDFs to disk

    Returns
    -------
    mode_cube : ndarray
        cube of pupil plane modes as array of 2D arrays


Read all modes into an array of hcipy.Fields and an array of 2D arrays.

    Parameters
    ----------
    datadir : string
        path to overall data directory containing matrix and results folder

    Returns
    -------
    all_modes : ndarray
        all pastis modes as an array of Fields
    mode_cube : ndarray
        all pastis modes as a 2D array


Calculate the maximum mode contribution(s) from the static contrast target and the singular values.

    Parameters
    ----------
    cstat : float
        static contrast requirement
    nmodes : int
        number of contributing PASTIS modes we want to calculate the sigmas for
    svalues : float or array
        singular value(s) of the mode(s) we are calculating the sigma(s) for
    c_floor : float
        coronagraph floor (baseline contrast without aberrations)

    Returns
    -------
    sigma : float or array
        maximum mode contribution sigma for each mode


Calculate dynamic contrast contribution of a mode - not tested, not implemented anywhere.

    Parameters
    ----------
    cdyn : float
        dynamic contrast requirement
    nmodes : float
        dynamic contrast requirement
    svalue : float
        singular value of the mode we are calculating delta sigma for

    Returns
    -------
    del_sigma : float
        dynamic contrast contribution


Calculate the cumulative contrast or contrast per mode of a set of PASTIS modes with mode weights sigmas,
    using an E2E simulator.

    Parameters
    ----------
    instrument : string
        'LUVOIR' or 'HiCAT'
    pmodes : ndarray
        PASTIS modes [nseg, nmodes]
    sigmas : ndarray
        weights per PASTIS mode
    sim_instance : instance of the simulator for "instrument"
        instance of the simulator for "instrument"
    dh_mask : hcipy.Field
        dh_mask that goes together with the instance of the LUVOIR simulator
    norm_direct : float
        normalization factor for PSF; peak of unaberrated direct PSF
    individual : bool, default False
        if False, calculates cumulative contrast, if True, calculates contrast per mode

    Returns
    -------
    cont_cum_e2e : list
        list of cumulative or individual contrasts


Calculate the cumulative contrast or contrast per mode of a set of PASTIS modes with mode weights sigmas,
    using PASTIS propagation.

    Parameters
    ----------
    pmodes : ndarray
        PASTIS modes [nseg, nmodes]
    sigmas : ndarray
        weights per PASTIS mode
    matrix : ndarray
        PASTIS matrix [nseg, nseg]
    c_floor : float
        coronagraph contrast floor
    individual : bool, default False
        if False, calculates cumulative contrast, if True, calculates contrast per mode

    Returns
    -------
    cont_cum_pastis : list
        list of cumulative or individual contrasts


Calculate segment-based PASTIS constraints from PASTIS matrix and PASTIS modes.

    Parameters
    ----------
    pastismatrix : ndarray
        full PASTIS matrix [nseg, nseg]
    c_target : float
        static target contrast
    coronagraph_floor : float
        coronagraph contrast floor

    Returns
    -------
    mu_map : ndarray
         map of segment-based PASTIS constraints


Calculate the PSF after applying a randomly weighted set of segment-based PASTIS constraints on the pupil.

    Parameters
    ----------
    instrument : string
        "LUVOIR", "HiCAT" or "JWST"
    sim_instance : instance of the simulator for "instrument"
        instance of the simulator for "instrument"
    mus : ndarray
        segment-based PASTIS constraints in nm
    dh_mask : ndarray
        dark hole mask for PSF produced by/for instrument
    norm_direct : float
        normalization factor for PSF; peak of unaberrated direct PSF

    Returns
    -------
    ndarray
        random segment map used in this PSF calculation in m
    float
        mean contrast of the calculated PSF


Calculate the PSF after weighting the PASTIS modes with weights from a normal distribution with stddev = sigmas.

    Parameters
    ----------
    instrument : string
        "LUVOIR", "HiCAT" or "JWST"
    pmodes : ndarray
        pastis mode matrix [nseg, nmodes]
    sim_instance : instance of the simulator for "instrument"
        instance of the simulator for "instrument"
    sigmas : ndarray
        mode-based PASTIS constraints
    dh_mask : ndarray
        dark hole mask for PSF produced by instrument
    norm_direct : float
        normalization factor for PSF; peak of unaberrated direct PSF

    Returns
    -------
    ndarray
        random weights used in this PSF calculation
    float
        mean contrast of the calculated PSF


Run a full PASTIS analysis on a given PASTIS matrix.

    The first couple of lines contain switches to turn different parts of the analysis on and off. These include:
    1. calculating the PASTIS modes
    2. calculating the PASTIS mode weights sigma under assumption of a uniform contrast allocation across all modes
    3. running an E2E Monte Carlo simulation on the modes with their weights sigma from the uniform contrast allocation
    4. calculating a cumulative contrast plot from the sigmas of the uniform contrast allocation
    5. calculating the segment constraints mu under assumption of uniform statistical contrast contribution across segments
    6. running an E2E Monte Carlo simulation on the segments with their weights mu
    7. calculating the segment- and mode-space covariance matrices Ca and Cb
    8. analytically calculating the statistical mean contrast and its variance
    9. calculating segment-based error budget

    Parameters
    ----------
    instrument : string
        "LUVOIR", "HiCAT" or "JWST"
    run_choice : string
        path to data and where outputs will be saved
    design : string, default None
        "None" means we read from the configfile (if running for LUVOIR):
        what coronagraph design to use - 'small', 'medium' or 'large'
    c_target : float
        target contrast
    n_repeat : int, default 100
        number of realizations in both Monte Carlo simulations (modes and segments)

    Returns
    -------


    :param zernike_pol:
    :param coef:
    :param cali: bool; True if we already have calibration coefficients to use. False if we still need to create them.
    :return:


Main method that calculates the PASTIS matrix


Calculate the contrast matrix.

        Uses the class attribute "self.calculate_matrix_pair", which needs to be a partial function, to calculate the
        PSFs of all pair-wise aberrated segments in the pupil. This is using multiprocessing. The contrast matrix will
        be saved to disk as fits file and as a PDF image.


Take the contrast matrix and calculate the PASTIS matrix from it.


Calculate the direct PSF peak and unaberrated coronagraph floor of an instrument.

    Parameters
    ----------
    instrument : string
        'LUVOIR', 'HiCAT', 'RST' or 'JWST'
    design : string, default None
        Choice of LUVOIR APLC design (small, medium, large), only used for LUVOIR. Default is None, which means we read
        from the configfile.
    return_coro_simulator : bool, default True
        Whether to return the coronagraphic simulator as third return.
    save_coro_floor : bool, default False
        Whether to save coro floor value to txt file.
    save_psfs : bool, default False
        Whether to save direct and coro PSF images to disk.
    outpath : string
        Where to save outputs to if save=True
    Returns
    -------
    contrast floor and PSF normalization factor, and optionally (by default) the simulator in coron mode


Function to calculate JWST mean contrast of one aberrated segment pair in NIRCam; for PastisMatrixIntensities().

    Parameters
    ----------
    norm : float
        Direct PSF normalization factor (peak pixel of direct PSF)
    wfe_aber : float
        Calibration aberration per segment in m
    resDir : string
        Directory for saving matrix calculations
    savepsfs : bool
        If True, all PSFs will be saved to disk individually, as fits files
    saveopds : bool
        If True, all pupil surface maps of aberrated segment pairs will be saved to disk as PDF
    segment_pair : tuple
        Pair of segments to aberrate, 0-indexed. If same segment gets passed in both tuple entries, the segment will be
        aberrated only once.
        Note how JWST segments start numbering at 0 just because that's python indexing, with 0 being the segment A1.

    Returns
    -------
    contrast as float, and segment pair as tuple


Calculate the LUVOIR-A mean contrast of one aberrated segment pair; for PastisMatrixIntensities().

    Parameters
    ----------
    design : string
        what coronagraph design to use - 'small', 'medium' or 'large'
    norm : float
        direct PSF normalization factor (peak pixel of direct PSF)
    wfe_aber : float
        calibration aberration per segment in m
    resDir : string
        directory for saving matrix calculations
    savepsfs : bool
        if True, all PSFs will be saved to disk individually, as fits files
    saveopds : bool
        if True, all pupil surface maps of aberrated segment pairs will be saved to disk as PDF
    segment_pair : tuple
        Pair of segments to aberrate, 0-indexed. If same segment gets passed in both tuple entries, the segment will be
        aberrated only once.
        Note how LUVOIR segments start numbering at 1, with 0 being the center segment that doesn't exist.

    Returns
    -------
    contrast as float, and segment pair as tuple


Function to calculate HiCAT mean contrast of one aberrated segment pair; for PastisMatrixIntensities().

    Parameters
    ----------
    norm : float
        direct PSF normalization factor (peak pixel of direct PSF)
    wfe_aber : float
        calibration aberration per segment in m
    resDir : string
        directory for saving matrix calculations
    savepsfs : bool
        if True, all PSFs will be saved to disk individually, as fits files
    saveopds : bool
        if True, all pupil surface maps of aberrated segment pairs will be saved to disk as PDF
    segment_pair : tuple
        Pair of segments to aberrate, 0-indexed. If same segment gets passed in both tuple entries, the segment will be
        aberrated only once.
        Note how HiCAT segments start numbering at 0, with 0 being the center segment.

    Returns
    -------
    contrast as float, and segment pair as tuple


Function to calculate RST mean contrast of one DM actuator pair in CGI.

    Parameters
    ----------
    norm : float
        direct PSF normalization factor (peak pixel of direct PSF)
    wfe_aber : float
        calibration aberration per segment in m
    resDir : string
        directory for saving results of matrix calculations
    savepsfs : bool
        if True, all PSFs will be saved to disk individually, as fits files
    saveopds : bool
        if True, all pupil surface maps of aberrated segment pairs will be saved to disk as PDF
    actuator_pair : tuple
        Pair of actuators to aberrate, 0-indexed. If same actuator gets passed in both tuple entries, the actuator will
        be aberrated only once.

    Returns
    -------
    contrast as float, and segment pair as tuple


Calculate the final PASTIS matrix from the input contrast matrix (only half filled).

    The contrast matrix is a nseg x nseg matrix where only half of it is filled, including the diagonal, and the other
    half is filled with zeros. It holds the DH mean contrast values of each aberrated segment pair, with a WFE
    amplitude of the calibration aberration wfe_aber, in m. Hence, the input contrast matrix is not normalized to the
    desired units yet. The coronagraph floor is NOT subtracted from it at this point yet, but also passed in.
    This function first normalizes the contrast matrix and coro floor by the calibration aberration to get a matrix with
    units of contrast / nm^2. Then, it calculates the PASTIS matrix, and it adapts to whether we assume a static
    coronagraph floor (passed in as a single float) or a drifting coronagraph floor (passed in as a 2D array, per
    segment pair measurement). Finally, it symmetrizes the matrix to output the full PASTIS matrix.

    Parameters
    ----------
    contrast_matrix : ndarray
        nseg x nseg matrix holding DH mean contast values of all aberrated segment pairs;
        only half of the matrix has non-zero values, contrast floor NOT SUBTRACTED yet.
    seglist : list
        list of segment indices (e.g. 0, 1, 2, ...36 [HiCAT]; or 1, 2, ..., 120 [LUVOIR])
    wfe_aber : float
        calibration aberration in m, this is the aberration that was used to generate contrast_matrix
    coro_floor : float, or nd.array of same dims like contrast_matrix
        In simulations we usually assume a static coronagraph floor across the measurements for the PASTIS matrix and
        can use a single number. When we have a drifting coro floor though, we need one contrast floor number per
        measurement.

    Returns
    -------
    the finalized PASTIS matrix in units of contrast per nanometers squared, ndarray of nseg x nseg