    A subtask for computing anomalies of moving averages and writing them out.

    Attributes
    ----------

    mpasTimeSeriesTask : ``MpasTimeSeriesTask``
        The task that extracts the time series from MPAS monthly output

    outFileName : str
        The file name (usually without full path) where the resulting
        data set should be written

    variableList : list of str
        Variables to be included in the data set

    movingAveragePoints : int
        The number of points (months) used in the moving average used to
        smooth the data set

    alter_dataset : function
        A function that takes an ``xarray.Dataset`` and returns an
        ``xarray.Dataset`` for manipulating the data set (e.g. adding a new
        variable computed from others).  This operation is performed before
        computing moving averages and anomalies, so that these operations are
        also performed on any new variables added to the data set.


    Plot model output at OSNAP transects and compare it against OSNAP
    observations


    Performs analysis of the time-series output of sea-surface temperature
    (SST).

    Attributes
    ----------

    mpasTimeSeriesTask : ``MpasTimeSeriesTask``
        The task that extracts the time series from MPAS monthly output

    controlconfig : mpas_tools.config.MpasConfigParser
        Configuration options for a control run (if any)


    Computation and plotting of model meridional overturning circulation.
    Will eventually support:

        * MOC streamfunction, post-processed
        * MOC streamfunction, from MOC analysis member
        * MOC time series (max value at 24.5N), post-processed
        * MOC time series (max value at 24.5N), from MOC analysis member


    An analysis subtasks for computing cell masks and southern transects for
    MOC regions


    Computation of a climatology of the model meridional overturning
    circulation.

    Attributes
    ----------

    mpasClimatologyTask : ``MpasClimatologyTask``
        The task that produced the climatology to be remapped and plotted


    Computation of a climatology of the model meridional overturning
    circulation.


Computation of a time series of max Atlantic MOC at 26.5N.


    Combine individual time series of max Atlantic MOC at 26.5N into a single
    data set


Plots a time series of max Atlantic MOC at 26.5N.


