Integrated flux in [Emin, Emax] (eV) band.


        Plot meta-galactic background intensity at a single redshift.

        Parameters
        ----------
        z : int, float
            Redshift of interest


        Add rest-frame photon energies on top of plot, assumed to be in
        wavelength units on the bottom x-axis.

        Parameters
        ----------
        ax : matplotlib.axes.AxesSubplot instance


        Find trajectories that are flat. They are probably walkers stuck
        in some "no man's land" region of parameter space. Poor guys.

        Returns
        -------
        Lists of walker ID numbers. First, the good walkers, then the bad, as
        well as the mask itself.


        Draw a rectangle on supplied matplotlib.axes.Axes instance, return
        information about those models.


        Return revised ("sliced") dataset given set of criteria.

        Parameters
        ----------
        constraints : list, tuple
            A rectangle (or line segment) bounding the region of interest.
            For 2-D plane, supply (left, right, bottom, top), and then to
            `pars` supply list of datasets defining the plane. For 1-D, just
            supply (min, max).
        pars:
            Dictionary of constraints to use to calculate likelihood.
            Each entry should be a two-element list, with the first
            element being the redshift at which to apply the constraint,
            and second, a function for the posterior PDF for that quantity.s

        Examples
        --------

        Returns
        -------
        Object to be used to initialize a new ModelSet instance.


Create a new ModelSet out of the elements unique to current ModelSet.


Create a new ModelSet out of the elements unique to input sets.


        Convert a bounding polygon to a new ModelSet instance.

        Parameters
        ----------
        parameters : list
            List of parameters names / blob names defining the (x, y) plane
            of the input polygon.
        polygon : shapely.geometry.Polygon instance
            Yep.

        Returns
        -------
        New instance of THIS VERY CLASS.


        Return a new ModelSet instance containing only models that lie
        within (or outside, if union==False) intersection of two polygons.


Plot trajectories of `N` walkers for multiple parameters at once.


        Plot 1-D trajectories of N walkers (i.e., vs. step number).

        Parameters
        ----------
        parameter : str
            Name of parameter to show results for.
        walkers : str
            Which walkers to grab? By default, select `N` random walkers,
            but can also grab `N` first or `N` last walkers.


        Plot samples as points in 2-d plane.

        Parameters
        ----------
        pars : list
            2-element list of parameter names.
        ivar : float, list
            Independent variable(s) to be used for non-scalar blobs.
        z : str, float
            Redshift at which to plot x vs. y, if applicable.
        c : str
            Field for (optional) color axis.

        Returns
        -------
        matplotlib.axes._subplots.AxesSubplot instance.


        Basically a scatterplot but instead of plotting individual points,
        we draw lines bounding the locations of all those points.

        Parameters
        ----------
        pars : list, tuple
            List of parameters that defines 2-D plane.
        boundary_type : str
            Options: 'convex' or 'concave' or 'envelope'
        alpha : float
            Only used if boundary_type == 'concave'. Making alpha smaller
            makes the contouring more crude, but also less noisy as a result.


Take `N` models from each 2-D bin in space `pars`.


        Extract data for subsequent analysis.

        This means a few things:
         (1) Go retrieve data from native format without having to worry about
          all the indexing yourself.
         (2) [optionally] take the logarithm.
         (3) [optionally] apply multiplicative factors.
         (4) Create a mask that excludes all nans / infs.

        Parameters
        ----------
        pars : list
            List of quantities to return. These can be parameters or the names
            of meta-data blobs.
        ivars : list
            List of independent variables at which to compute values of pars.
        take_log single bool or list of bools determining whether data should
                 be presented after its log is taken
        un_log single bool or list of bools determining whether data should be
               presented after its log is untaken (i.e. it is exponentiated)
        multiplier list of numbers to multiply the parameters by before they
                   are presented
        remove_nas bool determining whether rows with nan's or inf's should be
                   removed or not. This must be set to True when the user
                   is using numpy newer than version 1.9.x if the user wants
                   to histogram the data because numpy gave up support for
                   masked arrays in histograms.

        Returns
        -------
        Tuple with two entries:
         (i) Dictionary containing 1-D arrays of samples for each quantity.
         (ii) Dictionary telling us which of the datasets are actually the
          log10 values of the associated parameters.


Create a vector of bins to be used when plotting PDFs.


        Figure out input values for x and y parameters for each panel.

        Returns
        -------
        Dictionary, elements sorted by


Make everything lists.


        Compute posterior PDF for supplied parameters.

        If len(pars) == 2, plot 2-D posterior PDFs. If len(pars) == 1, plot
        1-D marginalized PDF.

        Parameters
        ----------
        pars : str, list
            Name of parameter or list of parameters to analyze.
        ivar : float
            Redshift, if any element of pars is a "blob" quantity.
        plot : bool
            Plot PDF?
        like : float, list
            If plot == False, return the nu-sigma error-bar.
            If color_by_like == True, list of confidence contours to plot.
        color_by_like : bool
            If True, color points based on what confidence contour they lie
            within.
        multiplier : list
            Two-element list of multiplicative factors to apply to elements of
            pars.
        take_log : list
            Two-element list saying whether to histogram the base-10 log of
            each parameter or not.
        skip : int
            Number of steps at beginning of chain to exclude. This is a nice
            way of doing a burn-in after the fact.
        skim : int
            Only take every skim'th step from the chain.
        excluded : bool
            If True, and fill == True, fill the area *beyond* the given contour with
            cross-hatching, rather than the area interior to it.

        Returns
        -------
        Either a matplotlib.Axes.axis object or a nu-sigma error-bar,
        depending on whether we're doing a 2-D posterior PDF (former) or
        1-D marginalized posterior PDF (latter).


        Draw contours that are NOT associated with confidence levels.

        ..note:: To draw many contours in same plane, just call this
            function repeatedly.

        Should use pl.contour if we're plotting on a regular grid, i.e.,
        the parameter space of a 2-D model grid with the color axis
        some derived quantity.

        Parameters
        ----------
        pars : list
            List of parameters defining the plane on which to draw contours.
        c : str
            Name of parameter or blob that we're to draw contours of.
        levels : list
            [Optional] list of levels for


        Show contour plot in 2-D plane, and add colored points for third axis.

        Parameters
        ----------
        x : str
            Fields for the x-axis.
        y : str
            Fields for the y-axis.
        c : str
            Name of parameter to represent with colored points.
        z : int, float, str
            Redshift (if investigating blobs)
        Nscat : int
            Number of samples plot.

        Returns
        -------
        Three objects: the main Axis instance, the scatter plot instance,
        and the colorbar object.


Stolen from micro21cm...


Prepare datasets to make a contour plot.


        Return a set of model parameters close to those requested.

        Do this by searching the posterior distribution for nearby points,
        potentially within some tolerance of the value requested and/or within
        the bulk of the distribution, quantified by `limit_to`.


        Reconstructed evolution in whatever the independent variable is.

        Parameters
        ----------
        name : str
            Name of quantity you're interested in.
        ivar : list, np.ndarray
            List of values (or nested list) of independent variables. If
            blob is 2-D, only need to provide the independent variable for
            one of the dimensions, e.g.,

                # If LF data, plot LF at z=3.8
                ivar = [3.8, None]

            or

                # If LF data, plot z evolution of phi(MUV=-20)
                ivar = [None, -20]

        ivars : np.ndarray
            If this is a derived blob, supply ivars by hand. Need to write
            automated way of figuring this out.

        percentile : bool, float
            If not False, should be the confidence interval to plot, e.g, 0.68.
        use_best : bool
            If True, will plot the maximum likelihood reconstructed
            function. Otherwise, will use `percentile` and plot shaded region.
        samples : int, str
            If 'all', will plot all realizations individually. If an integer,
            will plot only the last `samples` realizations.


        Compute covariance matrix for input parameters.

        Parameters
        ----------
        pars : list
            List of parameter names to include in covariance estimate.

        Returns
        -------
        Returns vector of mean, and the covariance matrix itself.


        Return dictionaries of parameters corresponding to elements of the
        chain. Really just a convenience thing -- converting 1-D arrays
        (i.e, links of the chain) into dictionaries -- so that the parameters
        can be passed into ares.simulations objects.

        .. note :: Masked chain elements are excluded.

        N : int
            Maximum number of models to return, starting from beginning of
            chain. If None, return all available.
        include_bkw : bool
            Include base_kwargs? If so, then each element within the returned
            list can be supplied to an ares.simulations instance and recreate
            that model exactly.
        loc : int
            If supplied, only the dictionary of parameters associated with
            link `loc` in the chain will be returned.
        update_kwargs : dict
            New kwargs that you want added to each set of parameters. Will
            override pre-existing keys.

        Returns
        -------
        List of dictionaries. Maximum length: `N`.


Plot correlation matrix.


        Return parameter values at maximum likelihood point.

        Parameters
        ----------
        method : str
            median or mode


        Generate a new blob from parameters only, i.e., we need to re-run
        some ARES calculation, which is wrapped by `func`.

        No restart option yet. Should add that.


        Derive new blob from pre-existing ones.

        Parameters
        ----------
        Either supply the first two arguments:
        func : function!
            A function of two variables: ``data`` (a dictionary containing the
            data) and ``ivars``, which contain the independent variables for
            each field in ``data``.
        fields : list, tuple
            List of quantities required by ``func``.

        OR the second two:

        expr : str
            For example, 'x - y'
        varmap : dict
            Relates variables in `expr` to blobs. For example,

            varmap = {'x': 'nu_D', 'y': 'nu_C'}

        The remaining parameters are:

        save : bool
            Save to disk? If not, just returns array.
        name : str
            If save==True, this is a name for this new blob that we can use
            to call it up later.
        clobber : bool
            If file with same ``name`` exists, overwrite it?


        Determine how close all models in ModelSet are to parameter set
        in kwargs.


Just a wrapper around `save' routine.


        Extract data from chain or blobs and output to separate file(s).

        This can be a convenient way to re-package data, for instance
        consolidating data outputs from lots of processors into a single file,
        or simply reducing the size of a file for easy transport when we
        don't need absolutely everything.

        Parameters
        ----------
        pars : str, list, tuple
            Name of parameter (or list of parameters) or blob(s) to extract.
        ivar : int, float, str, list, tuple
            [optional] independent variables, if None will extract all.
        fmt : str
            Options: 'hdf5' or 'pkl'
        path : str
            By default, will save files to CWD. Can modify this if you'd like.
        include_chain : bool
            By default, include the chain, which in the case of a ModelGrid,
            is just the axes of the grid.
        restructure_grid : bool
            Not implemented yet, but would be nice to restructure model grid
            data into an ordered mesh to be nice.


        Stolen from here:

        http://blog.thehumangeo.com/2014/05/12/drawing-boundaries-in-python/

        Thanks, stranger!

        Compute the alpha shape (concave hull) of a set
        of points.
        @param points: Iterable container of points.
        @param alpha: alpha value to influence the
            gooeyness of the border. Smaller numbers
            don't fall inward as much as larger numbers.
            Too large, and you lose everything!


            Add a line between the i-th and j-th points,
            if not in the list already


Wrapper around `Plot21cmGlobalSignal` for backward compatibility.


        Plot differential brightness temperature vs. redshift (nicely).

        Parameters
        ----------
        ax : matplotlib.axes.AxesSubplot instance
            Axis on which to plot signal.
        fig : int
            Figure number.
        freq_ax : bool
            Add top axis denoting corresponding (observed) 21-cm frequency?
        time_ax : bool
            Add top axis denoting corresponding time since Big Bang?
        z_ax : bool
            Add top axis denoting corresponding redshift? Only applicable
            if xaxis='nu' (see below).
        scatter : bool
            Plot signal as scatter-plot?
        mask : int
            If scatter==True, this defines the sampling "rate" of the data,
            i.e., only every mask'th element is included in the plot.
        xaxis : str
            Determines whether x-axis is redshift or frequency.
            Options: 'z' or 'nu'

        Returns
        -------
        matplotlib.axes.AxesSubplot instance.


        Wrapper around `Plot21cmGlobalSignalDerivative` for backward
        compatibility.


        Plot signal and its first derivative (nicely).

        Parameters
        ----------

        Returns
        -------


Return slope of signal in mK / MHz at input frequency (MHz).


        Return a measurement of the width of the absorption or emission signal.

        Parameters
        ----------
        max_fraction : float
            At what fraction of the peak should we evaluate the width?
        peak_relative: bool
            If True, compute the width on the left (L) and right (R) side of
            the peak separately, and return R - L. If Not, the return value is
            the full width of the peak evaluated at max_fraction * its max.
        to_freq: bool
            If True, return value is in MHz. If False, it is a differential
            redshift element.
        absorption : bool
            If True, assume absorption signal, otherwise, use emission signal.

        .. note :: With default parameters, this function returns the
            full-width at half-maximum (FWHM) of the absorption signal.


        Compute emergent spectrum at time t (Myr) and given cell in grid. By
        default, cell=-1, i.e., compute the spectrum that emerges from the grid.
        If norm=True, do not apply geometrical dilution.

        Returns
        -------
        E, Fin, Fout


        Classical analytic solution for expansion of an HII region in an
        isothermal medium.  Given the time in seconds, will return the I-front
        radius in centimeters.

        Future: sol = 1 will be the better "analytic" solution.


        Find the position of the ionization front.

        Parameters
        ----------
        t : int, float
            Time in code units.
        species : str
            For example, h_1, he_1, he_2.


        Find the position of the I-front at all times, and compute value of
        analytic solution.


Compute analytic and numerical I-front radii vs. time and plot.


        Plot radial profile of given field.

        Parameters
        ----------
        field : str
            Field you'd like to plot a radial profile of, e.g., `h_1`.
        t : int, float, list
            Time(s) at which to plot radial profile.


        Plot ionization rate.

        Parameters
        ----------
        total_only : bool
            If True, will only plot total ionization rate. If False, will
            separate out into photo-ionization, secondary ionization,
            and collisional ionization.


        Plot heating rate as a function of radius.

        Parameters
        ----------
        t : int, float
            Time (code units) at which to plot heating rate.
        plot_cooling : bool
            Plot total cooling rate vs. radius as well?


        Break radiation field into chunks we know how to deal with.

        For example, HI, HeI, and HeII sawtooth modulation.

        Returns
        -------
        List of band segments that will be handled by the generator.


        Create energy and redshift arrays.

        Parameters
        ----------
        pop : int
            Population ID number.
        bands : list
            Each element of this list is a (Emin, Emax) pair defining
            a band in which the RTE is solved.

        Returns
        -------
        Tuple of redshifts and energies for this particular population.

        References
        ----------
        Haardt, F. & Madau, P. 1996, ApJ, 461, 20


        Tabulate the optical depth.

        The results of this function depend on a few global parameters.

        If tau_approx is True, then the optical depth will be assumed to be
        zero for all redshifts and energies.

        If tau_approx == 'neutral', then the optical depth will be computed
        assuming a neutral medium for all times (including HeI).

        If tau_approx is a function, it is assumed to describe the ionized
        hydrogen fraction as a function of redshift.

        If tau_approx is 'post_EoR', we assume the only species left that
        isn't fully ionized is helium, with 100% of helium having been
        ionized once. That is, xHI = xHeI = 0, xHeII = 1.

        Parameters
        ----------
        z : np.ndarray
            Array of redshifts.
        energies : np.ndarray
            Array of rest-frame photon energies.

        Returns
        -------
        A 2-D array of optical depths, of shape (len(z), len(E)).


        Create generators for each population.

        Returns
        -------
        Nothing. Sets attribute `generators`.


Initialize attributes pertaining to numerical integration.


        Compute ionization and heating rate coefficients.

        Returns
        -------
        Dictionary containing ionization and heating rate coefficients.


i, j, k = source, species, band.


        Compute flux at observed redshift z and energy E (eV).

        Parameters
        ----------
        z : float
            observer redshift
        E : float
            observed photon energy (eV)

        ===============
        relevant kwargs
        ===============
        tau : func, e.g. tau = lambda E, z1, z2: 0.0 # const. tau
            If supplied, represents the optical depth between redshifts z1
            and z2 as a function of observed energy E.
        xavg : func, array
            Average ionized fraction. Can be function of redshift, or array
            of values
        zxavg : array
            If xavg is an array, this is the array of corresponding redshifts.
        zf : float
            Upper limit of redshift integration (i.e. exclude emission from
            sources at z' > zf).

        Returns
        -------
        Flux in units of erg s**-1 cm**-2 Hz**-1 sr**-1


        Compute background flux at Lyman-alpha resonance.

        ..note:: Optionally includes products of Ly-n cascades if approx_lwb=0.

        Parameters
        ----------
        z : int, float
            Redshift of interest
        fluxes : np.ndarray
            Fluxes grouped by LW band at a single redshift.

        Returns
        -------
        Lyman alpha flux at given redshift.


        Tabulate emissivity over photon energy and redshift.

        For a scalable emissivity, the tabulation is done for the emissivity
        in the (EminNorm, EmaxNorm) band because conversion to other bands
        can simply be applied after-the-fact. However, if the emissivity is
        NOT scalable, then it is tabulated separately in the (10.2, 13.6),
        (13.6, 24.6), and X-ray band.

        Parameters
        ----------
        z : np.ndarray
            Array of redshifts
        E : np.ndarray
            Array of photon energies [eV]
        pop : object
            Better be some kind of Galaxy population object.

        Returns
        -------
        A 2-D array, first axis corresponding to redshift, second axis for
        photon energy.

        Units of emissivity are: erg / s / Hz / cMpc


        Generic flux generator.

        Parameters
        ----------
        energies : np.ndarray
            1-D array of photon energies
        redshifts : np.ndarray
            1-D array of redshifts
        ehat : np.ndarray
            2-D array of tabulate emissivities (divided by H(z)).
        tau : np.ndarray
            2-D array of optical depths, or reference to an array that will
            be modified with time.
        flux0 : np.ndarray
            1-D array of initial flux values.


Create generators for the flux between all Lyman-n bands.


        Evolve some radiation background in time.

        Parameters
        ----------
        popid : str
            Create flux generator for a single population.

        Returns
        -------
        Generator for the flux, each in units of s**-1 cm**-2 Hz**-1 sr**-1.
        Each step returns the current redshift, and the flux as a function of
        energy at the current redshift.


        For internal use only.

        A storage container for fluxes to be passed from one generator to the
        next, to create continuity between sub-bands.


Compute rate coefficients for ionization / heating.


        Compute column densities cumulatively and on a cell-by-cell basis.

        Parameters
        ----------
        data : dict
            Dataset for a single RaySegment snapshot.


        Solver for finite speed-of-light radiation field

        PhotonPackage guide:
            pack = [EmissionTime, EmissionTimeInterval, ncolHI, ncolHeI, ncolHeII, Energy]


        Compute the optical depth between two redshifts.

        If no keyword arguments are supplied, assumes the IGM is neutral.

        Parameters
        ----------
        z1 : float
            observer redshift
        z2 : float
            emission redshift
        E : float
            observed photon energy (eV)

        Notes
        -----
        If keyword argument 'xavg' is supplied, it must be a function of
        redshift.

        Returns
        -------
        Optical depth between z1 and z2 at observed energy E.


        Compute optical depth as a function of (redshift, photon energy).

        Parameters
        ----------
        xavg : function
            Mean ionized fraction as a function of redshift.

        Notes
        -----
        Assumes logarithmic grid in variable x = 1 + z. Corresponding
        grid in photon energy determined in _init_xrb.

        Returns
        -------
        Optical depth table.


        From parameter file, initialize grids in redshift and frequency.

        Parameters
        ----------
        Only depends on contents of self.pf.

        Notes
        -----
        If tau_Nz != None, will setup logarithmic grid in new parameter
        x = 1 + z. Then, given that R = x_{j+1} / x_j = const. for j < J, we can
        create a logarithmic photon frequency / energy grid. This technique
        is outlined in Haardt & Madau (1996) Appendix C.

        References
        ----------
        Haardt, F. & Madau, P. 1996, ApJ, 461, 20


Read optical depth table.


Return name of table based on its properties.


Find an optical depth table.


        Look for optical depth tables. Supply corrected energy and redshift
        arrays if there is a mistmatch between those generated from information
        in the parameter file and those found in the optical depth table.

        .. note:: This will only be called from UniformBackground, and on
            populations which are using the generator framework.

        Parameters
        ----------
        popid : int
            ID # for population of interest.
        zpf : np.ndarray
            What the redshifts should be according to the parameter file.
        Epf : np.ndarray
            What the energies should be according to the parameter file.

        Returns
        -------
        Energies and redshifts, potentially revised from Epf and zpf.


        Determine dimensions of optical depth table.

        Unfortunately, this is a bit redundant with the procedure in
        self._init_xrb, but that's the way it goes.


        Write optical depth table to disk.

        Parameters
        ----------
        fn : str
            Full filename (including suffix). Will override prefix and suffix
            parameters.


        Evolve all cells by dt.

        Parameters
        ----------
        data : dictionary
            Dictionary containing elements for each field in the grid.
            Each element is itself a 1-D array of values.
        t : float
            Current time.
        dt : float
            Current time-step.


        Convert kwargs dictionary to list.

        Entries correspond to cells, a dictionary of values for each.


        Return non-negative mean correction <Auv> averaged over Luv assuming a
        normally distributed Auv


Return observed  magnitude.


Get the measured UV continuum slope from Bouwens+2014 (Table 3).


Get the measured slope of the UV continuum slope from Bouwens+2014.


An linear + exponential fit to Bouwens+14 data adopted from Mason+2015.


        Convert AB magnitude [ABSOLUTE] to rest-frame luminosity.

        Parameters
        ----------
        mag : int, float
            Absolute magnitude in AB system.
        z : int, float
            Redshift of object
        dL : int, float
            Luminosity distance of object [cm]

        Currently this is dumb: doesn't need to depend on luminosity.

        Returns
        -------
        Luminosity in erg / s / Hz.


Plot transmission curves for filters.


        Assembles a dictionary of throughput curves.

        Each element of the dictionary is a tuple containing:
            (wavelength, throughput, midpoint of filter,
                width of filter (FWHM), transmission averaged over filter)

        Example
        -------

        >>> wave, T, mid, wid, Tavg = self.read_throughputs()


        Return the fraction of secondary electron energy deposited as heat, or
        further ionizations.

        The parameter 'channel' determines which we want, and could be:

            channel = (heat, h_1, he_1, he_2, lya)

        also,

            Method = 0: OFF - all secondary electron energy goes to heat.
            Method = 1: Empirical fits of Shull & vanSteenberg 1985.
            Method = 2: Empirical Fits of Ricotti et al. 2002.
            Method = 3: Lookup tables of Furlanetto & Stoever 2010.

        xHII is preferably an array of values (corresponding to grid elements).


        Run CosmoRec. Assumes we've got an executable waiting for us in
        directory supplied via ``cosmorec_path`` parameter in ARES.

        Will save to $ARES/input/inits. Can check in $ARES/input/inits/outputs
        for CosmoRec parameter files should any debugging be necessary. They
        will have the same naming convention, just different filename prefix
        ("cosmorec" instead of "inits").


        The continuum emission coefficient, over (ne * np * gamma_c).

        .. note :: This is Eq. 6.22 in Dopita & Sutherland (2003).
        .. note :: Pretty sure their F_k in that equation should be f_k.
        .. note :: We don't need the ne * np bit thanks to our assumption
            of photo-ionization equilibrium.


        Fraction of photons reprocessed into different channels.

            .. note :: This carries units of Hz^{-1}.


        Add together nebular continuum contributions, i.e., free-free,
        free-bound, and two-photon.

        Parameters
        ----------
        Return L_\nu in [erg/s/Hz]


        Add as many nebular lines as we have models for.

        Parameters
        ----------
        Return L_\nu in [erg/s/Hz]


Follow Inoue (2011) with coefficients from Osterbrock & Ferland (2006).


Return spectrum containing only H lines from transitions into `ninto`.


Extrapolate kappa outside tabulated range.


        Return energy of photon transitioning from nu to nl in eV.
        Defaults to Lyman-series.


        Flux of photons = 1 photon per hydrogen atom assuming Lyman alpha
        frequency.


From Pritchard & Furlanetto 2006.


Must be a function of redshift.


        Parameters
        ----------
        z : float
            Redshift
        Tk : float
            Kinetic temperature of the gas [K]
        xHII : float
            Hydrogen ionized fraction
        ne : float
            Proper electron density [cm**-3]

        References
        ----------
        Zygelman, B. 2005, ApJ, 622, 1356


        Return radiative coupling coefficient (i.e., Wouthuysen-Field effect).

        .. note :: If approx_Sa > 3, will return x_a, S_a, and T_S, which are
            determined iteratively.


Account for line profile effects.


Return energy of photon in eV using Bohr atom.


Short-hand for calling `SpinTemperature`.


Collisional ionization rate which we denote elsewhere as Beta.


        Coefficient for radiative recombination.  Here, species = 0, 1, 2
        refers to HII, HeII, and HeIII.


Dielectric recombination coefficient for helium.


        Returns coefficient for cooling by collisional ionization.  These are equations B4.1a, b, and d respectively
        from FK96.

            units: erg cm^3 / s


        Returns coefficient for cooling by collisional excitation.  These are equations B4.3a, b, and c respectively
        from FK96.

            units: erg cm^3 / s


        Returns coefficient for cooling by recombination.  These are equations B4.2a, b, and d respectively
        from FK96.

            units: erg cm^3 / s


        Returns coefficient for cooling by dielectric recombination.  This is equation B4.2c from FK96.

            units: erg cm^3 / s


        (void) -> 3darray

        Calculates and / or returns the specific luminosity L_nu in
        ergs / s / Hz for each galaxy at all frequencies and redshifts
        provided.

        Note: This is a very expensive calculation! Make sure you really need
        to see all those redshifts. Lower redshifts tend to take longer to
        calculate.

        first axis: galaxy index
        second axis: data at given frequency index (ergs / s / Hz)
        third axis: data at given redshift index


        (void) -> 2darray

        Calculates and / or returns the dust radius for each galaxy at each redshift
        in kpc.

        first axis: galaxy index
        second axis: redshift index


        (void) -> 2darray

        Calculates and / or returns the dust mass in each galaxy at each redshift in solar masses.

        first axis: galaxy index
        second axis: redshift index


        (void) -> 2darray

        Calculates and / or returns the metallicity calculated from the Imara et al. (2018) paper.
        The convention is Z = 12 + log(O/H). This is only used in experimental mode
        and is NOT self-consistent.

        first axis: galaxy index
        second axis: redshift index


        (void) -> 2darray

        Calculates and / or returns the Dust-to-Gas Ratio (DGR) for all galaxies at all redshifts.
        For now, this is only used in experimental mode and is NOT self-consistent. Based on
        Imara et al. (2018).

        first axis: galaxy index
        second axis: redshift index


        (void) -> 2darray

        Calculates and / or returns the gas mass based on Imara et al. This is only used in
        experimental mode, and is NOT self-consistent. Based on Imara et al. (2018)

        first axis: galaxy index
        second axis: redshift index


        (void) -> 3darray

        Returns and / or calculates the dust opacity given the frequencies. The data
        returned is in cm^2 / g.

        first axis: galaxy index
        second axis: frequency index
        third axis: redshift index


        (void) -> 3darray

        Returns and / or calculates the optical depth of the dust. This
        quantity is dimensionless.

        first axis: galaxy index
        second axis: frequency index
        third axis: redshift index


        (void) -> 2darray

        Returns and / or calculates the Cosmic Microwave Background temperature
        for each galaxy at each redshift.

        first axis: galaxy index
        second axis: redshift index


        (1darray, 3darray, 3darray, 2darray, 2darray) -> 2darray

        Calculates and returns the dust temperature for each galaxy at each redshift.
        If 'pop_dust_experimental' is False, this is based on Imara et al (2018).
        If 'pop_dust_experimental' is True, this is a log-linear parametrization.

        first axis: galaxy index
        second axis: redshift index


        (void) -> 2darray

        Calculates and / or returns the dust temperature for each galaxy at
        each redshift.

        first axis: galaxy index
        second axis: redshift index

        If the temperature returns nan, then this means that there was no dust
        in the galaxy in the first place (maybe galaxy was not born yet, or the halo
        has no galaxy at all)


        (num, num, int) -> 1darray, 3darray

        Returns and / or calculates the dust SED in ergs / s / Hz for each galaxy
        at each redshift.

        RETURNS

        frequencies, SED: 1darray, 3darray

        first axis: galaxy index
        second axis: frequency index
        third axis: redshift index

        PARAMETERS

        fmin: number
            minimum frequency of the band

        fmax: number
            maximum frequency of the band

        Nfreqs: integer
            number of frequencies between fmin and fmax to be calculated


        (num, num) -> 1darray

        Calculates the luminosity function for dust emissions in galaxies.
        The results are returned in [ergs / s / Hz]. Returns nu * L_nu

        PARAMETERS

        z: number
            redshift where the luminosity function will be calculated

        wave: number
            wavelength (in Angstroms) where the luminosity will be
            calculated

        band: tuple
            tuple of wavelengths (in Angstroms) where the luminosity
            will be calculated and then averaged over the band
            !! NOT IMPLEMENTED YET !!

        total_IR: boolean
            if False: returns the luminosity at the given wavelength in [ergs / s / Hz]
            if True: ignore wave, and returns the total luminosity in [ergs / s]
            integrated between 8 and 1000 microns

        RETURNS

        luminosities: 1darray
            luminosity in [ergs / s / Hz] of each galaxy for the given redshift and wavelength
            OR
            total luminosity in [ergs / s] integrated between 8 and 1000 microns


Load table from HDF5 or binary.


        Build a lookup table for the halo mass function / collapsed fraction.

        Can be run in parallel.


        Construct splines for fcoll and its derivatives given a (fixed)
        minimum virial temperature.


        Return fraction of mass in halos more massive than 10**logMmin.
        Interpolation in 2D, x = redshift = z, y = logMass.


Return derivative of fcoll(z).


"Evolve" a halo through time (assuming fixed number density).


Mean density in g / cm^3.


        What should we name this table?

        Convention:
        hmf_FIT_logM_nM_logMmin_logMmax_z_nz_

        Read:
        halo mass function using FIT form of the mass function
        using nM mass points between logMmin and logMmax
        using nz redshift points between zmin and zmax


        Save mass function table to HDF5 or binary (via pickle).

        Parameters
        ----------
        fn : str (optional)
            Name of file to save results to. If None, will use
            self.tab_prefix_hmf and value of format parameter to make one up.
        clobber : bool
            Overwrite pre-existing files of the same name?
        destination : str
            Path to directory (other than CWD) to save table.
        format : str
            Format of output. Can be 'hdf5' or 'pkl'


Return real-space window function.


Compute the variance in the field on some scale `R`.


        Compute the size distribution of objects.

        Parameters
        ----------
        z: int, float
            Redshift of interest.

        Returns
        -------
        Tuple containing (in order) the radii, masses, and the
        differential size distribution. Each is an array of length
        self.tab_M, i.e., with elements corresponding to the masses
        used to compute the variance of the density field.


        First-crossing distribution function.

        i.e., dF/dS where S=sigma^2.


The concentration-mass relation


        Normalized Fourier Transform of an NFW profile.

        ..note:: This is Equation 81 from Cooray & Sheth (2002).

        Parameters
        ----------
        k : int, float
            Wavenumber
        m :


        Normalized Fourier transform of an r^-2 profile.

        rmax : int, float
            Effective horizon. Distance a photon can travel between
            Ly-beta and Ly-alpha.


        Return the modulation factor as a function of redshift or comoving distance
        - Reference: Ahn et al. 2009
        :param z0: source redshift
        :param z: the redshift (whose LW intensity is) of interest
        :param r: the distance from the source in cMpc
        :lc: True or False, including the light cone effect
        :return:


        Compute integrals over profile, weighted by bias, dndm, etc.,
        needed for halo model.

        .. note :: This is really just a wrapper around _integrate_over_prof,
            that handles the fact that `k` can be a number or an array.


        Compute integrals over profile, weighted by bias, dndm, etc.,
        needed for halo model.


        Basic prep: fill prof1=None or prof2=None with defaults, determine
        the index of the requested redshift in our lookup tables.


        Return linear matter power spectrum for requested wavenumber `k`.

        .. note :: Assumes we already know the index of the redshift of interest
            in our lookup tables, `iz`.


        Compute the correlation function of the matter power spectrum.

        Parameters
        ----------
        z : int, float
            Redshift of interest.
        R : int, float, np.ndarray
            Scale(s) of interest


        Take a power spectrum and perform the inverse (3-D) FT to recover
        a correlation function.


        This is nearly identical to the inverse transform function above,
        I just got tired of having to remember to swap meanings of the
        k and R variables. Sometimes clarity is better than minimizing
        redundancy.


k-vector constructed from mps parameters.


R-vector constructed from mps parameters.


Redshift array -- different than HMF redshifts!


        What should we name this table?

        Convention:
        ps_FIT_logM_nM_logMmin_logMmax_z_nz_

        Read:
        halo mass function using FIT form of the mass function
        using nM mass points between logMmin and logMmax
        using nz redshift points between zmin and zmax


        A version of the prefix to be used only for checkpointing.

        This just means take the full prefix and hack out the bit with the
        redshift interval.


Tabulate the matter power spectrum as a function of redshift and k.


        Save matter power spectrum table to HDF5 or binary (via pickle).

        Parameters
        ----------
        fn : str (optional)
            Name of file to save results to. If None, will use
            self.tab_prefix_ps and value of format parameter to make one up.
        clobber : bool
            Overwrite pre-existing files of the same name?
        destination : str
            Path to directory (other than CWD) to save table.
        format : str
            Format of output. Can be 'hdf5' or 'pkl'


High redshift approximation under effect.


Returns lookback time from z_i to z_f in seconds, where z_i < z_f.


        Time-redshift relation for a matter + lambda Universe.

        References
        ----------
        Ryden, Equation 6.28

        Returns
        -------
        Time since Big Bang in seconds.


This is dTk/dz.


        Returns luminosity distance in cm.  Assumes we mean distance from
        us (z = 0).


        Given a redshift and a LOS distance, return the corresponding dz.

        Parameters
        ----------
        z0 : int, float
            Redshift.
        dl : int, float
            Distance in Mpc.


Return comoving distance between redshift z0 and z, z0 < z.


Comoving differential line element at redshift z.


Proper differential line element at redshift z (i.e. dl/dz).


        Generally denoted (in LaTeX format) \Delta_c, fit from
        Bryan & Norman (1998).


        Compute the co-moving volume of a spherical shell defined by `angle`
        and thickness `dz`.

        Parameters
        ----------
        z : int, float
            Redshift of shell center.
        area : int, float
            Angular scale in degrees.
        dz : int, float
            Shell thickness in differential redshift element.

        Returns
        -------
        Volume in comoving Mpc^3.


Convert a length scale (co-moving) to an observed angle [arcmin].


        Convert an angle to a co-moving length-scale at the observed redshift.

        Parameters
        ----------
        z : int, float
            Redshift of interest
        angle : int, float
            Angle in arcminutes.

        Returns
        -------
        Length scale in Mpc.


    Compute bound-free absorption cross section for hydrogen or helium.

    Parameters
    ----------
    E : float
        Photon energy (eV)
    species : int
        Species ID number. HI = 0 (default), HeI = 1, HeII = 2

    Returns
    -------
    Cross section in cm**2 using fits from Verner et al. (1996).

    References
    ----------
    Verner, D.A., Ferland, G.J., Korista, K.T., and Yaklovlev, D.G., ApJ, 465, 487


Units of erg / s / A / Msun


Construct list of RadiationSource class instances.


Return average photon energy in supplied band.


Return a normalized version of the spectrum at photon energy E / eV.


        Normalization constant that forces self.Spectrum to have unity
        integral in the (Emin, Emax) band.


UV luminosity per unit SFR.


        Specific emissivity at provided wavelength at `source_tsf`.

        .. note :: This is just taking self.L_per_sfr_of_t and interpolating
            to some time, source_tsf. This is generally used when assuming
            constant star formation -- in the UV, L_per_sfr_of_t will
            asymptote to a ~constant value after ~100s of Myr.

        Parameters
        ----------
        wave : int, float
            Wavelength at which to determine emissivity.
        avg : int
            Number of wavelength bins over which to average

        Units are
            erg / s / Hz / (Msun / yr)
        or
            erg / s / Hz / Msun


Compute the average energy per photon (in eV) in some band.


Must be in the internal units of erg / g.


        Return bolometric luminosity at time `t`.

        Assume 1 Msun / yr SFR.


        Compute photons emitted integrated in some band for all times.

        Returns
        -------
        Integrated flux between (Emin, Emax) for all times in units of
        photons / sec / (Msun [/ yr]), unless energy_units=True, in which
        case its erg instead of photons.


        Compute the number of photons emitted per unit stellar baryon.

        ..note:: This integrand over the provided band, and cumulatively over time.

        Parameters
        ----------
        Emin : int, float
            Minimum rest-frame photon energy to consider [eV].
        Emax : int, float
            Maximum rest-frame photon energy to consider [eV].

        Returns
        -------
        An array with the same dimensions as ``self.times``, representing the
        cumulative number of photons emitted per stellar baryon of star formation
        as a function of time.


        Units = erg / s / A / [depends]

        Where, if instantaneous burst, [depends] = 1e6 Msun
        and if continuous SF, [depends] = Msun / yr

        In SSP case, remove factor of 1e6 here so it propagates everywhere
        else.


        Inner radius of disk.  Unless SourceISCO > 0, will be set to the
        inner-most stable circular orbit for a BH of mass M.


Temperature (in Kelvin) at inner edge of the disk.


        A simple power law X-ray spectrum - this is proportional to the
        *energy* emitted at E, not the number of photons.


        Purpose:
        --------
        Convolve an input spectrum with a Comptonization kernel.

        Inputs:
        -------
        Gamma  - Power-law index, LE ~ E**(-Gamma)
        fsc    - Fraction of seed photons that get scattered
                 (assumes all input photons have same probability of being scattered
                 and that scattering is energy-independent)
        fref   - Of the photons that impact the disk after a scattering, this is the
                 fraction that reflect back off the disk to the observer instead of
                 being absorbed and thermalized (default 1)
        uponly - False: SIMPL-2, non-rel Comptonization, up- and down-scattering
                 True:  SIMPL-1, relativistic Comptoniztion, up-scattering only

        Outputs: (dictionary)
        --------
        LE - Absorbed power-law luminosity array [keV s^-1]
        E  - Energy array [keV]
        dE - Differential energy array [keV]

        References
        ----------
        Steiner et al. (2009). Thanks Greg Salvesen for the code!


Must perform integral transform to compute output photon distribution.


        Soft component of accretion disk spectra.

        References
        ----------
        Mitsuda et al. 1984, PASJ, 36, 741.


See if source is on. Provide t in code units.


        Return quantity *proportional* to fraction of bolometric luminosity
        emitted at photon energy E.  Normalization handled separately.


        Returns the bolometric luminosity of a source in units of erg/s.
        For accreting black holes, the bolometric luminosity will increase
        with time, hence the optional 't' and 'M' arguments.


        Compute black hole mass after t (seconds) have elapsed.  Relies on
        initial mass self.M, and (constant) radiaitive efficiency self.epsilon.


Compute age of black hole based on current time, current mass, and initial mass.


Print info like Nlw etc in various units!


Compute average recycling fraction (i.e., spectrum-weighted frec).


Take tables and create interpolation functions.


Compute bound-free absorption cross-section for all frequencies.


Returns number of photons emitted (s^-1) at all frequencies.


Average ionizing (per absorber) photon energy in eV.


Average ionizing photon luminosity (per absorber) in s^-1.


Frequency averaged cross section (single bandpass).


        Fraction of bolometric luminosity emitted above all ionization
        thresholds.


        Return ionization rate (as a function of radius) assuming optical
        depth to cells and of cells is small.


Return Qdot (photons / s) for this source at energy E.


r"""
        Return fraction of bolometric luminosity emitted at energy E.

        Elsewhere denoted as :math:`I_{\nu}`, normalized such that
        :math:`\int I_{\nu} d\nu = 1`

        Parameters
        ----------
        E: float
            Emission energy in eV
        t: float
            Time in seconds since source turned on.
        i: int
            Index of component to include. If None, includes contribution
            from all components.

        Returns
        -------
        Fraction of bolometric luminosity emitted at E in units of
        eV\ :sup:`-1`\.


        Bolometric luminosity / number of ionizing photons in spectrum in bandpass
        spanning interval (Emin, Emax). Returns mean photon energy and number of
        ionizing photons in band.


        Write SED out to file.

        Parameters
        ----------
        fn : str
            Filename, suffix determines type. If 'hdf5' or 'h5' will write
            to HDF5 file, otherwise, to ASCII.
        E : np.ndarray
            Array of photon energies at which to sample SED. Units = eV.


Return name of output file based on SED properties.


        Return quantity *proportional* to fraction of bolometric luminosity emitted
        at photon energy E.  Normalization handled separately.


Returns specific intensity of blackbody at temperature T [K].


        Return quantity *proportional* to fraction of bolometric luminosity.

        Parameters
        ----------
        E : int, float
            Photon energy of interest [eV]


        Specific emissivity at provided wavelength.

        .. note :: This is analogous to SynthesisModel.L_per_sfr, but since
            in this class we deal with single stars (so ill-defined SFR),
            we're doing some gymnastics here to get things in the right units.
            All that really matters is that we have something, that when
            multiplied by an SFR, will yield a halo's luminosity in
            erg/s/Hz/(Msun/yr).

        Parameters
        ----------
        wave : int, float
            Wavelength at which to determine luminosity [Angstroms]
        avg : int
            Number of wavelength bins over which to average


        Luminosity of stars as function of their mass and age.

        Parameters
        ----------
        M : int, float, np.ndarray
            Mass [Msun]
        t : int, float, np.ndarray
            Time [Myr]


        Tabulated spectra of stars.

        Units: erg/s/A


        This is where we'll put the population-averaged spectra, i.e.,
        L as a function of wavelength and time.

        Units: erg/s/Ang/Msun


Normalized such that Mtot = 10^6 Msun.


CDF for IMF. By number, not mass!


    Read output from starburst99.

    Parameters
    ----------
    fn : str
        Name of file within $ARES/input/starburst99 to open.
    skip : int
        Number of lines to skip at beginning of file. I don't think this should
        ever change.


    Only built for figures 1-12 right now.

    Parameters
    ----------
    imf : float
        2.35
        3.3
        30


Return wavelengths, fluxes, for given set of parameters (at all times).


Compute number density of quasars with luminosity L at redshift z.


Compute cutoff redshift for luminosity-dependent density evolution.


Pure density evolution model.


    Compute the 2-10 keV quasar luminosity function.

    Parameters
    ----------
    L : int, float, np.ndarray
        Luminosity of interest [erg / s]
    z : int, float
        Redshift of interest

    kwags['evolution'] : str
        "ple": Pure Luminosity Evolution (Eq. 11)
        "pde": Pure Density Evolution (Eq. 12)
        "ldde": Luminosity-Dependent Density Evolution (Eqs. 16-17)


    Broadband quasar template spectrum.

    References
    ----------
    Sazonov, S., Ostriker, J.P., & Sunyaev, R.A. 2004, MNRAS, 347, 144.


Determine filename of appropriate BPASS lookup table based on kwargs.


    Equation 9 from McBride et al. (2009).

    ..note:: This is the *median* MAH, not the mean.


    Compute the HMF from some kwargs. In this case, just truncate below
    some mass threshold and return modified HMF.

    In practice this will be a wrapper around some other function. We just
    need to rename parameters so ARES understands them, hence the
    `hmf_extra_par0` parameter below, which is serving as our mass cutoff.


Return line intensities relative to H-beta for given metallicity.


Returns wavelengths and


    Returns (frequencies, temperatures) for Fig. 1 or 2 data.

    ..note:: The contents of the `data` array are different for each file!


Flattened Gaussian model for the brightness temperature.


    Assumes you downloaded the raw EoS data into $ARES/input/eos, and that
    there are separate directories 'faint_galaxies', and 'bright_galaxies'
    containing all the ps_no_halos* files.


    .. note :: There's a typo in Eq. 5 of Y. Feng et al. (2016). They had
    a factor of (1 - alpha), it should be (1 + alpha).


Load file `fn` and assume mass grid `Marr`.


Returns a copy of the Periodogram object.

        This method uses the `copy.deepcopy` function to ensure that all
        objects stored within the Periodogram are copied.

        Returns
        -------
        pg_copy : Periodogram
            A new `Periodogram` object which is a copy of the original.


Returns a copy of this `cbvCorrector` object.

        This method uses Python's `copy.deepcopy` function to ensure that all
        objects stored within the cbvCorrector instance are fully copied.

        Returns
        -------
        cbvCorrector_copy : `cbvCorrector`
            A new object which is a copy of the original.


Wrapper for cubic spline interpolation, to work like np.interp()


 Port of Jam_IntTab - does a 5-point Newton-Cotes formula

    Arguments:
    f -- Array of x-pts to be integrated over
    h -- Array of y-values corresponding to x-pts

    Returns: Integral with respect to f


 Create array of dust grain sizes

    This is a direct port of jam_grainradii.pro
    Verified to work same as IDL version 8/18/20

    Keyword Arguments:
    numRad -- the number of output points (default 81)
    minRad -- minimum grain radius in micron (default 1e-3)
    maxRad -- max grain radius in micron (default 10.)

    Returns: Array of grain radii, log-spaced


 Compute dust grain cross sections

    Direct port of jam_graincrosssection. Note that the python interpolation algorithms
    return slightly different results for extrapolations than their IDL equivalents, which
    may lead to slightly different results in some cases. Doesn't appear to ever be more
    than about 2 percent.
    Verified 8/24/20

    Arguments:
    wave -- array of wavelengths over which to compute cross sections
    rad -- array of dust grain sizes to compute cross sections for
    scaleSIL -- Array to use in scaling silicate features between Draine/OHMc

    Keyword Arguments:
    tablePath -- directory for grain opacity tables

    Returns: tuple of dicts, first for absorption and second for extinction. Each
    dictionary contains grids of wavelength, grain size, and opacities for silicate,
    graphite neutral, and ionized species


    Compute equilibrium temperatures of grains in radiation field as function of size (T_eq)

    Port of jam_graineqtemp.pro. Differences from IDL version due to different inteprolation routines,
    should be ~2 percent or less, with edges being the worst
    Verified to match well enough 9/7/20

    Parameters
    ----------
    a -- array of grain sizes
    T_bb -- array of blackbody temperature of ambient radiation field
    cAbs -- absorption cross-sections for the grains (default None)
    sourceType -- object producing ambient radiation field (default None)
    TTable -- Array of temperatures to compute over (default None)
    scaleSIL -- Scaling between Draine and OHMc silicates (default None)

    Returns
    -------
        Dictionary of grain sizes, ambient radiation field temperatures,
    and equilibrium temperatures of silcate and carbonaceous grains.
    Also returns TTable, which is a holdover from IDL and possibly unnecessary (TTable deleted by TL 4/5)


 Calculate grain size distribution of graphitic and silicate dusts

    Port of jam_grainsizedf. Appears to match IDL functionality 8/26/20
    Note that testing has only been done for T_bb = 0, issues may crop
    up at different T_bb, espeically with grainEQTemp

    Arguments:
    rad -- array of grain radii in microns
    T_bb -- blackbody matching ambient radiation field
    sourceType -- Type of input SED source to be passed to grainEQT

    Keyword Arguments:
    model -- Which grain size distribution model to use (default 'WD01-RV31')
    dndaTab -- Table of grain size distribution parameters (default None0)
    cutoff -- Whether to truncate the grain size distribution. Options are
    'big', 'small', or None (default)

    Returns: Dict of grain sizes, blackbody temperatures, and size distributions
    for both silicate and carbonaceous grains


 Calculate grain opacities at different blackbody temperatures

    Port of JAM_GrainOpacity IDL routine. Tested to reproduce IDL outputs 9/6/20

    Arguments:
    wave -- array of wavelengths over which to calculate the opacity
    T_bb -- blackbody temperature of ambient radiation field
    scaleSIL -- ???

    Keyword Arguments:
    tablePath -- directory where grain opacities are stored
    cAbs_wR -- grain absorption cross sections in reduced wavelengths (wR) (default None)
    cExt_wR -- grain scattering cross section in reduced wavelengths (wR) (default None)
    dnda -- grain size table. (default None)
    gra -- whether to use graphitic grain absorption/extinction (default None)
    noPAH -- whether to include PAH contribution (default True)
    cutoff -- whether/which grain size cutoff to impose (defailt None)
    kExt -- Whether to calculate scattering, in addition to absorption (default True)
    fstTab -- Silicate feature mass-opacities table (default None)
    ensTab --  Silicate feature mass-opacities table (default None)

    Returns:
        Dictionary of wavelengths, blackbody temperature, and opacties by
        species (further divided into continuum/feature)


 Calculates grain emissivity at varying blackbody temperatures

    Port of jam_grainemissivity, verified to match IDL version 9/8/20, with some differences due to
    Python handling interpolation differently in the carbonaceous grains

    Arguments:
    wave -- array of wavelengths over which to calculate the opacity
    T_bb -- blackbody temperature of ambient radiation field
    sourceType -- source of the ambient radiation field (default None)
    scaleSIL -- array of scaling factors between different silicate features (default None)

    Keyword Arguments:
    fstTab -- silicate feature mass-opacities table (default None)
    ensTab --  silicate feature mass-opacities table (default None)
    T_EQ -- array of grain equilibrium temperatures (default None)
    tablePath -- directory for emissivity tables (defaule 'tables/')

    Returns: Dictionary of wavelengths, blackbody temperature, and emissivities by
    species (further divided into continuum/feature)


 Calculates the total grain emissivity from all species

    Replacing jam_graintotemissivity, mostly verified as of 9/26/20, dropped features for jSilDo,
    jCryDo, jAmoDo since I don't think they're being used

    Arguments:
    wave -- array of wavelengths over which to calculate the opacity
    T_bb -- blackbody temperature of ambient radiation field

    Keyword Arguments:
    fCarb -- scaling factor for carbonaceous grains (default 1)
    fSil -- scaling factor for silicate grains (default 1)
    fCry -- scaling factor for crystaline opacities (default 1)
    fEns -- scaling factor for something opacity. (default 0.5)
    E_T -- emissivity dictionary (default 0)
    FASTTEMP -- replaces interpolation over temperature with nearest-
    neighbor. Significantly speed improvement, some loss in accuracy
    in dust-dominated portions of the spectrum

    Returns: Total grain emission at the specified wavelength points


 Compute PAH cross sections

    Direct port of IDL jam_pahcrosssection routine.
    Appears to correspond to IDL version verified 8/24/20

    Arguments:
    wave -- array of wavelengths to compute cross sections
    a -- array of grain sizes to compute cross sections
    cGra -- graphite abuncances, read from a grain size table previously

    Keyword Arguments:
    feat -- whether to include narrow (feature) PAHs as well as broad (default False)

    Returns: Continuum and feature absorption cross sections, each of which is further
    separated into neutral and ionized species


This function masks extreme outliers in the data


 Calculates array of weights to use in continuum fitting

    Ports the functionality of CAFE_WEIGHTS. However, this version explicitly
    treats spec and phot separately, which the IDL version also does in a way
    that's much harder to follow
    Outputs verified to match IDL version 08/16/20

    Arguments:
    wave -- array of rest-frame spectrum wavelengths, in um
    pwave -- wavelengths of broad-band photometric data points, in um
    nBins -- number of log-spaced bins to divide spectrum into

    Returns: array of weights for each spectral and photometric wavelength point


 Integrate flux over the specified filters

    Integrate the spectrum over the transmission curve for the specific filter, in
    order to accurately predict photometric points. Note the (1+z) factors - the
    spectrum needs to be in observed wavelength for accurate transmission curves
    but the input is in rest wavelength. Flux is in flux density units, so it also
    needs to be scaled.

    Arguments:
    wave  -- the rest wavelength of the spectrum
    flux -- the rest-frame fluxes

    Keyword Arguments:
    z -- Redshift (default 0.0)
    filters -- list of filter names to integrate over
    filterPath -- directory for filter files

    Returns: Dict, containing the effective wavelength, flux measured in the
    filter, and the effective filter width


 Objective function for fitting

    This is the objective function to minimize in the fitting. Note
    the extra sqrt at the end due to an lmfit convention

    Arguments:
    params -- lm parameters object being minimized
    spec -- dictionary with the spectroscopic data
    phot -- dictionary with the photometric data
    cont_profs -- dictionary of arguments to be passed to the model flux computation

    Keyword Arguments:
    show -- whether to print the current chi2 of the fit (default True)

    Returns: weighted mean-square difference between observed flux and the
    CAFE model from params and cont_profs.


 Calculates continuum uncertainty

    Arguments:
    params -- lm parameters object with fitting errors
    derivs -- numerical derivative for each parameter at its value
    covar -- covariance matrix of parameters

    Keyword Arugments:
    pkeys -- list of parameter names to use in estimating uncertainty (default None)

    Returns: Estimated propegated undertainty in flux


Takes a numerical derivative of callable with form f(pars, wave, funcargs)

    Arguments:
    func -- callable, function to differentiate
    wave -- wavelength points where we take the derivative
    params -- params we're taking derivatives with respect to

    Keyword Arugments:
    funcargs -- Dict of additional parameters to pass to func (default None)
    eps --  Fractional variation to use in differentiation (default 1e-2)

    Returns: list of numerical derivatives for each parameter at each wavelength


 Plot the overall SED and the CAFE fit

    Arguments:
    wave -- rest wavelength of observed spectrum
    flux -- observed flux values
    sigma -- uncertainties in measured fluxes
    comps -- dict of component fluxes

    Keyword Arugments:
    weights -- CAFE weights to use in estimating final chi^2 (default None)
    npars -- number of parameters varied (default 1)

    Returns: Tuple of figure, chi^2 of fit


 Plot the SED and the CAFE fit over the spectrum wavelength range

    Arguments:
    wave -- rest wavelength of observed spectrum
    flux -- observed flux values
    func -- uncertainties in measured fluxes
    comps -- dict of component fluxes

    Keyword Arugments:
    weights -- CAFE weights to use in estimating final chi^2 (default None)
    drude -- The collection of ouput parameters of Drude profiles
    plot_drude -- if true, plots individual drude profiles, otherwise plots total
    PAH contribution. (default false)
    pahext -- if not None, applies extinction curve to PAHs

    Returns: Figure


 Plots the correlation matrix for the parameters

    Arguments:
    params -- fit lm parameters object. Fit must have been successful for
    errors to be calculted - note that if you turn off error checking,
    this is not guarenteed, and may cause crashes.

    Keyword Arguments:
    outpath -- directory to save plots to (default '')
    obj -- target name to use in filename (default '')
    tag -- string to append to the filename (default '')

    Returns: None, saves the figure to the global outpath


 Plots each components' fractional contribution to the SED

    Note that this plot interacts weirdly with the 2D version sometimes, so it's
    not generated by default.

    Arguments:
    comps -- dictionary of component fluxes

    Keyword Arguments:
    outpath -- directory to save plots to (default '')
    obj -- target name to use in filename (default '')

    Returns: None, saves to global outpath


 Plot array, assuming it's a spatial image

    Plots a spatial map of the array with the specified title. Defaults to image, can be switched
    using the contour keyword. Will eventually want to be able to specify axes in physical
    units, but need information on detector and direction to NCP.

    Arguments:
    data -- 2D spatial array of values
    name -- name of parameter to show in plot title

    Keyword Arguments:
    outpath -- directory to save plots to (default '')
    obj -- target name to use in filename (default '')
    contour -- Whether to make a contour plot (default False)
    givefig -- Whether to return figure or save it. Default false (saves)

    Returns: None, saves figure to output directory


 Plot spatial image of parameter

    Plots a spatial map of the parameter with name in pars. Defaults to image, can be switched
    using the contour keyword. Will eventually want to be able to specify axes in physical
    units, but need information on detector and direction to NCP.

    Arguments:
    pars -- lm parameters object with the parameter to plot
    name -- name of parameter to show

    Keyword Arguments:
    outpath -- directory to save plots to (default '')
    obj -- target name to use in filename (default '')
    contour -- Whether to make a contour plot (default False)
    givefig -- Whether to return figure or save it. Default false (saves)

    Returns: None, saves figure to output directory


 Plot spatial image of parameter's estimated error

    Plots a spatial map of the parameter error with name in pars. Defaults to image, can be switched
    using the contour keyword. Will eventually want to be able to specify axes in physical
    units, but need information on detector and direction to NCP.

    Arguments:
    pars -- lm parameters object with the parameter to plot
    name -- name of parameter to show

    Keyword Arguments:
    outpath -- directory to save plots to (default '')
    obj -- target name to use in filename (default '')
    contour -- Whether to make a contour plot (default False)

    Returns: None, saves figure to output directory


    params [lmfit.parameter() object]: parameters of the model
    spec [dictionary]: spectrum/a to be fitted
    phot [dictionary]: photometry to be fitted


        file_name [str]: Name of the cube to read
        file_dir [str]: Folder where the data are
        extract [str]: In case of ingesting a CRETA-produced cube, read the column that have the spectra stitched
        trim [bool]: CRETA cubes retain info on the bands/channels, which is used to trim the spectra and avoid wavelength duplications (default: True)
        keep_next [bool]: The trimming process keeps the shortest wavelength data in overlapping bands/channels (default: False)
        z (float): Redshift of the source (default: 0.)


Main function setting up the parameters and profiles for cafe_grinder()


Plot the SED generated by the inital parameters


Plot the spectrum itself. If params already exists, plot the fitted results as well.


        file_name: [string] Name of the file to be read. It can be a plain text file (.txt, .dat) with wavelength, flux and
                   flux uncertainty columns, a .csv file from CRETA, or a .fits cube from CRETA
        xy:        [2-element touple] If the input is a cube, this specifies the spaxel that is read
        file_dir:  [string] The directory where the file is
        extract:   [string] The name of the extraction to be used when importing a CRETA cube (default: stitched spectrum)
        trim:      [bool] Whether to trim overlapping wavelengths (only available for spectra extracted with CRETA)
        keep_next: [bool] If trim=True, whether to keep the longer wavelength data/band instead of the shorter wavelength one
        z:         [float] redshift of the source
        is_SED:    [bool] Whether the spectrum is SED-like, i.e., it has an unknown, low resolution (active but currently not supported)
        read_columns: [string list] If the input is a table with many columns, this specifies the names of the columns to be read
                      Usually, 'wave', 'flux', and 'flux_unc'
        flux_unc:  [float] If read_columns is specified, this keyword allows override the uncertainty by specifying
                   a relative error wrt the flux. I.e., flux_unc=0.2 will force the errors to be 20% of the flux
        wave_min:  [float] Minimum observed wavelength to be kept in the spectrum
        wave_max:  [float] Maximum observed wavelength to be kept in the spectrum
        rwave_min: [float] Minimum rest-frame wavelength to be kept in the spectrum
        rwave_max: [float] Maximum rest-frame wavelength to be kept in the spectrum


Output result from lmfit


 Recover the CAFE plot based on the input asdf file
    INPUT:
        asdf_fn: the asdf file that store the CAFE fitted parameters
    OUTPUT:
        A mpl axis object that can be modified for making the figure


 Compute a Planck function

    Planck function from jam_planck.pro, verified 8/26/20

    Arguments:
    wave -- wavelength grid for blackbody
    T - blackbody temperature(s)

    Keyword Arguments:
    um - compute flux density in um (default True)
    Hz - compute flux density with Hz (default False)

    Returns: Array of blackbody spectra for each temperature over
    the given wavelength range


 Compute an ISRF SED

    Port of Jam_SourceSED_ISRF from jam_sourcesed.pro, verified 8/26/20

    Arguments:
    wave -- array to compute SED over

    Keyword Arguments:
    T_bb -- Blackbody temperature to scale SED to match (default None)

    Returns: Array of fluxes at specified wavelengths, in erg s-1 cm-2 um-1


 Compute an AGN SED

    Port of the corresponding function in jam_sourceSED

    Arguments:
    wave -- array to compute SED over

    Keyword Arguments:
    lTot -- Total luminosity of the AGN
    r -- Distance from source to compute SED
    T_bb -- Blackbody temperature to scale SED to match (default None)

    Returns: Array of fluxes at specified wavelengths, in erg s-1 cm-2 um-1


 Compute a starburst SED

    Port of the coresponding function in jam_sourceSED

    Arguments:
    wave -- array to compute SED over
    age -- whcih sb99 grid age to use

    Keyword Arguments:
    tablePath -- location of the sb99 tables (default 'tables/')
    nebular -- whether to use flux or nebular (default False, flux)

    Returns: Array of fluxes at specified wavelengths, in erg s-1 cm-2 um-1


 Returns SED from specified source

    Port of the corespondig function in jam_sourceSED, wrapper
    for the above set of functions

    Arguments:
    wave -- array of wavelengths to compute SED

    Keyword Arguments:
    source -- type of SED to return (default ISRF)
    Jy -- return flux density in Jy or um-1 (default False/um-1)
    tablePath -- path to SED templates (default 'tables/')

    Returns -- Arrays of wavelength and corresponding flux densities


 Loads the opacity table in the format used by the CAFE tables.

    Arguments:
    wave -- wavelegnth range output should be resampled to
    fname -- filename for table to read

    Returns: Second column from file fname, resampled to wave


instnames: instrument/module names, taken from the .ini list (list)


        Output the table of PAH integrated powers

        Parameters
        ----------
        parcube:
            The parameter cube that stores the fitted parameter values

        compdict: dict
            Component dictionary, which is the dictionary that stores the fitted line/continuum profiles.
            This is needed for EQW measurements. If set None, EQW will not be presented in the PAH table.

        pah_complex: bool (default: True)
            Whether to present the PAH complex fluxes. If set to False, "ALL" the PAH fluxes
            will be provided.

        pah_obs: bool (default: False)
            In default, the presented PAH flux is the intrinsic flux, which has been corrected
            based on the fitted extinction profile. If set to True, the output will be the
            "observed" flux which is measured directly from the input spectrum, without
            considering extinction correction. This can only be set to True when there is
            continuum dictionry as input.

        savetbl:
            Save the table to a .ecsv file

        Output
        ------
        PAH table in DataFrame


Output the table of line integrated powers


Write the asdf file containing all the info about the model components


        Build the Parameters object for lmfit based on the input spectrum.
        This function combines the Parameter obj output from "make_cont_pars"
        and "make_feat_pars".

        Parameters
        ----------
            obswave:
                wavelength in the rest frame


 Initialize line parameters with an iterative estimate

        Drude peaks are a bit different (few ppt) compared with IDL version but I think it's
        fine, verified 9/10/20. This is the first part of the jam_fitfeatures.pro IDL routine.

        Arguments:
        wave -- rest wavelengths to compute spectrum at
        flux -- measured fluxes at those wavelengths
        flux_unc -- uncertainty in measured flux

        Keyword Arguments:
        minWave -- minimum wavelength cutoff to apply to lines (default None)
        maxWave -- max wavelength cutoff to apply to lines (default None)
        ref_pah_wave -- Reference wavelength for PAH features (default 6.22)
        extPAH -- extinction to apply to PAHs (default 1)
        tablePath -- Directory with line parameter tables (default 'tables/')
        atomic_table -- List of input atomic features if set (default None)
        molecular_table -- List of input molecular features if set (default None)
        hrecomb_table -- List of input hydrogen recombination features if set (default None)
        pah_table -- List of input PAH features if set (default None)
        gopacity_table -- List of input gaussian opacity features if set (default None)

        Returns: Initial guesses for gaussian and drude line profile parameters for
        lines in the wavelength range


Makes the parameters structure for the continuum fit from the input dictionary

        Arguments:
        inpars -- dictionary of initial parameters/settings read from the runfile

        Returns: lm Parameters object for the CAFE continuum parameters


 Turns lists of initial Gaussian and Drude profiles into a parameters object for the fitter.

        Arguments:
        inpars -- dictionary of input parameters read from inpars['PAH & LINE OPTIONS']
        gauss -- first guess at gaussian line profile parameters
        drude -- first guess at drude line profile parameters

        Returns: lm Parameters object for the CAFE feature parameters


    Insert values in the Parameter object into an existing parcube

        Parameters
        ----------
        parobj: (Parameter object)
        parcube: (hdul)
        x, y:
            spaxel coordinate


    Turn parameters in parcube at a specific spaxel into a Parameter object

        Parameters
        ----------
        parcube: Parameter cube (hdul)
        x, y: Spaxel coordinate
        ini_parobj: Parameter object (lmfit parameters)

        If ini_parobj is provided the parcube parameters that are in ini_parobj will be injected in parobj
        and len(parobj) will have len(parobj) and not len(parcube)


Convert a parameter object to a DataFrame


 Make initial PAH profile structure

    Makes a first guess at PAH feature amplitudes, presumably based on the
    references Smith et al. 2006) and Brandl et al. (2006). This is a direct
    port of the jam_pahdrude.pro IDL routine used by original CAFE

    Keyword Arguments:
    path -- the path to look for the pah template file

    Returns: Dict, consisting of inital wavelength, with, peak, and line
    complex IDs for the PAHs in the file


 Compute the flux from a gaussian profile

    Arguments:
    wave -- array of wavelengths to compute fluxes for
    gauss -- list of profile parameters for each line [wave0, sigma, peak],...]

    Returns: Array of fluxes corresponding to initial wavelength array


    Output the comblined PAH profiles with a set of parameters (wave, width(gamma), peak, complex).

    Port of jam_drudeflux.pro IDL routine. Drude is a list of 3-elements
    [wave0, gamma, peak] for each line
    Verified 8/24/20
    This is the line profile used for PAHs, see Draine's ISM book for a better
    explanation

    Parameters
    ----------
    wave -- array of wavelengths to compute fluxes for
    drude -- list of profile paramerers for each line [[waves],[widths(gamma)],[peaks],[complexes]]

    Returns
    -------
    Profile of the summation of all the PAH features


 Computes integrated flux of each line in drude, with optional extinction

    Arguments:
    wave -- array of wavelengths to compute fluxes
    drude -- list of profile paramerers for each line [[waves],[widths],[peaks],[complexes]]

    Keyword Arguments:
    ext -- extinction curve to apply to flux, with same shape as wave. Default None (no extinction)
    scale -- PAH contribution relative to continuum at refwave. Default 1.0 (use whatever the fitter gives!)
    refwave -- PAH reference wavelength, default 6.22um

    Returns: array of integrated fluxes for each PAH in the drude table


Default Gaussian likelihood


        Check for existence of the desired output directory and create it
        if it doesn't exist


Update the environment-lock.yml file from the current project environment.


Run mypy static type analysis.


Run unit tests.


Create daily NetCDFs with only data we care about from CFSR source data.

    The source data (GRIB2) will be filtered for only the variables of interest,
    subset to only the region of interest, and reprojected for the area of interest.


Extract only analysis and 6-hour forecast files from a daily tar.

    Daily tars also contain unwanted 1-hour through 9-hour forecast files.


Filter analysis grib2s in `grib2_dir`, selecting those relevant to `date`.

    This is trivial with analysis files; simply select those files matching date.


Filter for analysis grib2s in daily `grib2_dir`.

    Grab all files that match *pgrbhanl*.


Filter forecast grib2s in `grib2_dirs`, selecting those relevant to `date`.

    `grib2_dirs` may contain up to 2 paths.

    This is non-trivial for forecast files; we need to offset the selection back by 6
    hours, because each file contains expected measurements 6 hours in the future from
    the date in the filename.


Filter forecast grib2s in provided dirs.

    Grab files that match *pgrbh06*: from previous day grab 18z, from current day, grab
    00z, 06z, 12z.


Select CFSR monthly granule matching `month` and `product_type`.


Download a 1-day .tar file from RDA.

    The end date is calculated from `window_start`; the last day of the month is used if
    `window_start + 5` is in the next month.


Download a 5-day .tar file from RDA.

    The end date is calculated from `window_start`; the last day of the month is used if
    `window_start + 5` is in the next month.


Download a monthly .tar file from RDA (containing v2 monthly data).


Download a yearly .tar file from RDA (containing v1 monthly data).


Calculate a 5-day tar base URL (i.e. URL excluding filename).

    E.g.:
    * analysis v1: 'https://rda.ucar.edu/data/ds093.0/1982'
    * forecast v1: 'https://rda.ucar.edu/data/ds093.0/1980'
    * analysis v2: 'https://rda.ucar.edu/data/ds094.0/2011'
    * forecast v2: 'https://rda.ucar.edu/data/ds094.0/2011'

    ENC - This base url is the same for daily v1/v2 so I changed the name so it
          can be used for both


Calculate a CFSR 1-day tar filename.

    Both analysis and forecast files are in a single tar e.g.
     'cdas1.20110401.pgrbh.tar'


Calculate a CFSR 5-day tar filename.

    E.g.:
    * analysis: 'pgbhnl.gdas.19820616-19820620.tar'
    * forecast: 'pgbh06.gdas.19800306-19800310.tar'


Generate a 1-day tar URL for daily tar files.

    E.g.:
        'https://rda.ucar.edu/data/ds094.0/2011/cdas1.20110402.pgrbh.tar'


Generate a 5-day tar URL.

    E.g.:
    * analysis v1:
        'https://rda.ucar.edu/data/ds093.0/1982/pgbhnl.gdas.19820616-19820620.tar'
    * forecast v1:
        'https://rda.ucar.edu/data/ds093.0/1980/pgbh06.gdas.19800306-19800310.tar'
    * analysis v2:
        'https://rda.ucar.edu/data/ds094.0/2011/pgbhnl.gdas.20110326-20110331.tar'
    * forecast v2:
        'https://rda.ucar.edu/data/ds094.0/2011/pgbh06.gdas.20110326-20110331.tar'


Calculate a CFSR monthly tar baseurl.

    e.g.: 'https://rda.ucar.edu/data/ds094.2/regular'


Calculate a CFSR monthly tar filename.

    e.g.: 'pgbh.gdas.201101.tar'


Calculate a monthly tar URL.

    NOTE: only v2 product provides monthly data in monthly tars.

    e.g. forecast and analysis data combined:
        'https://rda.ucar.edu/data/ds094.2/regular/pgbh.gdas.201101.tar'


Calculate a yearly tar URL.

    NOTE: only v1 product provides monthly data in yearly tars.

    E.g.
    * analysis: 'https://rda.ucar.edu/data/ds093.2/regular/pgbhnl.gdas.1979.tar'
    * forecast: 'https://rda.ucar.edu/data/ds093.2/regular/pgbh06.gdas.1979.tar'


Validate whether `date` is a valid start date of a ~5-day CFSR window.


Validate whether `end` is valid in relation to `start`.

        E.g. 2010-01-05 may look like a valid end date, but not if the start date is
        2001-01-01 because the difference is years.


Calculate end date of CFSR 5-day window based on start date.

        Because the CFSR files are named with inclusive intervals, the actual difference
        between the start and end dates is 4 days, although the files each contain 5
        days of data.


Calculate a CFSR 5-day window containing `date`.


Calculate the nearest valid start date less than or equal to `date`.


Generate list of dates between start and end, inclusive.


Calculate the number of months between 0 AD and `month`.

    Ignore day portion of `date`.

    NOTE: Python's built-in datetime module doesn't support 0AD. This is only a hack for
    calculating month ranges, since Python's built-in datetime module also doesn't
    support adding or subtracting months (ignoring month length).


List months that lie within `start` and `end` ("day" portion of dates ignored).

    The result is inclusive, e.g. if `end` is `2022-01-01`, then `(2022, 1)` will be in
    the result.


Lookup elements in a dict keyed by a tuple representing a range of values.

    When lookup_key is between the two values in the tuple, we've found a match.


Generate mapping of some GRIB2 varnames to new varnames.

    Does not map variable names with level-dependent GRIB2 varnames.


Combine surface and upper level variables into a single data array.

    Variables are combined by stacking the surface level 2d array "on top" of the upper
    level 3d array.

    * surface2d: 2d array representing surface level
    * pl3d: 3d array representing pressure levels above surface. Expected to contain
      exactly 3 pressure levels.


Replace the maximum value for the array's dtype with NaN.

    Expects only float32 datatypes.


Keep only specified dataset variables.


Test conversion funcs from CLI.

        e.g.:
            PYTHONPATH=. python sipn_reanalysis_ingest/util/convert.py


Test 6-hourly convert function.


Test monthly convert function.


Add an image on the figure
    :param imagepath: path to the image to add
    :param ax: axes object
    :param position: relative position on the map
    :param zoom: zoom level
    :param zorder:
    :return:


    Create a rectangular patch to add on the map
    :param coordinates:
    :param m: Basemap object
    :return: patch


    Extract the coastline in a region delimited by a bounding box
    and save the result in a text file
    :param coordinates: coordinates delimiting a bounding box (lonmin, lonmax, latmin, latmax)
    :param filename: name of the file where the coastline will be saved
    :param res: resolution for the extraction
    :return:


    Read coastline coordinates from an existing file
    :param coastfile: name of the file containing the coastline
    :param valex: exclusion value
    :return: lon, lat


    Read coastline coordinates from an existing file in a region delimited
    by a bounding box
    :param coastfile: name of the file containing the coastline
    :param coordinates: coordinates delimiting a bounding box (lonmin, lonmax, latmin, latmax)
    :param valex: exclusion value
    :return: lon, lat


    Load bathymetry from a netCDF file in a select region
    delimited by a list of coordinates
    :param bathyfile: name of the netCDF file
    :param coordinates: coordinates delimiting a bounding box (lonmin, lonmax, latmin, latmax)
    :return:


    :param altimetryfile:
    :param coordinates: coordinates delimiting a bounding box (lonmin, lonmax, latmin, latmax)

    :return:


Return the coordinates, the SST, the time and the satellite name,
    given a data file and a list of coordinates delimiting a bounding box
    :param sstfile: name of the netCDF4 file containing the data
    :param coordinates: coordinates delimiting a bounding box (lonmin, lonmax, latmin, latmax)
    :return:


    Load the coordinates (lon, lat, depth), the temperature and chlorophyll concentration
    from the selected netCDF file
    :param ctdfile: name of the netCDF file
    :return: lon, lat, depth, temp, chloro


    Load the coordinates and the temperature from a glider file
    :param gliderfile: name of the netCDF file
    :param NN: sub-sampling factor (keep 1 out of NN measurements)


    Load the coordinates from a glider file
    :param gliderfile: name of the glider netCDF file
    :return: lon: longitude
    :return: lat: latitude
    :return: depth: depth
    :return: time: time


    Read the L2 wind from a netCDF file
    given a list of coordinates delimiting a bounding box
    :param windfile: netCDF file containing the data
    :param coordinates: coordinates delimiting a bounding box (lonmin, lonmax, latmin, latmax)
    :return: lon, lat, uwind, vwind, windtime


Return a fig, m and ax objects
    given a set of coordinates defining a bounding box
    :param coordinates: list of coordinates (lonmin, lonmax, latmin, latmax)
    :param res: resolution in the projection ; 'i' by default (intermediate)
    :return: fig
    :type fig: Figure object
    :return m
    :type m: Basemap object
    :return ax
    :type ax: AxesSubplot object


repare the logging messages and file


Add x and y ticks (no line plotted for better visibility)


Return coordinates from the file containing the information
    on the different CTD legs


    Return the coordinates of the contours
    as a list of lists (one list per contour)


        Applying a smoothing function on the front coordinates
        :param N: subsampling factor
        :param s: smoothness parameter
        :param nest: estimate of number of knots needed (-1 = maximal)
        :return:


        Discard the measurements of which the position
        doesn't have the indicated quality flag


        Mask the time outside the selected period

        finaldate and initialdate are `datetime` obects
        for example: finaldate=datatime.datetime(2017, 5, 3, 18, 30, 0)


        Compute the velocity using the Vincenty distance

        The values above velmax are masked


Remove the masked coordinates (lon, lat, time, dates)


Add the measurements to a 3D scatter plot


        Create a geoJSON file containing the glider coordinates as a LineString object
        :param filename: name of the JSON file
        :varname: name of the variable in the JSON file
        :NN: value used for the data subsampling


        Read the profile stored in a mat file
        Return
          the coordinates lon, lat and time (scalars)
          the depth (array)
          the temperature and salinity (arrays)


        Read all the profiles from a list of files
        Return
          arrays for lon, lat and time


        Write the arrays into a single netCDF file `ncfile`
        with a structure similar to SOCIB files
        Inputs:
          lon, lat, time, pressure, T and S are numpy ndarrays
          (arrays of arrays), one array per profile


        Mask the coordinates with a quality flag different from the specified value
        1 = good data


Mask the sst values which don't match the mentioned quality flag


Mask the velocity values which don't match the mentioned quality flag


Plot velocity field with arrows on a map


        Draw a rectangle around the transect
        N1 and N2 are the indices of the extreme points
        of the considered section


        Create a meridional section of zonal velocity
        Inputs:
        lat: 1-D array of latitudes
        depth: 1-D array of depths
        u: 2-D array of velocities


        :param filename: name of the netCDF file
        :return: lon, lat, SLA, u, v, time


Subset based on geographical positions


        Smooth the jet coordinates using a spline
        Input:
            s = smoothness parameter
            k = spline order
            nest = estimate of number of knots needed (-1 = maximal)


        Add an arrow at the specified position
        Input:
            NN = index of the coordinates vector


Add a circular gyre with arrows on the eastern and western sides


Reads LROC 5 - 20 km crater catalogue CSV.

    Parameters
    ----------
    filename : str, optional
        Filepath and name of LROC csv file.  Defaults to the one in the current
        folder.
    sortlat : bool, optional
        If `True` (default), order catalogue by latitude.

    Returns
    -------
    craters : pandas.DataFrame
        Craters data frame.


Reads Head et al. 2010 >= 20 km diameter crater catalogue.

    Parameters
    ----------
    filename : str, optional
        Filepath and name of Head et al. csv file.  Defaults to the one in
        the current folder.
    sortlat : bool, optional
        If `True` (default), order catalogue by latitude.

    Returns
    -------
    craters : pandas.DataFrame
        Craters data frame.


Combines LROC 5 - 20 km crater dataset with Head >= 20 km dataset.

    Parameters
    ----------
    filelroc : str, optional
        LROC crater file location.  Defaults to the one in the current folder.
    filehead : str, optional
        Head et al. crater file location.  Defaults to the one in the current
        folder.
    sortlat : bool, optional
        If `True` (default), order catalogue by latitude.

    Returns
    -------
    craters : pandas.DataFrame
        Craters data frame.


Helper function copied from cartopy.img_transform for resizing an image
    without changing its aspect ratio.

    Parameters
    ----------
    regrid_shape : int or float
        Target length of the shorter axis (in units of pixels).
    target_extent : some
        Width and height of the target image (generally not in units of
        pixels).

    Returns
    -------
    regrid_shape : tuple
        Width and height of the target image in pixels.


Warps images with cartopy.img_transform.warp_array, then plots them with
    imshow.  Based on cartopy.mpl.geoaxes.imshow.

    Parameters
    ----------
    img : numpy.ndarray
        Image as a 2D array.
    iproj : cartopy.crs.Projection instance
        Input coordinate system.
    iextent : list-like
        Coordinate limits (x_min, x_max, y_min, y_max) of input.
    oproj : cartopy.crs.Projection instance
        Output coordinate system.
    oextent : list-like
        Coordinate limits (x_min, x_max, y_min, y_max) of output.
    origin : "lower" or "upper", optional
        Based on imshow convention for displaying image y-axis.  "upper" means
        [0,0] is in the upper-left corner of the image; "lower" means it's in
        the bottom-left.
    rgcoeff : float, optional
        Fractional size increase of transformed image height.  Generically set
        to 1.2 to prevent loss of fidelity during transform (though some of it
        is inevitably lost due to warping).


Wrapper for WarpImage that adds padding to warped image to make it the
    same size as the original.

    Parameters
    ----------
    img : numpy.ndarray
        Image as a 2D array.
    iproj : cartopy.crs.Projection instance
        Input coordinate system.
    iextent : list-like
        Coordinate limits (x_min, x_max, y_min, y_max) of input.
    oproj : cartopy.crs.Projection instance
        Output coordinate system.
    oextent : list-like
        Coordinate limits (x_min, x_max, y_min, y_max) of output.
    origin : "lower" or "upper", optional
        Based on imshow convention for displaying image y-axis.  "upper" means
        [0,0] is in the upper-left corner of the image; "lower" means it's in
        the bottom-left.
    rgcoeff : float, optional
        Fractional size increase of transformed image height.  Generically set
        to 1.2 to prevent loss of fidelity during transform (though some of it
        is inevitably lost due to warping).
    fillbg : 'black' or 'white', optional.
        Fills padding with either black (0) or white (255) values.  Default is
        black.

    Returns
    -------
    imgo : PIL.Image.Image
        Warped image with padding
    imgw.size : tuple
        Width, height of picture without padding
    offset : tuple
        Pixel width of (left, top)-side padding


Wrapper for WarpImage that adds padding to warped image to make it the
    same size as the original.

    Parameters
    ----------
    craters : pandas.DataFrame
        Crater info
    geoproj : cartopy.crs.Geodetic instance
        Input lat/long coordinate system
    oproj : cartopy.crs.Projection instance
        Output coordinate system
    oextent : list-like
        Coordinate limits (x_min, x_max, y_min, y_max)
        of output
    imgdim : list, tuple or ndarray
        Length and height of image, in pixels
    llbd : list-like
        Long/lat limits (long_min, long_max,
        lat_min, lat_max) of image
    origin : "lower" or "upper"
        Based on imshow convention for displaying image y-axis.
        "upper" means that [0,0] is upper-left corner of image;
        "lower" means it is bottom-left.

    Returns
    -------
    ctr_wrp : pandas.DataFrame
        DataFrame that includes pixel x, y positions