Plot model output and compare it against Antarctic ship transects (https://doi.org/10.17882/99787)


    A subtask for remapping climatologies to transect points

    Attributes
    ----------

    obsDatasets : TransectsObservations
        A dictionary of observational datasets

    verticalComparisonGridName : {'obs', 'mpas'} or any str
        The vertical grid name on which to compare MPAS data with
        observations. 'obs' indicates the locations of the original
        observations; 'mpas' is the vertical locations of MPAS points,
        remapped to the observation latitude/longitude. If any other,
        string, verticalComparisonGrid should be a 1D numpy array and this
        name should be a useful (and unique) description of that grid.

    verticalComparisonGrid : 1D numpy array
        The vertical grid on which to compare MPAS data with observations
        if ``verticalComparisonGridName`` is not 'obs' or 'mpas'.  The
        values should be elevations (in m, typically negative).

    transectNumber : ``xarray.DataArray``
        For each point in the point collection after remapping, the index of
        the transect it belongs to (so that remapped results can be separated
        back into individual transects for plotting)

    transectCollectionName : str
        A name that describes the collection of transects (e.g. the name
        of the collection of observations) used to name the
        destination "mesh" for regridding

    collectionDescriptor : ``PointCollectionDescriptor``
        The mesh descriptor for the collection of all points in all transects,
        used for remapping

    zMid : ``xarray.DataArray``
        Vertical coordinate at the center of layers, used to interpolate to
        reference depths

    zInterface : ``xarray.DataArray``
        Vertical coordinate at the interfaces between layers, used to
        interpolate to reference depths


    A class for loading and manipulating transect observations

    Attributes
    ----------

    config : mpas_tools.config.MpasConfigParser
        Configuration options

    obsFileNames : OrderedDict
        The names of transects and the file names of the corresponding
        observations for a transect

    horizontalResolution : str
        'obs' for the obs as they are, 'mpas' for the native MPAS mesh, or a
        size in km if subdivision of the observational transect is desired.

    transectCollectionName : str
        A name that describes the collection of transects (e.g. the name
        of the collection of observations) used to name the
        destination "mesh" for regridding

    obsDatasets : OrderedDict
        A dictionary of observational datasets


    An analysis task for comparison of potential temperature against Argo
    observations


    An analysis task for comparison of global salinity against Argo
    observations


    A flexible analysis task for plotting climatologies of any MPAS-Ocean field
    on cells from timeSeriesStatsMonthly at various depths (if the field has
    vertical levels) and for various seasons.

    Various derived fields are also supported:

    * velocity magnitude
    * thermal forcing (temperature - freezing temperature)


    A subtask for computing derived variables (such as velocity magnitude and
    thermal forcing) as part of remapping climatologies at depth slices

    Attributes
    ----------
    variables : dict of dict
        A dictionary of variable definitions, with variable names as keys


    An analysis task for comparison of Antarctic Bottom Water properties
    against Schmidtko et al. (2014) observations


A subtask for reading and remapping Schmidtko et al. (2014) observations


    An analysis task for comparison of the anomaly from a reference year
    (typically the start of the simulation) of ocean heat content (OHC)

    Attributes
    ----------
    mpas_climatology_task : mpas_analysis.shared.climatology.MpasClimatologyTask
        The task that produced the climatology to be remapped and plotted

    ref_year_climatology_task : mpas_analysis.shared.climatology.RefYearMpasClimatologyTask
        The task that produced the climatology from the first year to be
        remapped and then subtracted from the main climatology


    A subtask for computing climatologies of ocean heat content from
    climatologies of temperature

    Attributes
    ----------
    ref_year_climatology_task : mpas_analysis.shared.climatology.RefYearMpasClimatologyTask
        The task that produced the climatology from the first year to be
        remapped and then subtracted from the main climatology

    min_depth, max_depth : float
        The minimum and maximum depths for integration


An analysis task for computing and plotting maps of the wind stress curl.


    A subtask for computing climatologies of the wind stress curl before
    it gets remapped to a comparison grid.


An analysis task for the computation of wave climatologies


A subtask for reading and remapping wave climatology


A subtask for reading and remapping ERA5 wave observations


A subtask for reading and remapping SS_CCI wave observations


    Compute and plot a Hovmoller diagram (depth vs. time) for regionally
    analyzed data.  The mean of the data are computed over each region at each
    depth and time.


    A subtask for computing anomalies of moving averages and writing them out.

    Attributes
    ----------
    inFileName : str
        The file name for the time series

    outFileName : str
        The file name (usually without full path) where the resulting
        data set should be written

    movingAveragePoints : int
        The number of points (months) used in the moving average used to
        smooth the data set


    An analysis task for plotting 2D model fields against observations.

    Attributes
    ----------
    season : str
        A season (key in ``shared.constants.monthDictionary``) to be
        plotted.

    transectName : str
        The name of the transect to plot

    computeTransectsSubtask : ``ComputeTransectsSubtask``
        The subtask for computing the MPAS climatology that this subtask
        will plot

    plotObs : bool, optional
        Whether to plot against observations.

    controlconfig : mpas_tools.config.MpasConfigParser
        Configuration options for a control run (if any), ignored if
        ``plotObs == True``

    horizontalBounds : [float, float]
        The distance in km of the left- and right-hand edges of the plot,
        chosen automatically by default or if the list is empty

    outFileLabel : str
        The prefix on each plot and associated XML file

    fieldNameInTitle : str
        The name of the field being plotted, as used in the plot title

    mpasFieldName : str
        The name of the variable in the MPAS timeSeriesStatsMonthly output

    diffTitleLabel : str, optional
        the title of the difference subplot

    unitsLabel : str
        the units of the plotted field, to be displayed on color bars

    imageCaption : str
        the caption when mousing over the plot or displaying it full
        screen

    galleryGroup : str
        the name of the group of galleries in which this plot belongs

    groupSubtitle : str
        the subtitle of the group in which this plot belongs (or blank
        if none)

    groupLink : str
        a short name (with no spaces) for the link to the gallery group

    galleryName : str
        the name of the gallery in which this plot belongs

    configSectionName : str
        the name of the section where the color map and range is defined


    A task for computing and plotting time series and spectra of the El Nino
    3.4 climate index

    Attributes
    ----------

    mpasTimeSeriesTask : ``MpasTimeSeriesTask``
        The task that extracts the time series from MPAS monthly output

    controlconfig : mpas_tools.config.MpasConfigParser
        Configuration options for a control run (if any)


    An Image is a single file taken by a RedEdge camera representing one
    band of multispectral information


    A Capture is a set of Images taken by one MicaSense camera which share
    the same unique capture identifier (capture_id). Generally these images will be
    found in the same folder and also share the same filename prefix, such
    as IMG_0000_*.tif, but this is not required.


An ImageSet is a container for a group of captures that are processed together


Container for Micasense image metadata


Tests for loading Phoenix stellar models.


Tests for plotting and spectral binning.


Tests for creating Planck stellar models.


    Abstract class to operate on a :class:`~exosim.models.signal.Signal` and return a :class:`~exosim.models.signal.Signal`.

    Returns
    --------
    :class:`~exosim.models.signal.Radiance`
        optical element radiance


    *Abstract class*

    Base class for tasks.


    It iteratively estimates the radiometric signals on the foregrounds sub focal planes for a channel
    and returns a table with all the contributions.

    Returns
    --------
    :class:`astropy.table.QTable`
        signal table

    Raises
    --------
    TypeError:
        if the output is not :class:`~astropy.table.QTable`

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It performs the aperture photometry using :func:`photutils.aperture.aperture_photometry`.

    The details of the aperture strongly depends on the configurations set by the user.


    It computes and adds the saturation time to the radiometric table using :class:`~exosim.tasks.instrument.computeSaturation.ComputeSaturation`.

    Returns
    -------
    astropy.units.Quantity:
        saturation time
    astropy.units.Quantity:
        maximum signal in focal plane
    astropy.units.Quantity:
        minimum signal in focal plane


    It computes the MULTIACCUM gain factor from Rauscher and Fox 2007 (http://iopscience.iop.org/article/10.1086/520887/pdf)
    with the correction from Robberto 2009, also reported in Batalha 2017 (https://doi.org/10.1088/1538-3873/aa65b0)

    Returns
    ---------
    float:
        read noise gain factor
    float:
        shot noise gain factor


    It computes spectral binning useful to produce the radiometric tables

    Returns
    --------
    astropy.table.QTable:
        wavelength bins table

    Raises
    --------
    TypeError:
        if the output is not :class:`~astropy.table.QTable`
    KeyError:
        if a column is missing in the output :class:`~astropy.table.QTable`

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It returns the sizes of the apertures to perform photometry for :func:`photutils.aperture.aperture_photometry`.
    The details of the apertures depends on the configurations set by the user.

    Returns
    --------
    astropy.table.QTable:

    Raises
    --------
    TypeError:
        if the output is not :class:`~astropy.table.QTable`

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


r"""
    Computes the photon noise.
    Given the incoming signal :math:`S` the resulting photon noise variance is :math:`Var[S]=S`.
    If photon gain factor :math:`gain_{phot}` is given, then  :math:`Var[S]= gain_{phot} \cdot Var[S]`.
    If photon noise margin :math:`\chi` is found in the description, then  :math:`Var[S]= (1+\chi) \cdot Var[S]`.
    The noise returned is :math:`\sigma = \sqrt{Var[S]}`

    Returns
    -------
    astropy.table.QTable:
       photon noise


    It estimates the radiometric signals on the input focal plane..

    Returns
    --------
    :class:`astropy.units.Quantity`
        photometry

    Raises
    --------
    TypeError:
        if the output is not :class:`~astropy.units.Quantity`
    UnitsError:
        wrong output units

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It computes the total noise from a radiometric table

    Returns
    -------
    table: :class:`astropy.table.QTable`
        total noise column


It averages the NDRs of the same group.


    This Task simulates the read noise as a normal distribution which parameters can be defined with a map indicated in the configuration file under `read_noise_filename` keyword.
    The input must be a NPY format file (see `numpy documentation <https://numpy.org/devdocs/reference/generated/numpy.lib.format.html>`_) containing the map of the distribution standard deviation for each pixel.

    A different realisations of the same distribution is added to each pixel of each sub-exposure.
    If an output group is provided, it saves all the random seeds used.


r"""
    It adds a gain noise map to the array.

    The gain Drift is modeled as a polynomial model for a spectral and time dependent modulation.

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It adds the ktc bias to the sub-exposures.
    This Task produces a new random offset map for each ramp,
    and it adds it to the sub-exposures of the same ramp.
    If an output group is provided, it saves all the random seeds used.


    This Task simulates the read noise as a normal distribution which parameters can be defined in the configuration file.

    If it is not explicitly stated, the distribution mean is set to 0.
    A different realisation of the same distribution is added to each pixel of each sub-exposure.
    If an output group is provided, it saves all the random seeds used.

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It adds a dark current map to the array.
    The map must be indicated under the `dc_map_filename` keyword.
    The dark current is loaded from a NPY format file (see `numpy documentation <https://numpy.org/devdocs/reference/generated/numpy.lib.format.html>`_).


    Task to simulate the addition of cosmic rays to sub-exposures in a detector.

    This task models the impact of cosmic rays on a detector during the exposure time. The model assumes
    that the cosmic rays can interact with the detector pixels in various predefined shapes like a cross,
    horizontal rectangle, and vertical rectangle. The number of cosmic ray events and their impact on the
    detector pixels are calculated based on the given cosmic ray flux, detector characteristics, and
    integration times for the sub-exposures.

    Notes
    -----
    - This task assumes that the cosmic ray events saturate the affected pixels, setting their value to the full well depth.
    - The probabilities for the interaction shapes are configurable. The task issues a warning if the sum of provided probabilities is not 1.
    - The cosmic ray flux is specified in ct/s/cm^2 and is scaled based on the pixel size and detector dimensions.

    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It masks the dead pixel in the array given a numpy map.
    The input must be a NPY format file (see `numpy documentation <https://numpy.org/devdocs/reference/generated/numpy.lib.format.html>`_) containing a boolean map marking with True the dead pixels.
    The map should be indicated under ``dp_map_filename`` keyword.


It masks the dead pixel in the array given their coordinates.


r"""
    This Task applies a simple model of saturation to pixel counts.
    If the counts in a pixel are higher than the well depth, the counts are set to the well capacity.


    Loads the pixels non-linearuty map

    Returns
    --------
    dict
        channel non linearity map

    Raises
    ------
    KeyError:
        if the output do not have the `map` key

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


It accumulates sub-exposures of the same ramp.


    It adds the shot noise to the sub-exposures.
    The shot noise is added as a Poisson noise to the sub-exposures.
    If an output group is provided, it saves all the random seeds used.


    Loads the pixels non-linearity map given a numpy map.
    The input must be a NPY format file (see `numpy documentation <https://numpy.org/devdocs/reference/generated/numpy.lib.format.html>`_) containing the coefficients for each pixel.
    The map should have dimensions (n, y, x) where n is the number of coefficients for the polynomial approximation and y and x are the number of pixels in spatial and spectral directions.
    The map should be indicated under ``pnl_filename`` keyword.

    Returns
    --------
    dict
        channel non linearity map

    Raises
    ------
    KeyError:
        if the output do not have the `map` key


    It converts the :math:`counts` units of sub-exposures into :math:`adu` units of NDRs.
    The conversion is related to the user defined number of bits of the ADC.
    In the number of bits is not defined, 32 is the default value.
    This Task select the smallest ``dtype`` to represent the desired data type:

    + if the input number of bits is smaller than 16, a ``int16`` data type is used,
    + if the input number of bits is smaller than 8, a ``int8`` data type is used.

    Otherwise, a ``int32`` data type is used.

    The user should also specify the ADC gain factor to apply to the focal plane before the conversion.

    Finally, the user should specify the rounding method to use to cast the float into integers.
    The `ADC_round_method` keyword indicates which method the ADC should use to cast the float into integers. Three options are available:

    - `floor` which uses :class:`numpy.floor`;
    - `ceil` which uses :class:`numpy.ceil`;
    - `round` which uses :class:`numpy.round`;

    Default is `floor`.

    Returns
    ---------
    :class:`~exosim.models.signal.Adu`
        sub-exposures converted into NDRs :math:`adu` units


r"""
    Given the pixel non-linearity parameters,
    this Task correct the ideal measured signal rate to the pixel linearity.

    .. math::
        Q_{det} = Q \cdot (a + b \cdot Q + c \cdot Q^2 + d \cdot Q^3 + e \cdot Q^4)

    The input is a dictionary with a `map` keyword containg an array with the coefficients for each pixel.
    The map shape is (n_pixels_x, n_pixels_y, coefficient order).

    The user can list any number of coefficients, that will be parsed in the following model

    .. math::
        Q_{det} = Q \cdot (a_0 + \sum_i a_i \cdot Q^i)


    It adds constant dark current to all the pixel in the array.
    The dark current is loaded from the parameters

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    This task applies the astronomical signal to the sub-exposures.
    To do so, it first convolve the astronomical signal with the instrument line shape (ILS)
    on the focal plane. This is done by populating the focal plane with the ILS and then weighting the contributions to each pixel.
    The resulting model is then convolved with the intrapixel response function (IPRF) and downsampled to the sub-exposure time resolution.
    Then is finally multiplied to the sub-exposure signal.

    Returns
    --------
    :class:`~exosim.models.signal.Counts`
        sub-exposure cached signal class


    It is a base class for all astronomical signal estimation tasks.
    If an output file is provided, the signal model is stored in the output file.

    Returns
    -------
    ArrayType
        returns the planetary signal in a 2D array (wavelength, time)


    This task estimates the planetary signal.
    The signal parameters are extracted from the sky configuration file.
    This Task is a wrapper for the batman package: it parses the planet parameters and computes the transit model.
    The transit model is computed at the input wavelength grid.
    By default, the transit type is set to 'primary' (i.e. the planet transits in front of the star).
    The planetary sarius can be parsed as a string (path to a file) or as a float (in units of stellar radii).
    If a file is indicated, the planetary radius is binned or interpolated to the input wavelength grid.

    Based on Batman package by L. Kreidberg (https://ui.adsabs.harvard.edu/abs/2015PASP..127.1161K/abstract).


    This tasks find astronomical signals in the sky parameters dictionary.
    The signals are identified by the presence of the key "signal_task" in the dictionary.


    it propagates the foreground though the channel.

    Returns
    -------
    `~collections.OrderedDict`
        dictionary of :class:`~exosim.models.signal.Radiance` and :class:`~exosim.models.signal.Dimensionless`,
        represeting the radiance and efficiency of the path.


    It computes the saturation time given the focal plane and the detector parameters.

    Returns
    --------
    :class:`~astropy.units.Quantity`
        saturation time
    :class:`~astropy.units.Quantity`
        frame time
    :class:`~astropy.units.Quantity`
        maximum signal
    :class:`~astropy.units.Quantity`
        minimum signal


    It produces the empty focal plane

    Returns
    -------
    :class:`~exosim.models.signal.Signal`
        focal plane array (with time evolution)


    It creates the intrapixel response function to be used in the convolution with the focal plane array.

    Returns
    -------
    kernel	: 2D array
            the kernel image
    kernel_delta  : scalar
                    the kernel sampling interval in microns

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    it propagates the sources though the channel.
    It multiplies the stellar SED by the effective telescope area, the channel efficiency and the channel responsivity:

    .. math::
        S_{\\nu} = S_{\\nu}^{*} \\times A_{tel} \\times \\eta \\times R_{\\nu}

    The result is in units of :math:`ct/s/\\mu m`

    Returns
    -------
    dict
        dictionary containing :class:`~exosim.models.signal.Signal`


    It adds the foreground contribution to the focal plane

    Returns
    -------
     :class:`~exosim.models.signal.Signal`
        focal plane array


    It loads the wavelength solution expressed as a table with wavelength position on spectral and spatial directcions

    Returns
    --------
    :class:`~astropy.table.Qtable`
        wavelength solution table

    Raises
    -------
    TypeError:
        if the output is not a :class:`~astropy.table.QTable` class

    UnitsError
        if the output has not the right units (micron) in every column

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


r"""
    It computes the solid angle given the system parameters.

    Returns
    --------
    :class:`~astropy.units.Quantity`
        solid angle expressed as :math:`sr \cdot m^2`


    It loads the PSFs from two PAOS files and interpolates over time between them according to the given parameters.
    Each PAOS file contains a PSF vs wavelength.
    The task loads the PSF cubes provided by the `filename` parameter.
    The PSFs are then interpolated over a grid matching the one used to produce the focal planes,
    to convert them into the physical units.
    Then the total volume of the interpolated PSF is rescaled to the total volume of the original one.
    This allow to take into account for loss in the transmission due to the optical path.
    The PSF are then interpolated over a wavelength grid matching the one used to for the focal plane, producing the cube.

    Then an example of time dependency is implemented in the model method.

    The PSF cube is then cropped to removed unused edges, where the signal is less than 1/100 of the PSF peak.
    This would fasten up the successive `ExoSim` step.

    Returns
    -------
     :class:`~numpy.ndarray`
        cube of psfs.  axis=0 is time, axis=1 is wavelength, axis=2 is spatial direction, axis=3 is spectral direction.

    Note
    -----
    `filename` must be a string of filenames separated by a comma and a space.
    To write your version, define a new class that inherits from this one in a dedicated python file.
    Then copy the `model` method and replace the indicated section (where `REPLACE THIS WITH YOUR MODE` is written).


    It loads the PSFs from files.

    Returns
    -------
    :class:`~numpy.ndarray`
        cube of psfs. axis=0 is time, axis=1 is wavelength, axis=2 is spatial direction, axis=3 is spectral direction.
    :class:`~numpy.ndarray`
        cube normalization factors. It contains the volume of each psf. axis=0 is time, axis=1 is wavelength.


    It applies the intra pixel response function to the plane

    Returns
    -------
    :class:`~exosim.models.signal.Signal`
        focal plane array (irf applied)


    It populates the empty focal plane with monocromatic PSFs.

    Returns
    -------
    :class:`~exosim.models.signal.Signal`
        focal plane array populated


    It produces the focal plane array

    Returns
    -------
    :class:`~exosim.models.signal.Signal`
        focal plane array (no time evolution)


    It loads the PSFs from a PAOS file.
    Each PAOS file contains a PSF vs wavelength.
    The task loads the PSF cube provided by the `filename` parameter.
    The PSF are then interpolated over a grid matching the one used to produce the focal planes,
    to convert them into the physical units.
    Then the total volume of the interpolated PSF is rescaled to the total volume of the original one.
    This allow to take into account for loss in the transmission due to the optical path.
    The PSF are then interpolated over a wavelength grid matching the one used to for the focal plane, producing the cube.
    Then, the PSF cube is repeated on the temporal axis, because no temporal variation is considered in this Task.

    Returns
    -------
    :class:`~numpy.ndarray`
        cube of psfs.  axis=0 is time, axis=1 is wavelength, axis=2 is spatial direction, axis=3 is spectral direction.


    It computes the source offset on the focal plane respect to the pointing direction.
    The offset is in units of subpixels.

    Returns
    -------
     int
       offset in the spatial direction
     int
       offset in the spectral direction


r"""
    Create a star SED using the Planck function.

    The star emission is simulated by :class:`astropy.modeling.physical_models.BlackBody`.
    The resulting sed is then converted into :math:`W/m^2/sr/\mu m` and scaled by the solid angle :math:`\pi \left( \frac{R}{D} \right)^2`.

    Returns
    -------
    :class:`~exosim.models.signal.Sed`
        Star Sed

    Examples
    --------
    >>> from exosim.tasks.sed import CreatePlanckStar
    >>> import astropy.units as u
    >>> import numpy as np
    >>> createPlanckStar = CreatePlanckStar()
    >>> wl = np.linspace(0.5, 7.8, 10000) * u.um
    >>> T = 6086 * u.K
    >>> R = 1.18 * u.R_sun
    >>> D = 47 * u.au
    >>> sed = createPlanckStar(wavelength=wl, T=T, R=R, D=D)

    >>> import matplotlib.pyplot as plt
    >>> plt.plot(sed.spectral, sed.data[0,0])
    >>> plt.ylabel(sed.data_units)
    >>> plt.xlabel(sed.spectral_units)
    >>> plt.show()

    .. plot:: mpl_examples/createPlanckStar.py


    Returns a source SED.
    The SED depends on the source type selected. This Task analyse the inputs and return the desired SED.

    Returns
    -------
    :class:`~exosim.models.signal.Sed`
        Star Sed

    Examples
    ---------
    We first define all the inputs and then we show how to produce the star sed:

    >>> from exosim.tasks.sed import LoadPhoenix
    >>> wavelength = np.linspace(0.5, 7.8, 10000) * u.um
    >>> T = 5778 * u.K
    >>> R = 1 * u.R_sun
    >>> D = 1 * u.au
    >>> M = 1 * u.Msun
    >>> z = 0.0
    >>> g = (cc.G * M.si / R.si ** 2).to(u.cm / u.s ** 2)
    >>> logg = np.log10(g.value)

    To produce a planck star:

    >>> prepareSed = LoadPhoenix()
    >>> sed = PrepareSed(source_type='planck', wavelength=wavelength, T=T, R=R, D=D)

    To load a Phoenix star:
    >>> sed_l = prepareSed(source_type='phoenix', path=phoenix_stellar_model, T=T, R=R, D=D, logg=logg, z=z)


    Creates a custom SED from input parameters.

    Returns
    -------
    :class:`~exosim.models.signal.Sed`
        Star Sed

    Raises
    ------
    TypeError:
        if the output is not a :class:`~exosim.models.signal.Sed` class

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


r"""
    Loads a custom SED from a file and scaled it by the solid angle :math:`\pi \left( \frac{R}{D} \right)^2`.

    Returns
    -------
    :class:`~exosim.models.signal.Sed`
        Star Sed


    Loads a star SED from a grid of Phoenix spectra or from a specific Phoenix file.

    Returns
    -------
    :class:`~exosim.models.signal.Sed`
        Star Sed

    Examples
    --------
    >>> from exosim.tasks.sed import LoadPhoenix
    >>> loadPhoenix = LoadPhoenix()

    Prepare the star

    >>> from astropy import constants as cc
    >>> import astropy.units as u
    >>> import numpy as np
    >>> D= 12.975 * u.pc
    >>> T= 3016 * u.K
    >>> M= 0.15 * u.Msun
    >>> R= 0.218 * u.Rsun
    >>> z= 0.0
    >>> g = (cc.G * M.si / R.si ** 2).to(u.cm / u.s ** 2)
    >>> logg = np.log10(g.value)

    Load the sed from a directory

    >>> sed = loadPhoenix(path = phoenix_directory,  T=T, D=D, R=R, z=z, logg=logg)

    or load the sed from a file

    >>> sed = loadPhoenix(filename = phoenix_file, D=D, R=R)

    Notes
    --------
    This class can either load the SED from a file or select the most suitable file from the Phoenix spectra path,
    given the proper information on the star. In the former case the `filename` keyword is needed, in the latter are
    required the keywords `path`, `T`, `z`, `logg`. Not providing the right keywords would result in an error.

    Raises
    --------
        InputError
            if neither `filename` or `path` are given.
        KeyError
            if a needed parameter is missing in the user inputs.


    Abstract class to load an optical element and returns the element self emission
    and it optical efficiency.

    Returns
    --------
    :class:`~exosim.models.signal.Radiance`
        optical element radiance
    :class:`~exosim.models.signal.Dimensionless`
        optical element efficiency

    Raises
    ------
    TypeError:
        if the outputs are not the right :class:`~exosim.models.signal.Signal` subclasses

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    Reads the XML file with payload parameters and returns an object with attributes related to the input data.

    Attributes
    ----------
    config_path : str
        Configuration path.

    Returns
    -------
    dict
        Parsed XML input file.

    Raises
    ------
    IOError
        If the indicated file is not found or the format is not supported.

    Examples
    --------
    >>> load_options = LoadOptions()
    >>> options = load_options(filename='path/to/file.xml')


    Class to load an optical element and return its radiance and efficiency using data from an HDF5 file.

    This class inherits from LoadOpticalElement and overrides the `model` and `_get_data` methods to use an HDF5 file
    for the optical element data.

    Returns
    --------
    :class:`~exosim.models.signal.Radiance`
        optical element radiance
    :class:`~exosim.models.signal.Dimensionless`
        optical element efficiency


    Given the element parameters, it parses the optical element and returns a dictionary.
    It also applyes the time variation if provided.

    Returns
    -------
    dict
        dictionary of :class:`~exosim.models.signal.Radiance` and :class:`~exosim.models.signal.Dimensionless`,
        represeting the radiance and efficiency of the optical element.


    This tasks parses the zodiacal foreground.

    Returns
    -------
    dict
        dictionary of :class:`~exosim.models.signal.Radiance` and :class:`~exosim.models.signal.Dimensionless`,
        representing the radiance and efficiency of the optical element.


    Given the source descrition, it parses the sources elements and return a dictionary.
    It also applyes the time variation if provided.

    Returns
    -------
    dict
        dictionary containing :class:`~exosim.models.signal.Sed`

    Examples
    ---------

    >>> import astropy.units as u
    >>> import numpy as np
    >>> from exosim.tasks.parse import ParseSources
    >>> from collections import OrderedDict
    >>>
    >>> wl = np.linspace(0.5, 7.8, 10000) * u.um
    >>> tt = np.linspace(0.5, 1, 10) * u.hr
    >>>
    >>> sources_in = OrderedDict({'HD 209458': {'value': 'HD 209458',
    >>>                                         'source_type': 'planck',
    >>>                                         'R': 1.18 * u.R_sun,
    >>>                                         'D': 47 * u.pc,
    >>>                                         'T': 6086 * u.K,
    >>>                                         },
    >>>                           'GJ 1214': {'value': 'GJ 1214',
    >>>                                       'source_type': 'planck',
    >>>                                       'R': 0.218 * u.R_sun,
    >>>                                       'D': 13 * u.pc,
    >>>                                       'T': 3026 * u.K,
    >>>                                       }, })
    >>>
    >>> parseSources = ParseSources()
    >>> sources_out = parseSources(parameters=sources_in,
    >>>                            wavelength=wl,
    >>>                            time=tt)

    >>> import matplotlib.pyplot as plt
    >>>
    >>> plt.plot(source_out['HD 209458'].spectral, source_out['HD 209458'].data[0,0])
    >>> plt.ylabel(source_out['HD 209458'].data_units)
    >>> plt.xlabel(source_out['HD 209458'].spectral_units)
    >>> plt.show()

    .. plot:: mpl_examples/parseSources.py


    Given the source parameters, it parses the source element and returns a dictionary.
    It also applyes the time variation if provided.

    Returns
    -------
    dict
        dictionary containing :class:`~exosim.models.signal.Sed`

    Examples
    ---------

    >>> from exosim.tasks.parse import ParseSource
    >>> import astropy.units as u
    >>> import numpy as np
    >>> parseSource = ParseSource()
    >>> wl = np.linspace(0.5, 7.8, 10000) * u.um
    >>> tt = np.linspace(0.5, 1, 10) * u.hr
    >>> source_in = {
    >>>     'value': 'HD 209458',
    >>>     'source_type': 'planck',
    >>>     'R': 1.18 * u.R_sun,
    >>>     'D': 47 * u.pc,
    >>>     'T': 6086 * u.K,
    >>>     }
    >>> source_out = parseSource(parameters=source_in,
    >>>                          wavelength=wl,
    >>>                          time=tt)

    >>> import matplotlib.pyplot as plt
    >>> plt.plot(source_out['HD 209458'].spectral, source_out['HD 209458'].data[0,0])
    >>> plt.ylabel(source_out['HD 209458'].data_units)
    >>> plt.xlabel(source_out['HD 209458'].spectral_units)
    >>> plt.show()

    .. plot:: mpl_examples/parseSource.py


    Given the optical path descrition, it parses the optical elements and return an ordered dictionary.

    Returns
    -------
    dict
        dictionary of :class:`~exosim.models.signal.Radiance` and :class:`~exosim.models.signal.Dimensionless`,
        represeting the radiance and efficiency of the path.

    Note
    ------
    The user can force the parser to isolate contribution by addind to the description dictionary the key 'isolate' set to ``True``.


    Loads the Quantum efficiency map

    Returns
    --------
    :class:`~exosim.models.signal.Signal`
        channel responsivity variation map

    Raises
    ------
    TypeError:
        if the output is not a :class:`~exosim.models.signal.Signal` class

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    Loads the Quantum efficiency map from a NPY file (see `numpy documentation <https://numpy.org/devdocs/reference/generated/numpy.lib.format.html>`_).

    Returns
    --------
    :class:`~exosim.models.signal.Signal`
        channel responsivity variation map

    Raises
    ------
    TypeError:
        if the output is not a :class:`~exosim.models.signal.Signal` class


    It scales the pointing jitter expressed as :math:`deg` into the pixel unit according to the channel plate scale
    and interpolates it to a time grid which is aligned to the detector readout time grid.

    Returns
    --------
    (:class:`~numpy.ndarray`, :class:`~numpy.ndarray`)
        Tuple containing the pointing jitter in the spatial and spectral direction expressed in units of pixels.


    This task implements the instantaneous read out.
    It loads the readout configuration from a dictionary that is produced by :class:`~exosim.tasks.subexposures.prepareInstantaneousReadOut.PrepareInstantaneousReadOut`.
    Then it creates the sub-exposure datacube, with sub-exposure for each NDRs in the ramp sampling scheme.
    Each of these sub-exposures collects more simulation steps, which have their own jitter offset.
    This Task iterates over the time steps to jitter the focal plane and pile it to the appropriate sub-exposure.
    The jittering is based on the focal plane oversampling factor.
    The contributions to each sub-exposures are averaged and the final product is multiplied by its integration time.

    Returns
    --------
    :class:`~exosim.models.signal.Counts`
        sub-exposure cached signal class


    Produces the telescope pointing jitter expressed as deg on the line of sight.

    Returns
    --------
    :class:`~astropy.units.Quantity`,
        pointing jitter in the spatial and spectral direction expressed in units of :math:`deg`.
    :class:`~astropy.units.Quantity`
        pointing jitter in the spatial and spectral direction expressed in units of :math:`deg`.
    :class:`~astropy.units.Quantity`
        pointing jitter in the spatial and spectral direction expressed in units of :math:`deg`.

    Raises
    ------
    TypeError:
        if the output is not a :class:`~astropy.units.Quantity` class

    Notes
    -----
    This is a default class with standardised inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It applies the quantum efficiency variation map to the sub exposures.

    Returns
    --------
    :class:`~exosim.models.signal.Counts`
        sub-exposure cached signal class


    It adds the foregrounds the sub exposures.

    Returns
    --------
    :class:`~exosim.models.signal.Counts`
        sub-exposure cached signal class


    This task prepares the instantaneous read out.
    It calls  :class:`~exosim.tasks.subexposures.computeReadingScheme.ComputeReadingScheme` to compute the ramp sampling scheme,
    and :class:`~exosim.tasks.subexposures.estimateChJitter.EstimateChJitter` to scale the input pointing jitter to the focal planet pixel units.
    The jittering is based on the focal plane oversampling factor.

    Returns
    --------
    dict
        readout_parameters dict
    :class:`~astropy.units.Quantity`
        sub-exposures integration times


    This Task loads the instrument line shapes (ILS) from the input file.
    The loaded ILS are then used to convolve the astronomical signal.
    The ILS here are intended as the PSF of the instrument.
    The ILS shapes are normalized to the maximum value.

    Returns
    -------
    :class:`numpy.ndarray`
        instrument line shape.
        The shape is (time, wavelength, spectral direction)

    Note
    -----
    The instrument line shapes produced by this task are not the same as the instrument line shapes
    as defined in the literature.
    The ILS produced by this task are the PSF of the instrument.
    To be used as the instrument line shapes as defined in the literature they need to be convolved with the intra-pixel response.
    This convolution is not part of this Task as it affects the way the ILS are sampled.
    The convolution with the intra-pixel response is done in the :class:`exosim.tasks.astrosignal.applyAstronomicalSignal.ApplyAstronomicalSignal` Task,
    where the ILS are used to convolve the astronomical signal.


    It computes the reading scheme for the sub-exposures given the instrument parameters and the focal planes.

    Returns
    -------
    :class:`astropy.units.Quantity`
        simulation frequency.
    :class:`numpy.ndarray`
        state machine for the reading operation on the ramp.
    :class:`numpy.ndarray`
        state machine of the group ends sampling the ramp.
    :class:`numpy.ndarray`
        state machine of the group starts sampling the ramp.
    :class:`numpy.ndarray`
        full list of simulation stapes for each steps on the ramp repeated by the number of ramps.
    int
        number of exposures needed to sample the full observation using ramps of the exposure time size.


    It estimate the zodiacal radiance in the target direction for a specific wavelength range

    Returns
    -------
    :class:`~exosim.models.signal.Radiance`
        zodiacal radiance

    Examples
    --------
    >>> estimateZodi = EstimateZodi()
    >>> wavelength = np.logspace(np.log10(0.45), np.log10(2.2), 6000) * u.um
    >>> zodi = estimateZodi(wavelength=wavelength, zodiacal_factor=1)

    or, given the pointing direction

    >>> zodi = self.estimateZodi(wavelength=wavelength,  coordinates=(90 * u.deg, -66 * u.deg))


    It sets the output for the code.
    This class created and initializes the output file.
    If a file name is provided, it loads the relative :class:`~exosim.output.output.Output` class is instatiated.
    Otherwise an :class:`~exosim.output.hdf5.hdf5.HDF5Output` is used by default for a temporary file.


    Radiometric plotter.
    This class handles the methods to plot the radiometric table produced by `exosim`.

    Attributes
    -----------
    input: str or :class:`astropy.table.QTable`
            input data
    input_table: :class:`astropy.table.QTable`
        input radiometric table
    fig: :class:`matplotlib.figure.Figure`
        produced figure

    Examples
    ----------
    The following example, given the `test_file.h5` preoduced by Exosim,
    plots the radiometric table and stores the figure as `radiometric.png`.

    >>> from exosim.plots import RadiometricPlotter
    >>> radiometricPlotter = RadiometricPlotter(input='./test_file.h5')
    >>> radiometricPlotter.plot_table()
    >>> radiometricPlotter.save_fig('radiometric.png')


    Sub-Exposures plotter.
    This class handles the methods to plot all the sub-exposures produced by `ExoSim`.

    Examples
    ----------
    The following example, given the `test_file.h5` preoduced by Exosim,
    plots the sub-exposures stores the figures in the indicated folder.

    >>> from exosim.plots import SubExposuresPlotter
    >>> subExposuresPlotter = SubExposuresPlotter(input='./test_se.h5')
    >>> subExposuresPlotter.plot('plots/')


    Sub-Exposures plotter.
    This class handles the methods to plot all the sub-exposures produced by `ExoSim`.

    Examples
    ----------
    The following example, given the `test_file.h5` preoduced by Exosim,
    plots the sub-exposures stores the figures in the indicated folder.

    >>> from exosim.plots import SubExposuresPlotter
    >>> subExposuresPlotter = SubExposuresPlotter(input='./test_ndr.h5')
    >>> subExposuresPlotter.plot('plots/')


    Focal plane plotter.
    This class handles the methods to plot the focal palnes produced by `exosim`.

    Attributes
    -----------
    input: str
        input file name
    fig: :class:`matplotlib.figure.Figure`
        produced figure

    Examples
    ----------

    The following example, given the `test_file.h5` produced by `exosim`,
    plots the focal plane at the first time stamp and stores the figure as `focal_plane.png`.

    >>> from exosim.plots import FocalPlanePlotter
    >>> focalPlanePlotter = FocalPlanePlotter(input='./test_file.h5')
    >>> focalPlanePlotter.plot_focal_plane(time_step=0)
    >>> focalPlanePlotter.save_fig('focal_plane.png')


This class adds methods to log the elapsed time


    *Abstract class*

    Standard logging using logger library.
    It's an abtract class to be inherited to load its methods for logging.
    It define the logger name at the initialization, and then provides the logging methods.


    It handles the channel gven the description

    Attributes
    ----------
    ch_name: str
        channel name
    path: dict
        dictionary of :class:`~exosim.models.signal.Radiance` and :class:`~exosim.models.signal.Dimensionless`,
        represeting the radiance and efficiency of the path.
    responsivity: :class:`~exosim.models.signal.Signal`
        channel responsivity
    sources: dict
        dictionary containing :class:`~exosim.models.signal.Signal`
    time: :class:`~astropy.units.Quantity`
        time grid.
    parameters: dict
        dictionary contained the optical element parameters. This is usually parsed from :class:`~exosim.tasks.load.loadOptions.LoadOptions`
    wavelength: :class:`~numpy.ndarray` or :class:`~astropy.units.Quantity`
        wavelength grid. If no units are attached is considered as expressed in `um`.
    focal_plane: :class:`~exosim.models.signal.Signal`
        source focal plane
    frg_focal_plane: :class:`~exosim.models.signal.Signal`
        foreground focal plane
    frg_sub_focal_planes: dict
        dictionary of :class:`~exosim.models.signal.Signal`. It contains the sub focal planes produced by the radiances.
        This dictionary is produced only if at least one optical surface has ``isolate=True``.
        The sum of the sub focal planes returns the frg_focal_plane. If not surface has ``isolate=True``, the dictionary is empty.
    output: :class:`~exosim.output.output.Output`
        output file
    target_source: str
        name of the target source


    This class handles data cubes. The cube axes are time (0), spatial (1) and spectral (2) directions.

    Attributes
    -----------
    spectral: :class:`~numpy.ndarray`
        spectral direction grid.
    data: :class:`~numpy.ndarray`
        data table. It has 3 axes: 0. time axis, 1. spatial axis, 2. spectral axis.
    dataset: :class:`h5py.Dataset`
        If cached mode is enabled, it contains the data table. It has 3 axes: 0. time axis, 1. spatial axis, 2. spectral axis.
    time: :class:`~numpy.ndarray`
        time grid.
    spatial: :class:`~numpy.ndarray`
        spatial direction grid.
    spectral_units: str
        define the spectral direction units. Default is `um`
    data_units: str
        define the data units.
    time_units: str
        define the time direction units. Default is `hr`.
    spatial_units: str
        define the spatial direction units. Default is `um`.
    cached: bool
        it tells if cache mode is enabled.
    output: str or  :class:`~exosim.output.hdf5.hdf5.HDF5Output`
        h5py open file used for caching
    dataset_name: :class:`h5py.Dataset`
        h5py dataset used to store the data
    output_path: str
        path where is stored the dataset inside the output file.
    metadata: dict
        signal metadata attached to the class

    Notes
    -----
    To understand caching mode, please look to :class:`~exosim.models.utils.cachedData.CachedData`


r"""
    It's a Signal class with data having units of :math:`[W m^{-2} \mu m^{-1}]`


r"""
    It's a Signal class with data having units of :math:`[ct/s]`


r"""
    It's a Signal class with data having units of :math:`[ct]`


r"""
    It's a Signal class with data having units of :math:`[adu/s]`


It's a Signal class with data having no units


    This class caches data cube into an h5 file. The cube data are chunked toward the first axis.
    In this class are also defined a set of operation to operate on the dataset using the chinks system.

    Attributes
    ----------
    axis0: int
        first axis size
    axis1: int
        second axis size
    axis2: int
        third axis size
    output: str or :class:`~exosim.output.HDF5Output`
        name of the file used for caching.
    dataset_name: str
        name used to store the dataset into the h5 file.
    output: :class:`h5py.File` or  :class:`~exosim.output.hdf5.hdf5.HDF5Output` or :class:`~exosim.output.hdf5.hdf5.HDF5OutputGroup`
        h5py open file used for caching
    dataset_path: str
         path where is stored the dataset inside the output file.
    chunked_dataset: :class:`h5py.Dataset`
        h5py dataset used to store the data

    Notes
    -----
    The cached data may be stored in a temporary file. To delete temporary files we included a garbage collector.
    Please, remember to delete the class when done as in the following example

    >>> myClass = CachedData(1,1,1)
    >>> del myClass


    Produces the channel dead pixel map

    Returns
    --------
    dict
        channels' dead pixels maps

    Raises
    ------
    TypeError:
        if the output is not a :class:`~astropy.table.Table` class

    Examples
    ----------

    >>> import exosim.tools as tools
    >>>
    >>> tools.DeadPixelsMap(options_file='tools_input_example.xml',
    >>>                     output='./')


    Produces the channels quantum efficiency variation map

    Returns
    --------
    dict:
        channels' quantum efficiency map

    Raises
    ------
    TypeError:
        if the output is not a :class:`~exosim.models.signal.Signal` class

    Examples
    ----------

    >>> import exosim.tools as tools
    >>>
    >>> results = tools.QuantumEfficiencyMap(options_file='tools_input_example.xml',
    >>>                                      output='output_qe_map.h5')


r"""
    This tools helps the user to find the pixel non-linearity coefficients to as inputs for ExoSim,
    starting from the an estimate of pixel non-linearity correction.

    This class will retrieve the :math:`a_i` coefficients, starting from physical assumptions.

    The detector non linearity model, is written as polynomial such as

    .. math::
        Q_{det} = Q \cdot (1 + \sum_i a_i \cdot Q^i)

    where :math:`Q_{det}` is the charge read by the detector, and :math:`Q` is the ideal count,
    as :math:`Q = \phi_t`, with :math:`\phi` being the number of electrons generated and :math:`t` being the elapsed time.

    Considering the detector as a capacitor, the charge :math:`Q_{det}` is given by

    .. math::
        Q_{det} = \phi \tau \cdot \left(1 - e^{-Q/\phi \tau}\right)

    where :math:`\phi` is the charge generated in the detector pixel, and :math:`\tau` is the capacitor time constant.
    In fact the product :math:`\phi \tau` is constant
    :math:`Q` is the response of a linear detectror is given by :math:`Q = \phi t`

    The detector is considered saturated when the charge :math:`Q_{det}` at the well depth :math:`Q_{det, \, wd}`
    differs from the ideal well depth :math:`Q_{wd}` by 5%.

    .. math::
        Q_{det} = (1-5\%)Q_{wd}

    Then

    .. math::
        \phi \tau \cdot \left(1 - e^{-Q_{wd}/\phi \tau}\right) = (1-5\%)Q_{wd}

    This equation can be solved numerically and gives

    .. math::
        \frac{Q_{wd}}{\phi \tau} \sim 0.103479

    Therefore the detector collected charge is given by

    .. math::
            Q_{det} = \frac{Q_{wd}}{0.103479} \cdot \left(1 - e^\frac{- 0.103479 \, Q}{Q_{wd}}\right)

    Which can be approximated by a polynomial of order 4 as

    .. math::

            Q_{det} = Q\left[ 1- \frac{1}{2!}\frac{0.103479}{Q_{wd}} Q

            + \frac{1}{3!}\left(\frac{0.103479}{Q_{wd}}\right)^2 Q^2

            - \frac{1}{4!}\left(\frac{0.103479}{Q_{wd}}\right)^3 Q^3

            + \frac{1}{5!}\left(\frac{0.103479}{Q_{wd}}\right)^4 Q^4 \right]

    The results are the coefficients for a 4-th order polynomial:

    .. math::
        Q_{det} = Q \cdot (a_1 + a_2 \cdot Q + a_3 \cdot Q^2 + a_4 \cdot Q^3 + a_5 \cdot Q^4)

    However, each pixel is different, and therefore, this class also produces a map of the coefficient for each pixel.
    Each coefficient is normally distributed around the mean value, with a standard deviation indicated in the configuration.
    If no standard deviation is indicated, the coefficients are assumed to be constant.

    The code output is a map of :math:`a_i` coefficients for each pixel, which can be injected into  :class:`~exosim.tasks.detector.applyPixelsNonLinearity.ApplyPixelsNonLinearity`.

    Examples
    ----------

    >>> import exosim.tools as tools
    >>>
    >>> results = tools.PixelsNonLinearity(options_file='tools_input_example.xml',
    >>>                                    output='output_pnl_map.h5')


    *Abstract class*

    Base class for exosim tools.

    Attributes
    ----------------
    ch_param: dict
        dictionary for the channels' configurations
    options: dict
        configurations dictionary
    results: dict
        dictionary for the results output


    Produces the channel dark current map

    Returns
    --------
    :class:`~exosim.models.signal.Signal`
        channel dark current map

    Raises
    ------
    TypeError:
        if the output is not a :class:`~exosim.models.signal.Signal` class

    Notes
    -----
    This is a default class with standardized inputs and outputs.
    The user can load this class and overwrite the "model" method
    to implement a custom Task to replace this.


    It computes the desired ADC gain, given the number of bits used by the ADC
    and the maximum number of counts in the pixel to represent.

    Returns
    --------
    dict
        ADC gain factors

    Examples
    ----------

    >>> import exosim.tools as tools
    >>>
    >>> tools.ADCGainEstimator(options_file='tools_input_example.xml')


    This tool helps in the definition of the channels' readout schemes.
    Starting from the desired readout format, this tool estimates
    the best parameters to set in the channel description to best fit the ramp.

    Attributes
    ----------
    input: str
        input file
    options: dict
        This is parsed from :class:`~exosim.tasks.load.loadOptions.LoadOptions`

    Examples
    --------
    >>> import exosim.tools as tools
    >>>
    >>> tools.ReadoutSchemeCalculator(options_file = 'tools_input_example.xml',
    >>>                               input_file='input_file.h5')


    This tools helps the user to find the pixel non-linearity coefficients to as inputs for ExoSim,
    starting from the measurable pixel non-linearity correction.

    In fact, the detector non linearity model, is usually written as polynomial such as

    .. math::
        Q_{det} = Q \\bigtriangleup (1 + \\sum_i a_i \\cdot Q^i)

    where :math:`Q_{det}` is the charge read by the detector, and :math:`Q` is the ideal count,
    as :math:`Q = \\phi_t`, with :math:`\\phi` being the number of electrons generated and :math:`t` being the elapsed time.
    In the equation above, :math:`\\bigtriangleup` is the operator used to defined the relation between :math:`Q_{det}` and :math:`Q`,
    which depends on the definition of the coefficients :math:`a_i` (see also equation below).

    However, it is usually the inverse operation that is known, as it's coefficients are measurable empirically:

    .. math::
        Q ={Q_{det}}\\bigtriangledown ( b_1 + \\sum_{i=2} b_i \\cdot Q_{det}^i)

    Where :math:`\\bigtriangledown` is the inverse operator of :math:`\\bigtriangleup`.
    Depending on the way the non linearity is estimated, the operator can either be a division (:math:`\\div`)
    or a multiplication (:math:`\\times`). If not specified, a division is assumed.

    The :math:`b_i` correction coefficients should be listed in the configuration file using the `pnl_coeff` keyword
    in increasing alphabetical order: `pnl_coeff_a` for :math:`b_1`,
    `pnl_coeff_b` for :math:`b_2`, `pnl_coeff_c` for :math:`b_3`,
    `pnl_coeff_d` for :math:`b_4`, `pnl_coeff_e` for :math:`b_5` and so on.
    The user can list any number of correction coefficients, and they will be automatically parsed.
    Please, note that using this notation, :math:`b_1` is not forced to be the unity.

    This class will restrieve the :math:`a_i` coefficients, starting from the the indicated :math:`b_i`.
    The results are the coefficients for a 4-th order polynomial:

    .. math::
        Q_{det} = Q \\cdot (a_1 + a_2 \\cdot Q + a_3 \\cdot Q^2 + a_4 \\cdot Q^3 + a_5 \\cdot Q^4)

    However, each pixel is different, and therefore, this class also produces a map of the coefficient for each pixel.
    Each coefficient is normally distributed around the mean value, with a standard deviation indicated in the configuration.
    If no standard deviation is indicated, the coefficients are assumed to be constant.

    The code output is a map of :math:`a_i` coefficients for each pixel, which can be injected into  :class:`~exosim.tasks.detector.applyPixelsNonLinearity.ApplyPixelsNonLinearity`.

    Attributes
    -----------
    operator_dict: dict
        dictionary of operators to use to estimates :math:`Q_{det}`
    Npt: int
        number of points used to estimate the coefficients

    Examples
    ----------

    >>> import exosim.tools as tools
    >>>
    >>> results = tools.PixelsNonLinearityFromCorrection(options_file='tools_input_example.xml',
    >>>                                                 output='output_pnl_map.h5')


    Pipeline to create the observation NDRs.
    This pipeline loads the configuration file and the Sub-Exposures.

    Examples
    --------

    >>> import exosim.recipes as recipes
    >>> recipes.CreateNDRs(input_file='./input_file.h5',
    >>>                    output_file = 'ndrs_file.h5',
    >>>                    options_file='main _configuration.xml')


    Pipeline to create the radiometric model.
    This pipeline has three working modes:

    - it can load an already produced focal plane and use it to estimate a radiometric model;
    - it can produce a single sourec focal planet and estimate the radiometric model;
    - it can load a target list and produce the radiometric model for each target of the target list.

    Attributes
    ------------
    mainConfig: dict
        This is parsed from :class:`~exosim.tasks.load.loadOptions.LoadOptions`
    input: :class:`~exosim.output.output.Output`
        input/output file
    payloadConfig: dict
        payload configuration dictionary extracted from mainConfig`
    table: :class:`~astropy.table.QTable`
        table for the radiometric estimations

    Examples
    --------

    If the user wants to estimate the radiometric model af an existing focal plane

    >>> import exosim.recipes as recipes
    >>> rm = recipes.RadiometricModel(options_file= 'main _configuration.xml',
    >>>                                input_file = 'focal_plane.h5')

    Otherwhise, if a focal planet has not been produced yet, this recipy can produce it,
    if a destination not existing file is provided:

    >>> import exosim.recipes as recipes
    >>> rm = recipes.RadiometricModel(options_file= 'main _configuration.xml',
    >>>                                input_file = 'desired_output.h5')

    In both cases, to store the produced table into the output file,
    the :func:`~exosim.recipes.radiometricModel.RadiometricModel.write`
    is to be used:

    >>> rm.write()


    Pipeline to create the focal planes sub-exposures.
    This pipeline loads the configuration file and the produced focal planes to produce the sub-exposures.
    It prepares the pointing jitter first, then it scales it to the instrument focal planes pixels.
    It estimates the detector reading scheme, considering instantaneous readout,
    and it produces the sub-exposures by jittering the focal planes.

    Attributes
    ------------
    input: str
        input file
    mainConfig: dict
        This is parsed from :class:`~exosim.tasks.load.loadOptions.LoadOptions`
    payloadConfig: dict
        payload configuration dictionary extracted from mainConfig
    jitter_spa: :class:`~astropy.units.Quantity`
        pointing jitter in the spatial direction expressed in units of :math:`deg`.
    jitter_spe: :class:`~astropy.units.Quantity`
        pointing jitter in the spectral direction expressed in units of :math:`deg`.

    Examples
    --------

    >>> import exosim.recipes as recipes
    >>> recipes.CreateSubExposures(input_file='./input_file.h5',
    >>>                            output_file = 'se_file.h5',
    >>>                            options_file='main _configuration.xml')


    Pipeline to create the instrument focal planes.
    This pipeline loads the configuration file and produces an output, if indicated,
    where all the products are stored.
    It loads the source SED and the foregrounds and, after the optical chain production,
    it estimates the focal plane for the source and for the foregrounds.

    Attributes
    ------------
    mainConfig: dict
        This is parsed from :class:`~exosim.tasks.load.loadOptions.LoadOptions`
    output: :class:`~exosim.output.output.Output` (optional)
        output file
    payloadConfig: dict
        payload configuration dictionary extracted from mainConfig`
    time: :class:`~astropy.units.Quantity`
        time grid.
    wl_grid: :class:`~numpy.ndarray` or :class:`~astropy.units.Quantity`
        wavelength grid.

    Examples
    --------

    >>> import exosim.recipes as recipes
    >>> recipes.CreateFocalPlane(options_file= 'main _configuration.xml',
    >>>                          output_file = 'output_file.h5')


Creates a NASA EarthData Login session. More info at https://urs.earthdata.nasa.gov/documentation/what_do_i_need_to_know
    From https://github.com/asfadmin/Discovery-asf_search/


    This Map class inherits the ipyleaflet Map class.
    Modified: https://github.com/giswqs/geodemo/blob/master/geodemo/geodemo.py
    Args:
        ipyleaflet (ipyleaflet.Map): An ipyleaflet map.


 A simulator superclass: all simulators are derived from this class

    Attributes:
        sim_name;
        prefix;
        id;
        nsim;
        base_file;
        dir_list;
        var_list;
        batch_file;
        qsub_command;
        batch_check;
        batch_size = 0;
        is_success;
        verbose = 0;


The ecosys simulator for the Duke Forest problem


    Class is initialized with one or a sequence of strings that are treated as
    regular expressions.  The () operation returns True if the argument matches
    any of the regular expressions.
    Initializing with None or empty list means anything will match.


Class collecting the information we need about each night's observations


    Class is a list of AttributeFinders which all encode a given keyword.
    They are added in order of increasing priority.  We will try each one (in reverse order)
    to see if it can assign a value to the attribute, and take the first one that succeeds.


Function class which returns the star flat epoch nearest to specifed input MJD
    that does not have an intervening camera event.  Returns '00000000' if no star flats
    occur in the same interval between events.


Abstract field definition.

    Child classes must override ``type`` class attribute to provide datatype
    infromation of the field definition. For more info about types visit
    `http://www.clicketyclick.dk/databases/xbase/format/data_types.html`

    Also child classes must override ``defaultValue`` field to provide
    default value for the field value.

    If child class has fixed length ``length`` class attribute must be
    overriden and set to the valid value. None value means, that field
    isn't of fixed length.

    Note: ``name`` field must not be changed after instantiation.


Definition of the character field.


Definition of the numeric field.


Definition of the integer field.


Definition of the currency field.


Definition of the logical field.


Definition of the memo field.


Definition of the general (OLE object) field.


Definition of the date field.


Definition of the timestamp field.


Field definition.

    This is a simple structure, which contains ``name``, ``type``,
    ``len``, ``dec`` and ``cls`` fields.

    Objects also implement get/setitem magic functions, so fields
    could be accessed via sequence iterface, where 'name' has
    index 0, 'type' index 1, 'len' index 2, 'dec' index 3 and
    'cls' could be located at index 4.


New .DBF creation helper.

    Example Usage:

        dbfn = dbf_new()
        dbfn.add_field("name",'C',80)
        dbfn.add_field("price",'N',10,2)
        dbfn.add_field("date",'D',8)
        dbfn.write("tst.dbf")

    Note:
        This module cannot handle Memo-fields,
        they are special.


DBF record.

    Instances of this class shouldn't be created manualy,
    use `dbf.Dbf.newRecord` instead.

    Class implements mapping/sequence interface, so
    fields could be accessed via their names or indexes
    (names is a preffered way to access fields).

    Hint:
        Use `store` method to save modified record.

    Examples:
        Add new record to the database:
            db = Dbf(filename)
            rec = db.newRecord()
            rec["FIELD1"] = value1
            rec["FIELD2"] = value2
            rec.store()
        Or the same, but modify existed
        (second in this case) record:
            db = Dbf(filename)
            rec = db[2]
            rec["FIELD1"] = value1
            rec["FIELD2"] = value2
            rec.store()


DBF accessor.

    FIXME:
        docs and examples needed (dont' forget to tell
        about problems adding new fields on the fly)

    Implementation notes:
        ``_new`` field is used to indicate whether this is
        a new data table. `addField` could be used only for
        the new tables! If at least one record was appended
        to the table it's structure couldn't be changed.


Works in the same way as a ``property``, but for the classes.


Value returned from DBF records when field validation fails

    The value is not equal to anything except for itself
    and equal to all empty values: None, 0, empty string etc.
    In other words, invalid value is equal to None and not equal
    to None at the same time.

    This value yields zero upon explicit conversion to a number type,
    empty string for string types, and False for boolean.


Dbf header definition.

    For more information about dbf header format visit
    `http://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_STRUCT`

    Examples:
        Create an empty dbf header and add some field definitions:
            dbfh = DbfHeader()
            dbfh.addField(("name", "C", 10))
            dbfh.addField(("date", "D"))
            dbfh.addField(DbfNumericFieldDef("price", 5, 2))
        Create a dbf header with field definitions:
            dbfh = DbfHeader([
                ("name", "C", 10),
                ("date", "D"),
                DbfNumericFieldDef("price", 5, 2),
            ])


Data read from or written to Memo file.

    This is 8-bit string data with additional attribute
    type which can accept values of the TYPE_* constants.


Memo file object


Convert Fortran arrays to NumPy and vice-versa


Leverages NVTX & NSYS to profile CUDA kernels.


Projection class for NSIDC EASE grid north


    Takes concept_ids and runs downloader/validator on each

    1. Can generate list of concept_ids from CMR query
    2. Accepts custom list of concept_ids


Tracks the status of each check


Validator class for datetime datatype


Validates downloaded metadata for its schema and returns the result.


Base class for all the validators


Validator class for URLs


Validator class for string values


Class to implement custom checks


Schedules the rules based on the applicable ordering


Downloads data given a concept ID


Handles both the structural and logical checks


Validator class for all the GCMD keywords (science, instruments, providers)


Test cases for the methods in Downloader class in downloder.py


Test cases for the CustomChecker script in custom_checker.py


Test cases for the validator script in validator.py


Test cases for the Checker script in checker.py


Cluster objects are intended to be pythonic representations of
    a galaxy cluster for processing through the Xray pypeline.


A Gaussian prior clipped to some range.


Like log-normal, but the distribution of ln of the variable is
    distributed uniformly instead of normally.


Main concatenation testing class.


    A harmony-service-lib wrapper around the concatenate-batcher module.
    This wrapper does not support Harmony calls that do not have STAC catalogs
    as support for this behavior is being depreciated in harmony-service-lib


Class generating dipole fields


Class generating a scaling vector potential for the inflow IMF


    Object that holds the stellar grid and its properties, as well as useful
    functions.

    Parameters
    ----------
    intensity_array (``numpy.ndarray``):
        Array of normalized intensities.

    radius_px (``int`` or ``float``, optional):
        Stellar radius in units of pixels.

    limb_darkening_law (``None`` or ``str``, optional):
        String with the name of the limb-darkening law.

    ld_coefficients (``float`` or ``array-like``):
        Limb-darkening law coefficients.

    supersampling (``int``, ``float``, or ``None``, optional):
        Supersampling factor.

    upscaling (``int``, ``float``, or ``None``, optional):
        Upscaling factor.

    resample_method (``str`` or ``None``, optional):
        Algorithm used to resize the grid.


Future class for making everything more OOP-sie


Generic instrument class. Contains things that all routines will need (e.g. dark subtraction, flat fielding, sky subtraction, bad pixel identification etc) while specific reduction routines are provided in extension classes. As much as possible, uncertainty tracking should be included here.


A result type that represents either a success or failure outcome.


A successful result with a value.


A failed result with an error.


Strongly typed configuration for Simbi build process.


(Hard Test: Fails)
    Shock with non-zero transverse velocity on both sides in 2D with 1 Partition
    This setup was adapted from Zhang and MacFadyen (2006) section 6.1


Kelvin Helmholtz problem in Newtonian Fluid


Left and right states for shock tube problems


Complete state for MHD shock tube problems


Mignone & Bodo (2006), Relativistic MHD Test Problems in 1D Mesh


State class for Quirk's problem with custom operations


    Quirk's problem in Newtonian Fluid from Quirk (1994),
    "A contribution to the great Riemann solver debate"
    This problem is a shock tube which is designed to exacerbate
    the carbuncle instability and odd-even decoupling in numerical schemes.
    Turning the `use_quirk_smoothing` flag on will apply a smoothing
    technique to mitigate these issues, as described in Quirk's paper.


The Thermal Bomb
    Launch a relativistic blast wave on a 3D Spherical Logarithmic mesh with variable zones per decade in radius


Physical parameters for isentropic wave


State calculator for isentropic wave


Relativistic Isentropic Pulse in 1D, Entropy conserving


The Magnetic Bomb
    Launch a cylindrical relativistic magnetized blast wave


Container that stores face-centered magnetic fields
    and cell-centered gas variables


Komissarov (1999), 1D SRMHD test problems.


    A thin ring of matter in Keplerian orbit.
    Tests angular momentum conservation and numerical viscosity.


The Sedov Taylor Problem
    Sedov-Taylor Explosion on a 2D Spherical logarithmic mesh with variable zones per decade in radius


Marti & Muller (2003), Relativistic Shock Tube Problem on 1D Mesh


Dataclass for Shock Tube State


    Sod's Shock Tube Problem in 2D Newtonian Fluid with 4 Partitions
    This setup was adapted from Zhang and MacFadyen (2006) section 4.8 pg. 11


Rayleigh Taylor problem in Newtonian Fluid


The Orszag-Tang vortex test case


Stationary Wave Test Problems in 1D Newtonian Fluid using HLL solver


Stationary Wave Test Problems in 1D Newtonian Fluid using HLLC solver


Mignone, Ugliano, & Bodo (2009), 1D SRMHD test problems.


Marti & Muller (2003), Relativistic Shock Tube Problem on 3D Mesh


State for split shock problem


    Shock with non-zero transverse velocity on one side in 2D with 1 Partition
    This setup was adapted from Zhang and MacFadyen (2006) section 4.4


Mignone & Bodo (2005), Relativistic Test Problems on 1D Mesh


State for shock heating problem


    1D shock-heating problem in planar geometry
    This setup was adapted from Zhang and MacFadyen (2006) section 4.5


Sod's Shock Tube Problem in 1D Newtonian Fluid


The Thermal Bomb
    Launch a relativistic blast wave on a 2D Spherical Logarithmic mesh with variable zones per decade in radius


Interface for simbi simulations using the new core.


Immutable directed acyclic graph of expressions.


Functional, immutable expression reference.


Compiled expression for efficient evaluation.


We're now gonna use Rich for beautiful terminal output


Handles formatting of different parameter types for display


Generates ASCII art for parameter summary display


Computes and formats summary statistics for the simulation


Renders parameter categories and their parameters


Main class for generating simulation parameter summaries


Handles conversion of configuration to execution format


Valid boundary conditions


Configuration for gravitational system.


Manages the execution of a simulation.

    This class orchestrates the initialization, execution, and output
    handling for a simulation.

    Attributes:
        config: The configuration for the simulation
        state: The current simulation state


Container for simulation state data.


Base model for CLI-configurable Pydantic models.

    This class extends Pydantic's BaseModel with methods for integrating
    with command-line interfaces. It processes SimbiField metadata to
    automatically register CLI parameters.


Base configuration model for simbi simulations.

    This provides a structured, validated configuration for all simulations.
    Problem implementations should extend this class and provide problem-specific
    parameters and methods.


Main parser for simbi CLI


Base parser interface


Sets computation mode (cpu/gpu/omp)


takes the user input, and sets the environment variables for GPU block dimensions


Maps field names to LaTeX strings


Main visualization container


Custom action to set plot style from flag or direct argument


Custom action to turn list of items into cycle


Bridge between existing data processing logic and new components


Container for accretion time series data


Container for time series data


Temporal plot visualization component


Base class for all visualization components


Line plot visualization component


Handles title display and formatting


Histogram visualization component for distribution functions


2D/3D visualization component


Text style configuration


Plot style configuration


Handles plot formatting


Container for simulation data


Handles data I/O operations


Manages themes for visualization components


Central theme configuration for visualization styling


Formats plot axes based on data and configuration


Handles colorbar creation and formatting


Handles data processing pipeline


Handles parsing of plotting arguments


Handles 2D and 3D visualization


Histogram plotter for distribution functions


Plots mean quantities vs time


Line plot implementation with mixins


Mixin for data handling operations


Mixin for animation capabilities


Mixin for coordinate system operations


Registry for argument-to-config mapping metadata


Plot configuration type definition


Style configuration type definition


Multidimensional plot configuration


Complete visualization configuration


Basic plot configuration


Multidimensional plot settings


Builds structured configuration from various input sources


Controls animation of visualization components


Central state container for visualization components


Lazily reads simulation data from HDF5 files, including fields, metadata, and mesh.


Option type for handling computations that may fail


Post-installation for development mode.


All directory paths.


    Method containing survey parameters and functions.

    Args:
        name (str): Name of survey with which to observe population. Can
            either be a predefined survey present in frbpoppy or a path name to
            a new survey filename
        n_days (float): Time spent surveying [days]


Create/use a NE2001 lookup table for dispersion measure.


    Create/use a lookup table for comoving distance, volume, redshift etc.

    Create a list of tuples to lookup the corresponding redshift for a comoving
    distance [Gpc] (or the other way around). Uses formulas from
    Hoggs et al. (1999) for the cosmological calculations. To avoid long
    calculation times, it will check if a previous run with the same parameters
    has been done, which it will then load it. If not, it will calculate a new
    table, and save the table for later runs. Covers z, dist, vol, dvol,
    cdf_sfr and cdf_smd and several delayed cdf_sfr.

    Args:
        H_0 (float, optional): Hubble parameter. Defaults to 67.74 km/s/Mpc
        W_m (float, optional): Omega matter. Defaults to 0.3089
        W_k (float, optional): Omega vacuum. Defaults to 0.6911


Class to hold a population of FRBs.


Method to deal with a large population.

    Basically splits it up, and merges the results.


    Add frbpoppy functionality to Frbcat.

    Get the pandas dataframe with Frbcat().df


Class for cosmic number density.


Gather all elements needed for a plot.


Gather plotting options.


Class to create a survey population of FRBs.


Class for converting redshift to other distance measures.


Class to hold rate counters.


Class containing FRB properties.


Generate a cosmic FRB population.


Given values, return uid

    Load from file, or make.


Gather input for each run.


        Operator comprising the likelihood contribution to the diffuse signal's
        covariance operator.

        See Also
        --------
        nifty.operator

        Notes
        -----
        Confer D3PO reference equation (B.2) or (B.5).


        The diffuse signal's covariance operator D^(s), here ``D``.

        See Also
        --------
        nifty.nifty_tools.propagator_operator

        Notes
        -----
        This operator is derived from the :py:class:`propagator_operator`.
        It uses a conjugate gradient for (normal) application, and involves
        Levenberg damping to ensure positive definiteness.
        Confer D3PO reference equation (B.2) or (B.5).


        The point-like signal's covariance operator D^(u), here ``F``.

        See Also
        --------
        nifty.nifty_tools.invertible_operator

        Notes
        -----
        This operator is derived from the :py:class:`invertible_operator`.
        It uses a conjugate gradient for (normal) application, and involves
        Levenberg damping to ensure positive definiteness.
        Confer D3PO reference equation (B.3) or (B.6).


        D3PO problem class.

        Its purpose is to condense a D3PO problem and provide a solver.

        Parameters
        ----------
        R : operator
            Response operator.
        configfile : string
            Name of the D3PO config file (default: "config").
        workingdirectory : string
            Name of the working directory (default: os.getcwd()).

        See Also
        --------
        demo.py

        Examples
        --------
        >>> import d3po
        >>> p = d3po.problem([RESPONSE_OPERATOR],[CONFIG_FILE])
        >>> p.solve([DATA_ARRAY])

        Attributes
        ----------
        R : operator
            Response operator.
        d : field
            Data vector
        config : configuration
            Configuration instance.
        z : space
            Image space.
        k : space
            Harmonic space.
        `s_` : field
             Current diffuse signal field.
        `u_` : field
             Current point-like signal field.
        `D_` : field
             Current diagonal of the diffuse covariance operator.
        `F_` : field
             Current diagonal of the point-like covariance operator.
        S : operator
            Prior covariance of the (current) diffuse signal field.
        Sk : operator
            Projection operator.
        M : operator
            Ms_operator instance.
        D : operator
            Ds_operator instance.
        F : operator
            Du_operator instance.
        note : notification
            Notification instance.
        _restrict : {bool, array}
            Dummy for restrictions.
        _io : array
            Dummy for IO indices


        Class for D3PO demonstration response operators

        This response involves a convolution with an exposure mask and a
        given kernel. Additionally, a binary mask excluding pixels hosting
        bright point sources can be included.

        Parameters
        ----------
        domain : space
            The space wherein valid arguments live.
        kernel : ndarray
            Normalised 1D convolution kernel with finite support.
        exposure : ndarray
            Exposure array mathching the dimensionality of the domain.
        mask : ndarray
            Masking array mathching the dimensionality of the domain.
        den : bool, *optional*
            Whether to consider the arguments as densities or not;
            mandatory for the correct incorporation of volume weights
            (default: False).
        target : space, *optional*
            The space wherein the operator output lives.

        See Also
        --------
        response_operator

        Raises
        ------
        TypeError
            If domain is no NIFTY space.

        Attributes
        ----------
        domain : space
            The space wherein valid arguments live.
        kernel : ndarray
            Normalised 1D convolution kernel with finite support.
        exposure : ndarray
            Exposure array mathching the dimensionality of the domain.
        mask : ndarray
            Masking array mathching the dimensionality of the domain.
        identify_io_pixels : bool
            Boolean indicating whether there is an equivalence between data
            and signal space; i.e., pixels are uniquely associated by their
            raveled indices.
        mask_out_pixels : switch
            Switch controlling the usage of the masking array that excludes
            pixels hosting bright point sources.
        sym : bool
            Indicates whether the operator is self-adjoint or not.
        uni : bool
            Indicates whether the operator is unitary or not.
        imp : bool
            Indicates whether the incorporation of volume weights in
            multiplications is already implemented in the `multiply`
            instance methods or not.
        den : bool
            Whether to consider the arguments as densities or not.
            Mandatory for the correct incorporation of volume weights.
        target : space
            The space wherein the operator output lives


Computes an estimate based on the Multi-Level Monte Carlo algorithm.


Abstract base class defining data inputs from which samples can be drawn.


Used to draw random samples from a data file.


    Used to draw samples from a specified distribution . Any distribution
    function provided must accept a "size" parameter that determines the
    sample size.


    Adds the product of the inner model outputs to the wrapper output array so
    that covariance may be calculated.


    Generates CDF indicators from an inner model that will be used by
    MLMCSimulator to generate a CDF from the inner model outputs.


Used to produce outputs from inputs based on data provided in text files.


    Abstract base class for Models which should evaluate sample inputs to
    produce outputs.

    :param inputs: one dimensional ndarray
    :return: two dimensional ndarray


    Defines Spring Mass model with 1 free param (stiffness of spring, k). The
    quantity of interest that is returned by the evaluate() function is the
    maximum displacement over the specified time interval


Custom adapter for Harmony SMAP L2 Gridding Service.


Base service exception.


Base error class for exceptions raised by smap_l2_gridder library.


Class for holding a GDAL-style 6-element geotransform.


The QCD beta function


The QCD gamma function


The strong coupling constant


 The running MS-bar quark mass

     Flavor can be one of the following: 't', 'b', 'c', 's', 'd', 'u'
     It determines the number of thresholds when running the quark mass


    Class that implements the Navarro, Frenk, & White (1997) profile:

        rho(R,z) = rho_crit * delta_char / [(r/r_s) * (1+r/r_s)^2]
                 = rho_0 / [(r/r_s) * (1+r/r_s)^2]

    in a cylindrical frame (R,phi,z), where

        r = sqrt(R^2 + z^2)
        r_s: scale radius, at which d ln rho(r) / d ln(r) = -2
        rho_crit: critical density of the Universe
        delta_char = Delta_halo / 3 * c^3 / f(c), where c = R_vir / r_s
            is the concentration parameter

    Syntax:

        halo = NFW(M,c,Delta=200.,z=0.)

    where

        M: halo mass [M_sun], where halo is defined as spherical
            overdensity of Delta times critical density (float)
        c: halo concentration (float)
        Delta: average overdensity of the halo, in multiples of the
            critical density of the Universe (float)
            (default 200.)
        z: redshift (float) (default 0.)

    Attributes:

        .Mh: halo mass [M_sun]
        .ch: halo concentration
        .Deltah: spherical overdensity wrt instantaneous critical density
        .z: redshift
        .rhoc: critical density [M_sun kpc^-3]
        .rhoh: average density of halo [M_sun kpc^-3]
        .rh: halo radius within which density is Delta times rhoc [kpc]
        .rs: scale radius [kpc]
        .rmax: radius at which maximum circular velocity is reached [kpc]
        .Vmax: maximum circular velocity [kpc/Gyr]
        .s001: logarithmic density slope at 0.01 halo radius
        .rhalf: half-mass radius [kpc]

    Methods:

        .rho(R,z=0.): density [M_sun kpc^-3] at radius r=sqrt(R^2+z^2)
        .s(R,z=0.): logarithmic density slope at radius r=sqrt(R^2+z^2)
        .M(R,z=0.): mass [M_sun] enclosed in radius r=sqrt(R^2+z^2)
        .rhobar(R,z=0.): mean density [M_sun kpc^-3] within radius
            r=sqrt(R^2+z^2)
        .tdyn(R,z=0.): dyn. time [Gyr] within radius r = sqrt(R^2+z^2)
        .Phi(R,z=0.): potential [(kpc/Gyr)^2] at radius r=sqrt(R^2+z^2)
        .fgrav(R,z): grav. acceleration [(kpc/Gyr)^2 kpc^-1] at (R,z)
        .Vcirc(R,z=0.): circ. vel. [kpc/Gyr] at radius r=sqrt(R^2+z^2)
        .sigma(R,z=0.): vel. disp. [kpc/Gyr] at radius r=sqrt(R^2+z^2)

    HISTORY: Arthur Fangzhou Jiang (2016-10-24, HUJI)
             Arthur Fangzhou Jiang (2016-10-30, HUJI)
             Arthur Fangzhou Jiang (2019-08-24, HUJI)


    Class that implements the Burkert (1995) profile:

        rho(R,z) = rho_0 / [(1+x)(1+x^2)], x = r/r_s

    in a cylindrical frame (R,phi,z), where

        r = sqrt(R^2 + z^2)
        r_s: scale radius, at which d ln rho(r) / d ln(r) = -2
        rho_crit: critical density of the Universe
        delta_char = Delta_halo / 3 * c^3 / f(c), where c = R_vir / r_s
            is the concentration parameter

    Syntax:

        halo = Burkert(M,c,Delta=200.,z=0.)

    where

        M: halo mass [M_sun], where halo is defined as spherical
            overdensity of Delta times critical density (float)
        c: Burkert concentration, R_vir/r_s (float)
        Delta: average overdensity of the halo, in multiples of the
            critical density of the Universe (float)
            (default 200.)
        z: redshift (float) (default 0.)

    Attributes:

        .Mh: halo mass [M_sun]
        .ch: halo concentration
        .Deltah: spherical overdensity wrt instantaneous critical density
        .z: redshift
        .rhoc: critical density [M_sun kpc^-3]
        .rhoh: average density of halo [M_sun kpc^-3]
        .rh: halo radius within which density is Delta times rhoc [kpc]
        .rs: scale radius [kpc]
        .rmax: radius at which maximum circular velocity is reached [kpc]
        .rho0: central density [M_sun kpc^-3]
        .Vmax: maximum circualr velocity [kpc/Gyr]
        .s001: logarithmic density slope at 0.01 halo radius
        .rhalf: half-mass radius [kpc]

    Methods:

        .rho(R,z=0.): density [M_sun kpc^-3] at radius r=sqrt(R^2+z^2)
        .s(R,z=0.): logarithmic density slope at radius r=sqrt(R^2+z^2)
        .M(R,z=0.): mass [M_sun] enclosed in radius r=sqrt(R^2+z^2)
        .rhobar(R,z=0.): mean density [M_sun kpc^-3] within radius
            r=sqrt(R^2+z^2)
        .tdyn(R,z=0.): dyn. time [Gyr] within radius r = sqrt(R^2+z^2)
        .Phi(R,z=0.): potential [(kpc/Gyr)^2] at radius r=sqrt(R^2+z^2)
        .fgrav(R,z): grav. acceleration [(kpc/Gyr)^2 kpc^-1] at (R,z)
        .Vcirc(R,z=0.): circ. vel. [kpc/Gyr] at radius r=sqrt(R^2+z^2)
        .sigma(R,z=0.): vel. disp. [kpc/Gyr] at radius r=sqrt(R^2+z^2)

    HISTORY: Arthur Fangzhou Jiang (2020-07-29, Caltech)


    Class that implements the "coreNFW" profile (Read+2016):

        M(r) = M_NFW(r) g(y)
        rho(r) = rho_NFW(r) g(y) + [1-g(y)^2] M_NFW(r) / (4 pi r^2 r_c)

    in a cylindrical frame (R,phi,z), where

        r = sqrt(R^2 + z^2)
        y = r / r_c with r_c a core radius, usually smaller than r_s
        g(y) = tanh(y)

    Syntax:

        halo = coreNFW(M,c,rc,Delta=200.,z=0.)

    where

        M: halo mass [M_sun], where halo is defined as spherical
            overdensity of Delta times critical density (float)
        c: NFW halo concentration (float)
        rc: core radius [kpc]
        Delta: average overdensity of the halo, in multiples of the
            critical density of the Universe (float)
            (default 200.)
        z: redshift (float) (default 0.)

    Attributes:

        .Mh: halo mass [M_sun]
        .ch: halo concentration
        .Deltah: spherical overdensity wrt instantaneous critical density
        .z: redshift
        .rhoc: critical density [M_sun kpc^-3]
        .rhoh: average density of halo [M_sun kpc^-3]
        .rh: halo radius within which density is Delta times rhoc [kpc]
        .rs: scale radius [kpc]
        .rc: core radius [kpc]
        .rmax: radius at which maximum circular velocity is reached [kpc]
        .Vmax: maximum circular velocity [kpc/Gyr]
        .s001: logarithmic density slope at 0.01 halo radius
        .rhalf: half-mass radius [kpc]

    Methods:

        .rho(R,z=0.): density [M_sun kpc^-3] at radius r=sqrt(R^2+z^2)
        .s(R,z=0.): logarithmic density slope at radius r=sqrt(R^2+z^2)
        .M(R,z=0.): mass [M_sun] enclosed in radius r=sqrt(R^2+z^2)
        .rhobar(R,z=0.): mean density [M_sun kpc^-3] within radius
            r=sqrt(R^2+z^2)
        .tdyn(R,z=0.): dyn. time [Gyr] within radius r = sqrt(R^2+z^2)
        .Phi(R,z=0.): potential [(kpc/Gyr)^2] at radius r=sqrt(R^2+z^2)
        .fgrav(R,z): grav. acceleration [(kpc/Gyr)^2 kpc^-1] at (R,z)
        .Vcirc(R,z=0.): circ. vel. [kpc/Gyr] at radius r=sqrt(R^2+z^2)
        .sigma(R,z=0.): vel. disp. [kpc/Gyr] at radius r=sqrt(R^2+z^2)

    HISTORY: Arthur Fangzhou Jiang (2021-03-11, Caltech)


    Class that implements Dekel+ (2016) profile:

        rho(R,z)=rho_0/[(r/r_s)^alpha * (1+(r/r_s)^(1/2))^(2(3.5-alpha))]
        M(R,z) = M_vir * g(x,alpha) / g(c,alpha)
               = M_vir [chi(x)/chi(c)]^[2(3-alpha)]

    in a cylindrical frame (R,phi,z), where

        r = sqrt(R^2 + z^2)
        c: concentration parameter
        r_s: scale radius, i.e., R_vir / c, where R_vir is the virial
            radius. (Note that unlike NFW or Einasto, where r_s is r_-2,
            here r_s is not r_-2, but 2.25 r_-2 / (2-alpha)^2 )
        alpha: shape parameter, the innermost logarithmic density slope
        x = r/r_s
        chi(x) = x^(1/2) / (1+x^(1/2))
        g(x,alpha) = chi(x)^[2(3-alpha)]
        rho_0: normalization density,
            rho_0 = c^3 (3-alpha) Delta rho_crit / [3 g(c,alpha)]
        M_vir: virial mass, related to rho_0 via
            M_vir = 4 pi rho_0 r_s^3 g(c,alpha) / (3-alpha)

    Syntax:

        halo = Dekel(M,c,alpha,Delta=200.,z=0.)

    where

        M: halo mass [M_sun], where halo is defined as spherical
            overdensity of Delta times critical density (float)
        c: concentration (float)
        alpha: shape parameter, the inner most log density slope (float)
            (there are singularities for computing potential and
            velocity dispersion, at 1+i/4, for i=0,1,2,...,8)
        Delta: multiples of the critical density of the Universe
            (default 200.)
        z: redshift (float) (default 0.)

    Attributes:

        .Mh: halo mass [M_sun]
        .ch: halo concentration
        .alphah: halo innermost logarithmic density slope
        .Deltah: spherical overdensity wrt instantaneous critical density
        .z: redshift
        .rhoc: critical density [M_sun kpc^-3]
        .rhoh: average density of halo [M_sun kpc^-3]
        .rh: halo radius within which density is Delta times rhoc [kpc]
        .rs: scale radius [kpc]
        .rmax: radius at which maximum circular velocity is reached [kpc]
        .Vmax: maximum circular velocity [kpc/Gyr]
        .s001: logarithmic density slope at 0.01 halo radius
        .sh: the old name for s001, kept for compatibility purposes
        .rhalf: half-mass radius [kpc]

    Methods:

        .rho(R,z=0.): density [M_sun kpc^-3] at radius r =sqrt(R^2 + z^2)
        .s(R,z=0.): logarithmic density slope at radius r=sqrt(R^2+z^2)
        .M(R,z=0.): mass [M_sun] enclosed in radius r = sqrt(R^2 + z^2)
        .rhobar(R,z=0.): mean density [M_sun kpc^-3] within radius
            r=sqrt(R^2+z^2)
        .tdyn(R,z=0.): dyn. time [Gyr] within radius r = sqrt(R^2 + z^2)
        .Phi(R,z=0.): potential [(kpc/Gyr)^2] at radius r=sqrt(R^2+z^2)
        .fgrav(R,z): grav. acceleration [(kpc/Gyr)^2 kpc^-1] at (R,z)
        .Vcirc(R,z=0.): circ. vel. [kpc/Gyr] at radius r=sqrt(R^2+z^2)
        .sigma(R,z=0.): vel. disp. [kpc/Gyr] at radius r=sqrt(R^2+z^2)

    HISTORY: Arthur Fangzhou Jiang (2018-03-23, UCSC)
             Arthur Fangzhou Jiang (2019-08-26, UCSC)