        Find the start (self.start_ind) and end (self.stop_ind) points
        for the data in the Horizons file (i.e. the end of the header
        and beginning of the footer). Also counts the lines in the
        file. (self.line_count)


reads standard output from JPL Horizons


        *Astropy.CartesianRepresentation*

        return X,Y,Z positions based on RA, DEC and distance


extract the name of dataset


import time, brightness, and its uncertainty


        Internal function to import photometric data into the correct
        form using a few numpy ndarrays.

        Parameters:
            time - Date vector of the data
            brightness - vector of the photometric measurements
            err_brightness - vector of the errors in the phot measurements.


        *dict*

        Settings that specify how the photometry should be plotted.

        The keys in this *dict* could be either special keys introduced here
        (i.e., ``show_bad`` and ``show_errorbars``) or keys accepted by
        matplotlib.pyplot plotting functions. The latter could be for example
        ``color``, ``marker``, ``label``, ``alpha``, ``zorder``,
        ``markersize``, or ``visible``.

        See :py:class:`~MulensModel.mulensdata.MulensData`
        for more information.


        Plot the data.

        Uses :py:attr:`plot_properties` for label, color, etc.
        This settings can be changed by setting ``**kwargs``.

        You can plot in either flux or magnitude space.

        Keywords:
            phot_fmt: *string* ('mag', 'flux')
                Whether to plot the data in magnitudes or in flux. Default
                is the same as :py:attr:`input_fmt`.

            show_errorbars: *boolean*
                If show_errorbars is True (default), plots with
                matplotlib.errorbar(). If False, plots with
                matplotlib.scatter().

            show_bad: *boolean*
                If False, bad data are suppressed (default).
                If True, shows points marked as bad
                (:py:obj:`mulensdata.MulensData.bad`) as 'x'

            subtract_2450000, subtract_2460000: *boolean*
                If True, subtracts 2450000 or 2460000 from the time
                axis to get more human-scale numbers. If using it, make
                sure to also set the same settings for all other
                plotting calls (e.g. :py:func:`plot_lc()`).

            ``**kwargs``:
                passed to matplotlib plotting functions.


plot datapoints while evaluating various contingencies


        Set plot properties using ``**kwargs`` and
        `py:plot_properties`. kwargs takes precedent.

        Keywords:
            show_errorbars: *boolean*
                `True` means plotting done with plt.errorbar. `False`
                means plotting done with plt.scatter.

            bad: *boolean*
                `True` means marker is default to 'x'. `False` means
                marker is default to 'o'.

           ``**kwargs``: *dict*
               Keywords accepted by plt.errorbar() or plt.scatter().


        Change negative uncertainties to 0.
        Parameters kind should be 'good' or 'bad'.


save run of matplotlib.pyplot.errorbar(); returns ErrorbarContainer


save run of matplotlib.pyplot.scatter(); returns PathCollection


just calculate magnitudes if needed, or return input otherwise


        *np.ndarray*

        magnitude vector


        *np.ndarray*

        vector of magnitude errors


        *numpy.ndarray*

        Vector of the measured brightness in flux units.


        *np.ndarray*

        Vector of uncertainties of *flux* values.


        *np.ndarray boolean*

        flags marking bad data


        *np.ndarray boolean*

        flags marking good data i.e., opposite to :py:func:`bad`


        *int*

        give total number of epochs (including bad data)


        Gives photometry in input format (mag or flux).

        Returns :
            data: *np.ndarray*
                Magnitudes or fluxes

            data_err: *np.ndarray*
                Uncertainties of magnitudes or of fluxes


get data and their photometry in mag or flux


        Gives photometry in format used for chi2 calculation
        (flux in most cases, but magnitude possible).

        Returns :
            data: *np.ndarray*
                Magnitudes or fluxes

            data_err: *np.ndarray*
                Uncertainties of magnitudes or of fluxes


        *String*

        Bandpass of given dataset (primary usage is limb darkening), e.g. 'I'
        or 'V'. Returns *None* if not set.


        *Astropy.SkyCoord* object for satellite
        positions at epochs covered by the dataset

        Returns :
            skycoord: *astropy.coordinates.SkyCoord*
                satellite positions at epochs covered by the dataset


        *str* ('mag' or 'flux')

        Input format - same as *phot_fmt* keyword in __init__().


        *str* ('mag' or 'flux')

        Photometry format used  for chi^2 calculations. Default is 'flux'.


        *str*

        File with satellite ephemeris.


        Returns a copy of given instance with settings copied

        Returns :
            mulens_data: :py:class:`~MulensModel.mulensdata.MulensData`
                Copy of self.


        Scale magnitude errorbars by multiplying by *factor* and
        then adding *minimum* in squares.

        Parameters :
            factor: *float*
                Multiplication factor. Typically used for faint events.

            minimum: *float*
                Floor of magnitude errorbars. Typically used for bright
                events.


Scale magnitude errorbars


        *list* of two *floats*

        Parameters used by :py:func:`scale_errorbars()`.
        The first one is multiplication factor,
        while the second is the minimum scatter added in squares.


        *str*

        Equation and parameters used by :py:func:`scale_errorbars()`.


        Plot the model magnification curve.

        Keywords :
            see :py:func:`plot_lc()`

            gamma:
                see :py:func:`get_magnification()`

            satellite_skycoord:
                see :py:func:`plot_trajectory()`

            source_flux_ratio: *float*
                If the model has two sources, source_flux_ratio is the ratio of
                source_flux_2 / source_flux_1

            ``**kwargs``:
                any arguments accepted by :py:func:`matplotlib.pyplot.plot()`.


Parsing of fluxes to be used in get_lc/plot_lc.


        calculate magnitude or flux without making checks on input parameters

        source_flux is a *float* (for single source model) or
        an iterable (for multiple sources)


        Obtain what is returned in function _get_lc, where phot_fmt and
        return_times are explicitly given


        Plot the model light curve in magnitudes.

        Keywords :
            times: [*float*, *list*, *numpy.ndarray*]
                a list of times at which to plot the magnifications

            t_range, t_start, t_stop, dt, n_epochs:
                see :py:func:`set_times()`

            source_flux, blend_flux, source_flux_ratio:
                see :py:func:`get_lc()`

            gamma, bandpass:
                see :py:func:`get_magnification()`

            subtract_2450000, subtract_2460000: *boolean*, optional
                If True, subtracts 2450000 or 2460000 from the time
                axis to get more human-scale numbers. If using, make
                sure to also set the same settings for all other
                plotting calls (e.g. :py:func:`plot_data()`)

            phot_fmt: *str*
                Specifies whether the photometry is plotted in magnitude or
                flux space. Accepts either 'mag' or 'flux'. Default = 'mag'.

            ``**kwargs``:
                any arguments accepted by :py:func:`matplotlib.pyplot.plot()`.


safe run of matplotlib.pyplot.plot()


Adjust axes labels and ranges, given the inputs phot_fmt and subtract


        Plot the caustic structure. See
        :py:func:`MulensModel.caustics.Caustics.plot()` for binary lenses.
        For a single lens it just marks (0, 0) point and
        the first two parameters are ignored.

        Additional parameters :
            n_points: *int*, optional
                The number of points to calculate along the caustic.
                Defaults to 5000.

            epoch: *float*, optional
                Epoch for which separation *s* will be used. Important
                for models with orbital motion. Defaults to *t_0_kep*,
                which defaults to *t_0*.

            ``**kwargs``:
                keywords accepted by :py:func:`matplotlib.pyplot.scatter()`


        Updates :py:attr:`~caustics` property for given epoch.

        Parameters :
            epoch: *float*
                For orbital motion models, epoch for which separation *s*
                is calculated to calculate :py:attr:`~caustics`. Defaults
                to *t_0_kep*, which defaults to *t_0*.


Update self._caustics for single lens.


Update self._caustics for binary lens.


        Plot the source trajectory.

        Keywords (all optional) :

            times, t_range, t_start, t_stop, dt, n_epochs:
                May all be used to specify exactly when to plot the
                source trajectory. See also :py:func:`plot_lc()` and
                :py:func:`set_times()`.

            caustics: *boolean*
                plot the caustic structure in addition to the source
                trajectory. default=False (off). For finer control of
                plotting features, e.g. color, use :py:func:`plot_caustics()`
                instead.

            arrow: *boolean*
                Show the direction of the source motion. Default is *True*.

            satellite_skycoord: *astropy.SkyCoord* or
            :py:class:`MulensModel.satelliteskycoord.SatelliteSkyCoord`

                Allows the user to specify that the trajectory is calculated
                for a satellite. If *astropy.SkyCoord* object is provided,
                then these are satellite positions for all epochs.
                See also :py:func:`get_satellite_coords()`

            arrow_kwargs: *dict*
                Kwargs that are passed to :py:func:`pyplot.arrow()`. If no
                color is given here, then we use one specified in ``**kwargs``
                and if nothing is there, then we use black. The size of
                the arrow is determined based on limits of current axis.
                If those are not adequate, then change the size by specifying
                *width* keyword and maybe other as well. Note that
                *arrow_kwargs* are of *dict* type and are different than
                ``**kwargs``.

            ``**kwargs``
                Controls plotting features of the trajectory. It's passed to
                :py:func:`pyplot.plot()`.

        Note that in order to have equal scaling of both axis
        (i.e., make circles look circular), you have to call appropriate
        *pyplot* command. This can be one of these commands:

        .. code-block:: python

          pyplot.axis('equal')
          pyplot.axis('scaled')
          pyplot.axis('square')
          pyplot.gca().set_aspect('equal')

        They have slightly different behavior.


Plots trajectory of a single source.


Plot arrow for given trajectory.


        Plot source: circles of the radius rho at positions corresponding to
        source positions at times. When the rho is not defined, then X symbols
        are plotted.

        Parameters:
            times: *float* or *np.ndarray*
                epochs for which source positions will be plotted

            ``**kwargs``:
                Keyword arguments passed to matplotlib.Circle_.
                Examples: ``color='red'``, ``fill=False``,
                ``linewidth=3``, ``alpha=0.5``. When the rho is not defined,
                then keyword arguments are passed to matplotlib.plot_.

        Note that it is likely that with default axis scaling, the circles may
        be plotted as ellipses. To mitigate it, use:
        ``plt.gca().set_aspect('equal')`` or ``plt.axis('equal')``
        (the other possible options are ``'scaled'`` or ``'square'``).

        .. _matplotlib.Circle:
          https://matplotlib.org/api/_as_gen/matplotlib.patches.Circle.html
        .. _matplotlib.plot:
          https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html


Internal function for plotting sources.


        Check if limb darkening is used without methods that allow it.

        Parameters :
            methods: *list*
                List of methods used for magnification calculation.


        *list*

        List of methods used for magnification calculation (single source) or
        *dict* of such lists (multiple sources).


        Stores information on method to be used, when no method is
        directly specified. See
        :py:class:`~MulensModel.magnificationcurve.MagnificationCurve`
        for a list of implemented methods.

        Parameters:
            method: *str*
                Name of the method to be used.


Check if the provided kwargs are valid for the given method.


Extract limb coeffs for all sources and given band.


Get gamma from either bandpass or gamma


        Specifies the types of the microlensing parallax that will be
        included in calculations.

        Parameters :

            earth_orbital: *boolean*, optional
                Do you want to include the effect of Earth motion about
                the Sun? Default is *False*.

            satellite: *boolean*, optional
                Do you want to include the effect of difference due to
                separation between the Earth and satellite? Note that this
                separation changes over time. Default is *False*.

            topocentric: *boolean*, optional
                Do you want to include the effect of different positions
                of observatories on the Earth? Default is *False*.
                Note that this is significant only for very high magnification
                events and if high quality datasets are analyzed.
                Hence, this effect is rarely needed. **Not Implemented yet.**


Internal function that calculates magnification.


        calculate model magnification for given times for model with
        a single source


        calculate model magnification for given times for model with
        two sources

        source_flux_ratio: *float* or *list*
        separate: *bool*


Calculate magnification separately for each source.


        :py:class:`~MulensModel.caustics.Caustics`

        Caustics for given model


        :py:class:`~MulensModel.modelparameters.ModelParameters`

        Model parameters.


        *int*

        number of objects in the lens system


        *int*

        number of luminous sources; it's possible to be 1 for xallarap model


        *list*

        List of all bandpasses for which limb darkening coefficients are set.


        Set both u and gamma LD coeffs based on info provided.

        default_gamma should be None or 0.


        Calculate point-source--binary-lens magnification.

        Returns :
            magnification: *float*
                Point source magnification.


Calculate point-source--binary-lens magnification.


        Change frame in which source position is provided:
        from the center of mass to the secondary mass.


Format error message and raise error for wrong number of solutions


Calculate 1 magnification using VBBL.


        Call VBBL to get 1 magnification for point source.
        This function is also called by child classes.


Calculate 1 magnification value


First try VBBL then WM95 to get magnification


Check if rho is float and positive.


Evaluates Gould (2008) eq. 7


        Calculate the magnification

        Parameters : None

        Returns :
            magnification: *float* or *np.ndarray*
                The magnification for each point
                specified by `u` in :py:attr:`~trajectory`.


        Calculate the magnification

        Returns :
            magnification: *float* or *sequence* of three *floats*
                Hexadecapole approximation (*float*) by default.
                If :py:attr:`all_approximations` is *True*, returns
                hexadecapole, quadrupole, and point source approximations
                (*sequence* of three *floats*)


Evaluates Gould (2008) eq. 8


Calculate 1 magnification using AC.


        Change frame in which source position is provided:
        mirror in X (i.e., secondary mass has negative X) and mirror in Y.


Check if the list of methods is valid and raise errors if not.


        check if there is method defined that uses finite source
        calculations and warn if not


High-level function that separations PL/BL and shear/no shear


 Create a trajectory object for a given subset of the data
        specified by *selection*.


Setup the kwargs for a given magnification object.


 For simple point lens models, create a *dict* of magnification
        objects corresponding to the user-specified magnification methods.


 For point lens + shear models, create a *dict* of magnification
        objects corresponding to the user-specified magnification methods.


 For simple binary lens models, create a *dict* of magnification
        objects corresponding to the user-specified magnification methods.


        For binary lens + shear models, create a *dict* of magnification
        objects corresponding to the user-specified magnification methods.


        Calculate the magnification both for point and binary lens models,
        avoiding code duplication.


        *list*

        for each epoch, decide which methods should be used to
        calculate magnification, but don't run the calculations


        *dict*

        Keys are the magnification methods. Values are a boolean index that
        indicate which epochs should be calculated with each method.


        Transform gamma limb darkening coefficient to u in convention
        introduced by `An et al. 2008 (ApJ 681, 1593)
        <https://ui.adsabs.harvard.edu/abs/2002ApJ...572..521A/abstract>`_.

        Parameters :
            gamma: *float*
                Limb darkening coefficient in gamma convention.

        Returns :
            u: *float*
                Limb darkening coefficient in u convention.


        Transform u limb darkening coefficient to gamma in convention
        introduced by `An et al. 2008 (ApJ 681, 1593)
        <https://ui.adsabs.harvard.edu/abs/2002ApJ...572..521A/abstract>`_.

        Parameters :
            u: *float*
                Limb darkening coefficient in u convention.

        Returns :
            gamma: *float*
                Limb darkening coefficient in gamma convention.


        Calculate 3D velocity of Earth for given epoch.

        If you need velocity projected on the plane of the sky, then use
        :py:func:`~MulensModel.coordinates.Coordinates.v_Earth_projected`

        Parameters :
            full_BJD: *float*
                Barycentric Julian Data. Full means it should begin
                with 245... or 246...

        Returns :
            velocity: *np.ndarray* (*float*, size of (3,))
                3D velocity in km/s. The frame follows *Astropy* conventions.


        Accurate floating points sum of complex numbers in iterable.

        Parameters :
            arguments: *iterable* (e.g., *list* or *np.ndarray*)

        Returns :
            sum: *complex*
                Sum of *arguments*.


        Get vector that is perpendicular to the 2 input ones and is normalized.

        Parameters :
            vector_1: *np.ndarray* (3,)
                First vector.

            vector_2: *np.ndarray* (3,)
                Second vector.

        Returns :
            vector_product_norm: *np.ndarray* (3,)
                Normalized vector product of the inputs.


        Dot product of 2 vectors represented by
        *astropy.CartesianRepresentation* and *np.ndarray*.

        Parameters :
            cartesian: *astropy.CartesianRepresentation*
                First vector.

            vector: *np.ndarray*
                Second vector (length 3).

        Returns :
            dot_product: *astropy.Quantity*
                Dot product of inputs.


        Change format of month in date, e.g.
        *'2015-Oct-30 12:00'* -> *'2015-10-30 12:00'*

        Parameters :
            text: *str*
                Date to be changed.

        Returns :
            out_text: *str*
                Changed text.


        Check if *astropy* package is installed at given or later version.

        Parameters :
            minimum: *str*
                Minimum version, e.g., *'3.1.2'*.

        Returns :
            out: *bool*
                Is the installed version later?


        Find value that is supposed to be subtracted from time vector.

        Parameters :
            subtract_2450000: *bool*
                Should we subtract 2450000?

            subtract_2460000: *bool*
                Should we subtract 2460000?

        Returns :
            subtract: *float*
                Value to be subtracted.


        Find string for xlabel

        Parameters :
            subtract_2450000: *bool*
                Should we subtract 2450000?

            subtract_2460000: *bool*
                Should we subtract 2460000?

        Returns :
            xlabel: *str*
                String to be used by *pyplot.xlabel()*


        Plots the caustics using :py:func:`matplotlib.pyplot.scatter()`.

        Parameters :
            n_points: *int*, optional
                The number of points to calculate along the caustic.
                Defaults to 5000.

            ``**kwargs``:
                keywords accepted by :py:func:`matplotlib.pyplot.scatter()`

        Note that default scaling of axis may not be equal on both axis.
        To mitigate this, use:
        ``plt.gca().set_aspect('equal')`` or ``plt.axis('equal')``
        (the other possible options are ``'scaled'`` or ``'square'``).


Critical curve stored as :py:class:`CriticalCurve` object, read-only


        Basic plotting. Default is to plot the light curve with the residuals.
        If the model has 2 or more lenses, also plot the source trajectory with
        caustics. For more detailed control over the plotting, see
        :py:func:`~plot_model()`, :py:func:`~plot_data()`, and
        :py:func:`~plot_trajectory`.

        Keywords:
            t_range: *list*, *tuple*
                Time range over which to show the light curve plot.

            residuals: *bool*
                Whether or not to plot the residuals with the light curve.

            show_errorbars: *bool*
                Whether or not to show the errorbars on the data. Default is
                *None* (see :py:func:`~plot_data()`).

            show_bad: *bool*
                Whether or not to show data points marked as "bad" (see
                :py:attr:`~MulensModel.mulensdata.MulensData.bad`). Default is
                *None* (see :py:func:`~plot_data()`).

            legend: *bool*
                Whether or not to show a legend for the datasets.

            trajectory: *bool*
                Whether or not to plot the source trajectory. Defaults to
                *False* for single lens events and *True* for binary lenses.

            title: *str*
                Title for the plot. Same title is used for trajectory plot, if
                applicable.

            subtract_2450000, subtract_2460000: *bool*
                see :py:func:`~plot_data()`.

            data_ref:  *int* or *MulensData*
                see :py:func:`~plot_data()`.


Plot model and data


plot trajectory after plotting model and data


        Plot the model light curve in magnitudes. See
        :py:func:`MulensModel.model.Model.plot_lc()` for details.

        Keywords :
            data_ref: *int* or *MulensData*
                If data_ref is not specified, uses :py:obj:`~data_ref`.

            ``**kwargs``:
                Keywords passed to
                :py:func:`MulensModel.model.Model.plot_lc()`.
                You can use them to set time range plotted, fluxes,
                limb-darkening etc.


        Plot the data scaled to the model.

        Keywords (all optional):
            phot_fmt: *string* ('mag', 'flux')
                Whether to plot the data in magnitudes or in flux. Default
                is 'mag'.

            data_ref: *int* or *MulensData*
                If data_ref is not specified, uses :py:obj:`~data_ref`.

            show_errorbars: *boolean* or *None*
                Do you want errorbars to be shown for all datasets?
                Default is *None*, which means the option is taken from each
                dataset plotting properties (for which default is *True*).
                If *True*, then data are plotted using matplotlib.errorbar().
                If *False*, then data are plotted using matplotlib.scatter().

            show_bad: *boolean* or *None*
                Do you want data marked as bad to be shown?
                Default is *None*, which means the option is taken from each
                dataset plotting properties (for which default is *False*).
                If bad data are shown, then they are plotted with 'x' marker.

            subtract_2450000, subtract_2460000: *boolean*
                If True, subtracts 2450000 or 2460000 from the time
                axis to get more human-scale numbers. If using, make
                sure to also set the same settings for all other
                plotting calls (e.g. :py:func:`plot_lc()`).

            ``**kwargs``:
                Passed to matplotlib plotting functions. Contrary to
                previous behavior, ``**kwargs`` are no longer remembered.


        Plot the residuals (in magnitudes) to the model.

        Keywords:
            For explanation of keywords, see doctrings in
            :py:func:`plot_data()`. Note different order of keywords.


        Plot the trajectory of the source. See
        :py:func:`MulensModel.model.Model.plot_trajectory()` for details.


        Plot source positions for all linked datasets.
        See :py:func:`MulensModel.model.Model.plot_source()` for
        details.

        Note: plots all points in datasets (including ones flagged as bad)
        using the same marker.


        If the user has not specified a color for a dataset, assign
        one.


        Calculate chi^2 gradient (also called Jacobian), i.e.,
        :math:`d chi^2/d parameter`.

        Parameters :
            parameters: *str* or *list*, required
                Parameters with respect to which gradient is calculated.
                Currently accepted parameters are: ``t_0``, ``u_0``, ``t_eff``,
                ``t_E``, ``pi_E_N``, and ``pi_E_E``. The parameters for
                which you request gradient must be defined in py:attr:`~model`.

        Returns :
            gradient: *float* or *np.ndarray*
                chi^2 gradient

        NOTE: Because this is not a 'get' function, it ASSUMES you have ALREADY
        fit for the fluxes, e.g. by calling get_chi2().


Fit for the optimal fluxes for each dataset (and its chi2)


calculate sum of the data


Set the coordinates as a SkyCoord object


        a *list* of :py:class:`~MulensModel.mulensdata.MulensData`
        instances.


        sets the value of self._datasets
        can be called by __init__ or @datasets.setter
        passes datasets to property self._model


        Reference data set for scaling the model fluxes to (for
        plotting). May be set as a
        :py:class:`~MulensModel.mulensdata.MulensData` object or an
        index (*int*). Default is the first data set.

        Returns :
            index (*int*) of the relevant dataset.


Set reference dataset. Not covered by unit tests.


        *float*

        Chi^2 value. Note this is a static property. It is only updated when
        :py:func:`~fit_fluxes()` or :py:func:`~get_chi2()` is run. So, if you
        change one of the settings be sure to run one of those functions to
        update the chi2.


        Return previously calculated chi^2 gradient (also called Jacobian),
        i.e., :math:`d chi^2/d parameter`. See :py:func:`~get_chi2_gradient()`
        and :py:func:`~calculate_chi2_gradient()`.

        Returns :
            gradient: *float* or *np.ndarray*
                chi^2 gradient. Will return None if the chi2 gradient was not
                previously calculated using one of the functions mentioned
                above.


        *list* of :py:class:`~MulensModel.fitdata.FitData` objects

        There is one :py:class:`~MulensModel.fitdata.FitData` object for
        each dataset containing the information for fitting the model to
        that dataset, e.g. fitted fluxes, chi2 (for that dataset).


        *list*

        An array giving the fitted source and blend flux(es) for each dataset.


        *list*

        An array giving the fitted source flux(es) for each dataset.


        *list*

        An array giving the fitted blend flux for each dataset.


        *str*

        Function used for adding chi^2 contributions. Can be either
        'numpy.sum' (default value) or 'math.fsum'.
        The latter is slightly slower and more accurate,
        which may be important for large datasets.


        :py:class:`~MulensModel.trajectory.Trajectory`

        Trajectory for which magnification is calculated.


        *np.ndarray*

        Magnification for each epoch.


Calculate dA/du assuming PSPL.


        *np.ndarray*

        Point-source--point-lens magnification for each epoch.


        *np.ndarray*

        Magnitude of lens-source separation for each epoch.


        *np.ndarray*

        Square of the magnitude of lens-source separation for each epoch.


        calculate B_0(z) function defined in:
        Gould A. 1994 ApJ 421L, 71 "Proper motions of MACHOs"
        https://ui.adsabs.harvard.edu/abs/1994ApJ...421L..71G/abstract
        Yoo J. et al. 2004 ApJ 603, 139 "OGLE-2003-BLG-262: Finite-Source
        Effects from a Point-Mass Lens"
        https://ui.adsabs.harvard.edu/abs/2004ApJ...603..139Y/abstract


        *np.ndarray*

        Magnitude of lens-source separation scaled to rho for each epoch
        (i.e., z = u/rho).


        *np.ndarray*

        The value of the B_0(z) function for each epoch.


        *np.ndarray*

        Derivative of the B_0(z) function for each epoch.


        calculate B_1(z) function defined in:

        Gould A. 1994 ApJ 421L, 71 "Proper motions of MACHOs"
        https://ui.adsabs.harvard.edu/abs/1994ApJ...421L..71G/abstract

        Yoo J. et al. 2004 ApJ 603, 139 "OGLE-2003-BLG-262: Finite-Source Effects from a Point-Mass Lens"
        https://ui.adsabs.harvard.edu/abs/2004ApJ...603..139Y/abstract


        *np.ndarray*

        Value of the B_1(z) function for each epoch.


        *np.ndarray*

        Derivative of the B_1(z) function for each epoch.


        *float*

        Limb-darkening gamma coefficient.


Get point-lens finite-source magnification without LD.


        Get value of elliptic integral of the first kind.
        Use interpolation if possible.


        Get value of elliptic integral of the second kind.
        Use interpolation if possible.


        Get value of elliptic integral of the third kind.
        Use interpolation if possible.


        Get point-lens finite-source magnification with LD using
        Witt & Mao 1994 approach and equations 16-19 from Bozza et al. 2018.


        Calculates Equation 4 of Lee et al. 2009.
        The u variable is float, theta is np.ndarray.


        Calculates Equation 5 of Lee et al. 2009.
        The u variable is float, theta is np.ndarray.


Calculates equation in text between Eq. 7 and 8 from Lee et al. 2009.


Calculates Equation 7 from Lee et al. 2009 in case u > rho.


Calculates Equation 7 from Lee et al. 2009 in case u < rho.


        Calculates Equation 13 from Lee et al. 2009.

        Accuracy of these calculations is on the order of 1e-4


        Integrand in Equation 13 in Lee et al. 2009.

        u_ and theta_ are np.ndarray, other parameters are scalars.
        theta_ is in fact cos(theta_) here


        Update .xallarap_reference_position for each source parameters

        Note: below we're calling private function and set private
        properties NOT of self, but self._source_X_parameters,
        which both are of the same type as self.


        Get position at t_0_xi from xallarap Orbit object.

        Note: this function is called in 2 different ways:
        - directly, i.e., self._get_xallarap_orbit(), and
        - indirectly, i.e., self._source_1_parameters._get_xallarap_orbit().


Split ABC_DEF_n into ABC_DEF (str) and n (int). For parameters like t_0 or rho, n is None.


sets self._type property, which indicates what type of a model we have


Check if self._type values make sense


Check that the user hasn't over-defined the ModelParameters.


        Check if Cassan08 is used and if so, then make sure that
        the trajectory is rectilinear and there is only one source.


        Divide an input dict into each source separately.
        Some of the parameters are copied to both dicts.


        For xallarap model with 2 sources, the orbit of the second source
        must have 2 parameters changed.
        Functions starts with tests of input


prepare all the standard parameters to be printed


get all the keys that will be printed


define formats that define how to print the numbers


define the default order of parameters


        Get full name of the parameter and its value (float)
        to be used by __rerp__().


Extract formats to be used by __repr__().


        make sure that there is no conflict between t_0 and t_0_1 etc.
        Also make sure that t_0 and u_0 are defined for all sources.


make sure that there is no conflict between t_0 and t_0_1 etc.


Check for additional source parameters with xallarap (bad).


Also make sure that t_0 and u_0 are defined for all sources.


Check if parameters have been set for sources that don't exist.


Here we check parameters for non-Cassan08 parameterization.


Make sure that t_0 and u_0 are defined.


Make sure that t_E is defined and that it's not overdefined.


Here we check parallax parameters for non-Cassan08 parameterization.


        Make sure that alpha is defined if shear_G is defined,
        but not if only convergence_K is defined.


Here we check binary lens parameters for non-Cassan08 parameterization.


        If xallarap parameters are defined,
        then make sure there are all required parameters


        check if orbit is properly defined; prefix is added to
        checked orbit parameters


        Check parameters defined for Cassan 2008 parameterization.
        Currently, only static models are accepted.


        Prevent user from setting negative (unphysical) values for
        t_E, t_star, rho etc. Shear_G should be complex.

        Also, check that all values are scalars.


check if parameter values make sense and remember the copy of the dict


        For multi-source models, update the values for all sources.
        Note that pi_E_N and pi_E_E are changed separately.


        Sets self._uniform_caustic if that is required.
        Also resets self._standard_parameters.


        Calculate these parameters:
        t_0 u_0 t_E alpha
        based on:
        x_caustic_in x_caustic_out t_caustic_in t_caustic_out
        using transformation that depends on:
        s q


Calculates s_z or ds_z_dt when the other is given.


        *float*

        The time of minimum projected separation between the source
        and the lens center of mass.


        *float*

        The minimum projected separation between the source
        and the lens center of mass.


        *float*

        t_star = rho * t_E = source radius crossing time in days


        *float*

        t_eff = u_0 * t_E = effective timescale in days


        *float*

        The Einstein timescale in days.


        *float*

        source size as a fraction of the Einstein radius


        *float*

        The angle of the source trajectory relative to the binary lens
        axis (or primary-secondary axis). Measured counterclockwise,
        i.e., according to convention advocated by
        `Skowron et al. 2011 (ApJ, 738, 87) <https://ui.adsabs.harvard.edu/abs/2011ApJ...738...87S/abstract>`_,
        but shifted by 180 deg.


        *float*

        mass ratio of the two lens components. Only 2 bodies allowed.


        *float*

        Convergence of external mass sheet.


        *complex*

        Shear of external mass sheet.


        *float*

        separation of the two lens components relative to Einstein ring size


        *float*

        The North component of the microlensing parallax vector.


        *float*

        The East component of the microlensing parallax vector.


        Not defined.

        It was used in previous versions. Use :py:attr:`~pi_E_N` and :py:attr:`~pi_E_E` instead.


        *float*

        The reference time for the calculation of parallax. If not set
        explicitly, then it is assumed t_0_par = t_0. If there are multiple sources,
        t_0_1 is used.

        Note that this is a reference value and not the fitting parameter.
        It is best to fix it at the begin of calculations.


        *float*

        The magnitude of the microlensing parallax vector.


        *float*

        Curvelinear coordinate (in `Cassan (2008) parameterization
        <https://ui.adsabs.harvard.edu/abs/2008A%26A...491..587C/abstract>`_)
        of caustic entrance for a static binary lens model. See
        :py:class:`~MulensModel.uniformcausticsampling.UniformCausticSampling`.


        *float*

        Curvelinear coordinate (in `Cassan (2008) parameterization
        <https://ui.adsabs.harvard.edu/abs/2008A%26A...491..587C/abstract>`_)
        of caustic exit for a static binary lens model. See
        :py:class:`~MulensModel.uniformcausticsampling.UniformCausticSampling`.


        *float*

        Epoch of caustic entrance for a static binary lens model in
        `Cassan (2008) parameterization
        <https://ui.adsabs.harvard.edu/abs/2008A%26A...491..587C/abstract>`_)
        See
        :py:class:`~MulensModel.uniformcausticsampling.UniformCausticSampling`.


        *float*

        Epoch of caustic exit for a static binary lens model in
        `Cassan (2008) parameterization
        <https://ui.adsabs.harvard.edu/abs/2008A%26A...491..587C/abstract>`_)
        See
        :py:class:`~MulensModel.uniformcausticsampling.UniformCausticSampling`.


        *float*

        Change rate of separation :py:attr:`~s` in 1/year.


        *float*

        Change rate of angle :py:attr:`~alpha` in deg/year.


        *float*

        instantaneous position in the direction perpendicular to the plane
        of the sky at time t_0_kep.


        *float*

        Change rate of separation :py:attr:`~s_z` in 1/year.


        *float*

        The reference time for the calculation of lens orbital motion.
        If not set explicitly, then it is assumed t_0_kep = t_0 (or t_0_1 for multi-source models).

        Note that this is a reference value and not the fitting parameter.
        It is best to fix it at the begin of calculations.


        *float*

        Orbital period of the source system (xallarap) in days.


        *float*

        Semi-major axis of the source orbit (xallarap) in the theta_E units.


        *float*

        The longitude of the ascending node of the xallarap orbit, i.e.,
        the angle from relative lens-source proper motion direction
        to the ascending node direction.
        The units are degrees.


        *float*

        The inclination of the xallarap orbit, i.e.,
        the angle between source-orbit plane and the sky plane.
        The units are degrees.


        *float*

        The argument of latitude for the xallarap orbit at :py:attr:`~t_0_xi`.
        The argument of latitude is a sum of the true anomaly and
        the argument of periapsis. In standard notation: u = nu + omega.
        This parameter is internally used to calculate perihelion passage
        (T_0 in standard notation).
        The units are degrees.


        *float*

        The eccentricity of the xallarap orbit. Has to be in [0, 1) range.


        *float*

        The argument of periapsis of the xallarap orbit, i.e., the angle
        between the ascending node and periapsis measured in
        the direction of motion.
        The units are degrees.


        *float*

        Reference epoch for xallarap orbit.
        If not provided, then it defaults to :py:attr:`~t_0`.


        *float*

        The mass ratio of the second and the first source.
        This is value must be positive and can be > 1.
        Defined only for xallarap binary-source models because it does not
        affect the magnification for binary-source models without xallarap.


        *np.ndarray* of shape (2, 1)

        The position of the first source at :py:attr:`~t_0_xi` relative to
        the source center of mass. It is a 2D vector that is subtracted from
        the source position along the orbit in order to calculate the shift
        caused by xallarap.


        *float*

        The time of minimum projected separation between the source no. 1
        and the lens center of mass.


        *float*

        The time of minimum projected separation between the source no. 2
        and the lens center of mass.


        *float*

        The minimum projected separation between the source no. 1
        and the lens center of mass.


        *float*

        The minimum projected separation between the source no. 2
        and the lens center of mass.


        *float*

        source no. 1 size as a fraction of the Einstein radius


        *float*

        source no. 2 size as a fraction of the Einstein radius


        *float*

        Parallel component of instantaneous velocity of the secondary
        relative to the primary in 1/year.
        It is parallel to the primary-secondary axis.
        Equals :py:attr:`~ds_dt`/:py:attr:`~s`. Cannot be set.


        *float*

        Perpendicular component of instantaneous velocity of the secondary
        relative to the primary. It is perpendicular to the primary-secondary
        axis. It has sign opposite to :py:attr:`~dalpha_dt`
        and is in rad/yr, not deg/yr. Cannot be set.


        *float*

        Perpendicular component of instantaneous velocity of the secondary
        relative to the primary in 1/yr. It is perpendicular to the plane of the sky
        at time :py:attr:`~t_0_kep`. Equals :py:attr:`~ds_z_dt`/:py:attr:`~s`. Cannot be set.


        *float*

        Instantaneous velocity of the secondary relative to the primary in 1/year. Cannot be set.


Set parameters of the lens keplerian orbit i.e. self._lens_keplerian.


        *float*

        Semi-major axis of the binary lens orbit in units of theta_E.


        *float*

        Orbital period of the binary lens orbit in years.


        *float*

        Inclination of the binary lens orbit in degrees.


        *float*

        Longitude of ascending node of the binary lens orbit in degrees.


        *float*

        Argument of latitude of the binary lens orbit in degrees.


        Checks if model has finite source. For binary source models it checks
        if either of the sources is finite.

        Returns:
            is_finite_source: *boolean*
                *True* if at least one source has finite size.


        Checks if model is static, i.e., orbital motion parameters are not set.

        Returns :
            is_static: *boolean*
                *True* if :py:attr:`~dalpha_dt` or :py:attr:`~ds_dt` are set.


        Checks if model includes keplerian orbital motion of the lenses,
        which can be either circular or elliptical.

        Returns :
            is_keplerian: *boolean*
                *True* if :py:attr:`~s_z` or :py:attr:`~ds_z_dt` are set.


        *int*

        Number of objects in the lens system.


        *int*

        Number of luminous sources.
        It can be be 1 for a xallarap model.


        *bool*

        Whether an external mass sheet is included in the model


        *bool*

        Whether an external mass sheet is included in the
        model with non-zero shear


        *bool*

        Whether the parameters include the xallarap or not.


        :py:class:`~MulensModel.modelparameters.ModelParameters`

        Parameters of source 1 in multi-source model.

        **Do not change returned values.** To change
        parameters of the source 1, simply change the parameters of double
        source instance.


        :py:class:`~MulensModel.modelparameters.ModelParameters`

        Parameters of source 2 in multi-source model.

        **Do not change returned values.** To change
        parameters of the source 1, simply change the parameters of double
        source instance.


        :py:class:`~MulensModel.uniformcausticsampling.UniformCausticSampling`

        An instance of the class
        :py:class:`~MulensModel.uniformcausticsampling.UniformCausticSampling`
        that is used to calculate standard parameters based on
        the curvelinear coordinates.
        The main usage is access to the *jacobian()* function.
        In most cases, you do not need to access this property directly.


        Give parameters as a dict.

        Returns :
            dictionary: *dict*
                The dictionary of model parameters.


        Prepare internal variables:
            self._phi - gives all phi values used for integration
            self._d_phi - step between adjacent phi values


Find inflection points in give tabulated function.


        Apply lens equation in complex coordinates and
        shift to center of mass coordinates.


returns element of array that is closest to value


Calculate a point on critical curve - see eq. 6 in Cassan 2008.


almost the same as eq. 11 from Cassan (2008)


check if caustic crosses the line defined by 2 points


        Main integration for Cassan (2008) parameterization.
        It sets internal variables:
        - self._z_all
        - self._sum_1
        - self._sum_2
        - self._z_sum_1
        - self._z_sum_2
        - self._z_index_sum_1
        - self._z_index_sum_2


        Find inflection points of s(phi). In the case of close configuration
        also correct the phase of planetary caustic - Do we do it in current
        version XXX ??? - yes because of self._which_caustic


Get uniform sampling for a single caustic.


        Evaluates Eq. 23 from Cassan et al. (2010) with condition under Eq. 27.

        Parameters :
            x_caustic_in: *float*
                Point of caustic entrance.
            x_caustic_out: *float*
                Point of caustic exit.

        Returns :
            jacobian: *float*
                Value of Jacobian. Returns *0.* if trajectory does not exist.


divide n_points into caustics


        Check if given (x_caustic_in, x_caustic_out) define an existing
        trajectory. An obvious case, when they don't is when both caustic
        points are on the same fold, but other cases exists.

        Parameters :
            x_caustic_in: *float*
                Coordinate of putative caustic entrance.

            x_caustic_out: *float*
                Coordinate of putative caustic exit.

        Returns :
            check: *bool*
                *True* if input defines a trajectory, *False* if it does not.


        Check if given parameters define real trajectory.

        Returns a list with first element being True/False


        Normalizes input to 0-1 range but in special way,
        which considers the middle point.


        Calculate caustic position corresponding to given x_caustic.

        Keywords :
            x_caustic: *float*
                Curvelinear coordinate of the point considered.
                Has to be in 0-1 range.

        Returns :
            point: *numpy.complex128*
                Caustic point in complex coordinates.


        Indicates on which caustic given point is.

        Keywords :
            x_caustic: *float*
                Curvelinear coordinate to be checked

        Returns :
            i_caustic: *int*
                Number indicating the caustic:

                ``1`` - central caustic,

                ``2`` - planetary caustic; for close configuration it is
                the lower of the two planetary caustics,

                ``3`` - upper planetary caustic.


        *int*

        Number of caustics: *1* for resonant topology, *2* for wide topology,
        or *3* for close topology.


        *float*

        Mass ratio.


        Try to check if RA is outside 0-24 range and raise a warning if that
        is the case. No warning would be given if the user provided RA of,
        e.g., 5.123 and assumed degrees, but has not explicitly stated that.


        Validate input for coordinates, checking if format is allowed (ICRS,
        FK4 or FK5) or raising ValueError otherwise. If SkyCoord() instance
        is provided, the frame should be allowed as well.


Calculate North and East directions projected on the plane of the sky.


        *astropy.coordinates.angles.Longitude*

        Galactic longitude. Note that for connivance, the values l >
        180 degrees are represented as 360-l.


        *astropy.coordinates.angles.Latitude*

        Galactic latitude calculated from (RA, Dec)


        *astropy.coordinates.angles.Longitude*

        ecliptic longitude calculated from (RA, Dec)


        *astropy.coordinates.angles.Latitude*

        ecliptic latitude calculated from (RA, Dec)


        *np.array*

        North projected on the plane of the sky.


        *np.array*

        East projected on the plane of the sky.


        Earth velocity at *full_BJD* projected on the plane of sky towards
        given coordinates.

        Parameters :
            full_BJD: *float*
                Epoch for which projected velocity is requested. In most cases
                it is
                :py:attr:`~MulensModel.modelparameters.ModelParameters.t_0_par`

        Returns :
            v_Earth_perp_N: *float*
                North component of Earth's projected velocity in km/s.

            v_Earth_perp_E: *float*
                East component of Earth's projected velocity in km/s.


Check if period and semimajor axis make physical sense.


        Check if arguments properly define epoch of
        the periapsis (eccentric orbit) or
        the ascending node (circular orbit) passage


Set parameters that are used for circular orbits.


        Get position projected on reference plane,
        but not rotated to the reference coordinate system


Calculate eccentric anomaly (typically indicated by E).


        Calculate mean anomaly, i.e., the one that is linear in time and
        typically indicated by M.


get value normalized to (-pi, pi) range


get value normalized to (0, 2*pi) range


Turn mean anomaly in range (-pi, pi) into eccentric anomaly


        Calculations needed to solve Kepler's equation.
        We use Newton's method.
        The input anomaly is current estimate of eccentric anomaly.


        Calculate ascending node epoch
        (called periapis in general case of eccentric orbits) based on
        the argument_of_latitude (u) at given epoch


        Calculate periapsis epoch (omega) based on
        the argument_of_latitude (u) at given reference epoch


Calculate mean anomaly (M) based on true anomaly (E)


Calculate sin(E) and cos(E) based on true_anomaly (nu)


        Calculate true anomaly for given times.
        The result is in (-pi, pi) range.


Calculate sin(nu) and cos(nu) based on E


        sfit returns: FSPL:
            61 dA/drho
            62 df/dparams, dAdu

        A_US = A_PS(u) * b0(z)
        dAdu_US = dA_PS(u) * b0(z) + A_PS(u) * db0(z)

        dAdu_FS = (damp*(b0-gamma*b1)+amp*(db0-gamma*db1)/rho)
         = dA*b0 - dA*gamma*b1 + A*db0/rho - A*gamma*db1/rho
         = dAdu_US - dA*gamma*b1 - A*gamma*db1/rho


        sfit returns: FSPL:
            61 dA/drho
            62 df/dparams, dAdu

        A_US = A_PS(u) * b0(z)
        dAdu_US = dA_PS(u) * b0(z) + A_PS(u) * db0(z)

        dAdu_FS = (damp*(b0-gamma*b1)+amp*(db0-gamma*db1)/rho)
         = dA*b0 - dA*gamma*b1 + A*db0/rho - A*gamma*db1/rho
         = dAdu_US - dA*gamma*b1 - A*gamma*db1/rho

        df_FS = fs * (dAdu_US - dA*gamma*b1 - A*gamma*db1/rho)


prepare a list of epochs based on parameters provided


Prepare ModelParameters object for testing keplerian orbit calculations


Coordinates of event


prepare fake data for binary source model


Generate two perfect datasets with different source and blend fluxes


generate a single dataset without noise


Generate perfect datasets with different source and blend fluxes


generate perfect data for a given set of properties


create data in two bands for each fake observatory


Return a list of fitted fluxes for all datasets


Prepare PointLensWithShear and Trajectory instances for tests


    For given Event instance event, check if .ra, .model.ra,
    .datasets[0].ra etc. are equal to ra and dec


returns a model, time array, and magnification


    returns a binary source model, time array, and the magnification of
    both sources


pass in f_mod and t, returns a MulensData


Create Model instance with parallax


        create a fake, perfect dataset, but with a few known outliers and
        errorbar variations.


Initialize a model to match sfit parameters


Read in datasets for test


Set up fits for each individual dataset.


        *astropy.Quantity*

        The distance to the source. May be set as a *float*.
        The distance should either be given in pc, or if no unit is
        given, the value is assumed to be kpc (*u.kpc*).


        *astropy.Quantity*

        The parallax to the source in millarcseconds. May be set as a
        *float*. If no units are specified, assumes milliarcseconds (*u.mas*).


        *astropy.Quantity*

        Angular radius of the source. May be set as a *float*. If
        units are not specified, assumed to be microarcseconds (*u.mas*).


        [*float, list, numpy.ndarray*]

        mass ratio for companions relative to the primary

        Array of mass ratios defined relative to the primary
        (m_i/m_1). Size is number of components -1. Set as a list,
        np.ndarray, or single value.

        Note: if :py:obj:`total_mass` is defined before q, it is
        assumed this is the mass of the primary. If you want this to
        actually be the total mass, define it after defining q.


        [*float, list, numpy.ndarray*]

        Separation between the components of the lens as a fraction of
        the Einstein ring. A np.ndarray or single value.

        Definitions for more than 2 lens bodies TBD


        *astropy.Quantity*

        The total mass of the lens (sum of all components). An
        astropy.Quantity with mass units. If set as a *float*, units
        are assumed to be solMass.


        *astropy.Quantity*

        The mass of a point lens --> total mass. An astropy.Quantity
        with mass units. May be set as a float (in which case solMass
        is assumed).


        *astropy.Quantity*

        The mass of the primary. Defined as total_mass *
        epsilon[0]. An *astropy.Quantity* with mass units. If set as a
        *float*, units are assumed to be solMass.


        *astropy.Quantity*

        The mass of the secondary. Defined as total_mass *
        epsilon[1]. An *astropy.Quantity* with mass units. If set as a
        *float*, units are assumed to be solMass.

        Note that if total_mass is defined before mass_2, and there is
        no epsilon corresponding to mass_2, mass_2 is added to the
        total_mass.


        *astropy.Quantity*

        The mass of the tertiary. Defined as total_mass * epsilon[2].
        An *astropy.Quantity* with mass units. If set as a *float*,
        units are assumed to be solMass.

        Note that if total_mass is defined before mass_3, and there is
        no epsilon corresponding to mass_3, mass_3 is added to the total_mass.


        *int*, read-only

        number of masses in the system.


        Updates total_mass and epsilon array if the mass of one of the
        components is changed. e.g. mass_2 is changed from 1 MJup to 2
        MJup.


        Initializes total_mass and epsilon if only one mass componenet
        is defined (i.e. a point lens).


        Private function: Updates the total_mass and adds a component
        to the epsilon array if masses are added
        sequentially. e.g. the lens is defined by defining mass_1 and
        mass_2.


        *astropy.Quantity*

        The distance to the lens.

        May be set as a *float*. If no unit is given, the value is
        assumed to be kpc.


        *astropy.Quantity*

        The parallax to the lens in milliarcseconds. May be set as a
        *float*, in which case units are assumed to be
        milliarcseconds.


        *astropy.Quantity*

        Projected separation between the components of the lens in
        AU. An *astropy.Quantity* with distance units. If set as *float*
        (without units), AU is assumed.


A :py:class:`~MulensModel.caustics.Caustics` object, read-only


        A function to plot the x,y coordinates (scaled to the
        Einstein ring) of the caustics. `Pyplot scatter`_ is used for
        plotting. See :py:func:`MulensModel.caustics.Caustics.plot()`.

        Parameters :
            n_points: *int*
                Number of points be plotted.

            ``**kwargs``:
                Keyword arguments passed to `Pyplot scatter`

        .. _Pyplot scatter:
           https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.scatter


        A :py:class:`~MulensModel.mulensobjects.lens.Lens` object.
        Physical properties of the lens. Note: lens mass must be in
        solMasses.


        :py:class:`~MulensModel.mulensobjects.source.Source` object.
        Physical properties of the source.


        *astropy.Quantity*

        Relative proper motion between the source and lens
        stars. If set as a *float*, units are assumed to be mas/yr.


        *astropy.Quantity*

        The Einstein crossing time (in days). If set as a *float*,
        assumes units are in days.


        *astropy.Quantity*, read-only

        The source-lens relative parallax in milliarcseconds.


        *float*, read-only

        The Einstein ring radius. It's equal to pi_rel / theta_E.
        Dimensionless.


        *astropy.Quantity*, read-only

        The angular Einstein Radius in milliarcseconds.


        *astropy.Quantity*, read-only

        The physical size of the Einstein Radius in the Lens plane (in AU).


        *astropy.Quantity*, read-only

        The physical size of the Einstein Radius projected onto the
        Observer plane (in AU).


        Plot the magnification curve for the lens. u_0 must always be
        specified. If the lens has more than one body, alpha must also
        be specified.

        Parameters :
            u_0: *float*
                Impact parameter between the source and the lens (as a
                fraction of the Einstein ring)

            alpha: *astropy.Quantity*, *float*
                If *float* then degrees are assumed as a unit.
                See :py:obj:`MulensModel.modelparameters.ModelParameters.alpha`

            ``**kwargs``:
                See :py:func:`MulensModel.model.Model.plot_magnification()`


        Plot the caustics structure using `Pyplot scatter`_. See
        :py:func:`MulensModel.caustics.Caustics.plot()`

        Parameters :
            n_points: *int*
                Number of points be plotted.

            ``**kwargs``:
                Keyword arguments passed to `Pyplot scatter`

        .. _Pyplot scatter:
           https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.scatter


priors - we only reject obviously wrong models


combines likelihood and priors


    Likelihood function. The values of *parameters_to_fit* are in *theta*.
    MulensModel Event class instance *event* gives event for which
    calculations will be done. Boolean *print_models* controls if
    all models are printed.


    Prior. Check if *theta* values for *parameters_to_fit* are within ranges
    defined by *ln_prior.min* and *ln_prior.max*.


Log probability of the model - combines ln_prior() and ln_like().


    Generate *n* vectors of values of *parameters* according to distributions
    specified in *starting*.


combines likelihood and priors; returns ln(prob) and a list of fluxes


    change the parameters so that we can easily print median and uncertainties
    (based on percentiles)


Generate sorted array simulating survey + follow-up time vector.


Generate simulated dataset assuming binary source model.


    for given event set attributes from parameters_to_fit (list of
    str) to values from theta list


    Calculate chi^2 gradient (also called Jacobian).

    Note: this implementation is robust but possibly inefficient. If
    chi2_fun() is ALWAYS called before jacobian with the same parameters,
    there is no need to set the parameters in event.model; also,
    event.calculate_chi2_gradient() can be used instead (which avoids fitting
    for the fluxes twice).


    Read names of photometry files. For each file read also format:
    'mag' or 'flux'.


    Read basic parameters of the microlensing models: methods used for
    calculating magnification and coordinates.


    Read info on starting parameter values. The distributions can be
    'gauss', 'uniform', or 'log-uniform'.


Read parameters that will be kept fixed during fitting process.


Read minimum and maximum values of parameters used for prior.


Read EMCEE parameters, i.e., number of walkers, steps, and burn-in steps.


Read other options.


return chi^2 for a parameters theta


    Simulate and save light curve.

    Parameters :
        parameters: *dict*
            Parameters of the model - keys are in MulensModel format, e.g.,
            't_0', 'u_0', 't_E' etc.

        time_settings: *dict*
            Sets properties of time vector. It requires key `type`, which can
            have one of two values:
            - `random` (requires `n_epochs`, `t_start`, and `t_stop`) or
            - `evenly spaced` (settings passed to `Model.set_times()`).

        file_out: *str*
            Name of the file to be saved.

        coords: *str*
            Event coordinates for parallax calculations, e.g.,
            "17:34:51.15 -30:29:28.27".

        methods: *list*
            Define methods used to calculate magnification. The format is
            the same as MulensModel.Model.set_magnification_methods().

        flux_source: *float*
            Flux of source.

        flux_blending: *float*
            Blending flux.

        relative_uncertainty: *float*
            Relative uncertainty of the simulated data (this is close to
            sigma in magnitudes).

        plot: *bool*
            Plot the data and model at the end?

        subtract_2450000: *bool*
            Do you want shorter JD values?


    Chi2 function. Changes values of the parameters and recalculates chi2.

    event = a MulensModel.Event
    parameters_to_fit = list of names of parameters to be changed
    theta = values of the corresponding parameters


    Fit an "event" with "parameters_to_fit" as free parameters.

    event = a MulensModel event
    parameters_to_fit = list of parameters to fit


    Define a Model using the gridpoint information + the PSPL parameters.

    index = index of the grid point for which to generate the model


    Fit model using EMCEE and print results.
    Arguments:
        parameters_to_fit - list of parameters
        starting_params - dict that specifies values of these parameters
        sigmas - list of sigma values used to find starting values
        ln_prob - function returning logarithm of probability
        event - MulensModel.Event instance
        n_walkers - number of walkers in EMCEE
        n_steps - number of steps per walker
        n_burn - number of steps considered as burn-in ( < n_steps)


    Calculate chi2 for given values of parameters

    Keywords :
        theta: *np.ndarray*
            Vector of parameter values, e.g.,
            `np.array([5380., 0.5, 20.])`.

        parameters_to_fit: *list* of *str*
            List of names of parameters corresponding to theta, e.g.,
            `['t_0', 'u_0', 't_E']`.

        event: *MulensModel.Event*
            Event which has datasets for which chi2 will be calculated.

    Returns :
        chi2: *float*
            Chi2 value for given model parameters.


Check if MulensModel is new enough


        Check if input parameters indicate run_fit() or plot_best_model() will
        be run.


        Make sure that there aren't too many parameters specified for:
        self._task == 'plot'


set some default parameters


        Method to be sub-classed if user defines their own parameters (microlensing or other).
        If you use different microlensing parameters, then define self._user_parameters and
        self._latex_conversion_user.
        If you add non-microlensing parameters (e.g., source distance) then define self._other_parameters and
        self._latex_conversion_other.


guess what is the fitting method based on parameters provided


        Guess fit_method between MultiNest or UltraNest, based on the
        provided fitting_parameters.


Check if fitting method is consistent with the settings.


        Check if starting parameters are read from file or
        will be drawn from distributions specified.


Find what are the fitted parameters. It will be sorted later.


Make sure that a list of parameters is provided


check if all the required packages are imported


        Run the fit, print the output, and make the plots.

        This function does not accept any parameters. All the settings
        are passed via __init__().


        Plot the best model.

        The parameters names and their values are taken from __init__()
        keyword ``model``, which is a *dict* and has this information in
        ``model['parameters']`` and ``model['values']``.


Check if parameters of plots make sense


Check if parameters of best model make sense


set time range for best model or triangle plots


Assuming magnitude range is for best model is provided, parse it and save.


Check if there is no problem with interactive best plot


Check if there is no problem with best model title


Check if "best model" -> "add models" are of proper type i.e., list of dicts


        Check if parameters for second Y scale make sense.
        This function assumes that the second Y scale will be plotted.


Check if parameters of trajectory plot make sense


Check if there is no problem with interactive trajectory plot


Check if parameters of triangle plot make sense


Check if 'shift t_0' is provided and parse it


Check if parameters of trace plot make sense


        Check parameters of the MulensModel.Model provided by the user
        directly.


Check if there aren't any other inconsistencies between settings


check if odd elements are floats and parse them


parse information on other output


parse information on "other output" -> "models"


parse information on "other output" -> "yaml output"


parse information on "other output" -> "residuals"


        Check if provided names of output files with residuals make sense.
        We do not check here if the number of files provided is the same
        as the number of input datasets.


construct a list of MulensModel.MulensData objects


Construct a single dataset and possibly rescale uncertainties in it.


Read the bad flags from photometry_files['bad'] in yaml file


Check if the provided bad flags are in range of dataset time vector


When bad flags sets from the file, print the file name


Setting bad flags for dataset base on argument photometry_files['bad'] in yaml file


        Check if there aren't too many parameters.
        Standard check (e.g. if t_0 is defined) are done in mm.Model().


        Order input parameters in some logical way.
        This is useful to make sure the order of printed parameters
        is always the same.


change self._fit_parameters into latex parameters


        run some checks on self._fitting_parameters to make sure that
        the fit can be run


make sure EMCEE fitting parameters are properly defined


        Check if required parameters are provided and there aren't parameters
        that shouldn't be defined.


        Check if the settings have right type.
        For floats we accept ints as well.


Parse information about posterior file for EMCEE fitting.


Guess how many walkers (and hence starting values) there will be. EMCEE fitting only.


make sure MultiNest fitting parameters are properly defined


        For each key in keys_mapping (*dict*) check if it is in
        source (*dict*). If it is, then set
        target[keys_mapping[key]] to source[key].


        Check if output files exist and warn about overwriting them.

        If they directory doesn't exist then raise error.


Make sure UltraNest fitting parameters are properly defined


        Checks if the path to `log directory` exists and is a directory,
        and also if the number of `derived parameter names` matches the
        number of derived fluxes.


Set minimum and maximum values of the prior space


        Parse min and max values of parameters so that they're properly
        indexed.


change dict that has str as key to index as key


Set prior limits and transformation constants (from unit cube to MM parameters).


Parse the fitting constraints that are not simple limits on parameters


Run checks on self._fit_constraints


Validate the keys in the provided fit_constraints.


Set default fitting constraints if none are provided.


Check for conflicts among 2 source flux ratio constraints.


Check for conflicts among 2 source flux size relation constraints.


Check if fitted model is a binary source model


Check for conflicts among flux or color constraints.


Process each constraint fit_constraints.


Check if soft fit constraint on fluxes are correctly defined.


Check if fit constraint on flux ratios are correctly defined.


Check if fit constraint on flux-size relation of 2 sources is correctly defined.


For a list with datasets labels return list with theirs indexes


Get settings of fit constraint on color.


Get settings of fit constraint on flux ratio of 2 sources.


Check if the labels of datasets are unique.


Check if priors in fit constraint are correctly defined.


Parse constraints on what is done with posterior.


        Returns the index of a dataset with a specific label.
        Parameters :
            label: *str* ,*int*
              Label of the dataset defined by
              MulensData.plot_properties['label'],
              or name of the data file if label is not specified,
              or a sequential index of the dataset.

        RP NOTE: the above docstring seems wrong, i.e., int input is not parsed properly.

        Returns :
          index: *int*
          Sequential index of the dataset from [0,1,...,n_datasets-1]


read data that specify t_E prior and parse them appropriately


        Read the starting parameters from file or
        change the format of provided information.


Read starting parameters from a file.


        replace self._starting_parameters with dict that has values
        [*str*, *float*, ...]
        and make basic checks


Check if fixed_parameters make sense


Set internal MulensModel instances: Model and Event


find out how many flux parameters there are


        Generate parameters *dict* according to provided starting and fixed
        parameters.


        Method to be sub-classed if user defines their own microlensing parameters.
        It takes a dict as input and returns a dict.


get sample values of parameters for EMCEE - only to make mm.Model


        Provide example parameters that will be used to initialize
        MM.Model and MM.Event. Sets of parameters are already read,
        so we just take 0-th set.


Randomly draw parameters or EMCEE - only to make mm.Model.


        Generate random parameters or read them from file.
        Check if there are enough of them and store.


        Generate a number of starting parameters values.
        It is checked if parameters are within the prior.


        Get n samples from a given distribution (settings[0]).
        The meaning and number of settings[1:] depends on particular
        distribution.


        Check if the set of points provided has at least self._n_walkers
        points inside the prior and save these.


        Check if the set of points provided has at least self._n_walkers
        points inside the prior.


        Log probability of the model - combines _ln_prior(), _ln_like(),
        and constraints which include fluxes.

        NOTE: we're using np.log(), i.e., natural logarithms.


        used to parse output of _ln_prob() in order to make that function
        shorter


        Set microlensing parameters of self._model

        Note that if only plotting functions are called,
        then self._fit_parameters and theta are empty.


        Check if fitting parameters are within the prior.
        Constraints from self._fit_constraints:
         - on blending flux are NOT applied here,
           but in _run_flux_checks_ln_prior(),
         - on t_E are applied here.

        NOTE: we're using np.log(), i.e., natural logarithms.


        Check if current model (that has to be in Cassan08 parameterization)
        has valid trajectory.


Calculate ln(prior) for given value and settings


        Get log prior for t_E of current model. This function is executed
        if there is t_E prior.


print the chi2 and parameters for model provided


        Function that defines calculation of
        ln(probability(other_parameters)).
        The logarithm is to the base of the constant e.

        If you have defined other_parameters, then you have to implement
        child class of UlensModelFit and re-define this function.

        NOTE: your implementation should primarily use *dict*
        `self._other_parameters_dict`, but all MM parameters are already
        set and kept in *MM.Event* instance `self._event`.


Extract all fluxes and return them in a list.


Apply the negative flux sigma magnitude prior.


        Calculates the contribution to the ln_prior
        from specified no negative flux constraints
        Parameters :
            fluxes: *array*
                Array with fluxes of the current model.
            key: *str*
                constrain key.
            inside: *float*
                ln_prior contribution
            index_plus: *int*
                For a single source, index_plus=0;
                for a binary source, index_plus=0 or 1.;
                for blend flux index_plus=self._n_fluxes_per_dataset-1
            inside: *float*
                Evaluated ln_prior contribution


Apply the color constraints.


        Calculates the contribution to the ln_prior
        from specified color constraints
        Parameters :
            fluxes: *array*
                Array with fluxes of the current model.
            key: *str*
                constrain key.
            inside: *float*
                ln_prior contribution
            index_plus: *int*
                For a single source, index_plus=0;
                for a binary source, index_plus=0 or 1.
        Returns :
            inside: *float*
                Evaluated ln_prior contribution


Apply priors of binnary sources


Apply prior on flux ratio of binnary sources


Apply prior on flux-size relation of binnary sources


Sumup prior on flux ratio of binnay sources from dataset in the same passbad


        returns index of flux
        Parameters :
            index_dataset: *int*
                index of data set as define in input yaml

            index_plus: *int*
                For a single source, index_plus=0;
                for a binary source, index_plus=0 or 1.
                for blend flux index_plus=self._n_fluxes_per_dataset-1

        Returns :
            flux_index: *int*


Check if the current model is the best one and save information.


Setup what is needed for fitting after MulensModel.Event is set up.


Setup EMCEE fit


Prepare MultiNest fit


        Prepare UltraNest fit, declaring sampler instance.
        If the names of the derived parameters are not given, the source
        and blending fluxes are assigned, with indexes depending on the
        number of sources (s1, s2) and datasets (_1, _2).


        Transform MultiNest/UltraNest unit cube to microlensing parameters.

        MultiNest: based on SafePrior() in
        https://github.com/JohannesBuchner/PyMultiNest/blob/master/
        pymultinest/solve.py
        UltraNest: based on the above and UltraNest documentation
        https://johannesbuchner.github.io/UltraNest/example-sine-line.html

        NOTE: We call self._ln_like() here (and remember the result)
        because in MultiNest you can add fluxes only in "prior" function,
        not in likelihood function.


        Calculate likelihood and save if its best model.
        This is used for MultiNest fitting.


Call the method that does the fit.


Run MultiNest fit


Run Ultranest fit


        Make the things that are necessary after the fit is done.
        Currently it's just closing the file with all models and
        reads the output files (only for MultiNest).


        We read data from MultiNest output file [root]post_separate.dat.
        It has 2 empty lines then info on a mode at this repeats N_modes
        times. We read it twice - first to get all the data and then to
        find how many samples there are in each mode.


        read and process information about best models
        (i.e., highest likelihood, not maximum a posteriori) for each mode


Call the function that prints and saves results


        Print and save results from EMCEE fitting.

        This version works with EMCEE version 2.X and 3.0.


set self._samples_flat and self._samples for EMCEE


calculate and print median values and +- 1 sigma for given parameters


        take a list of parameters and a list of results and
        return properly formatted string


        calculate and print in yaml format median values and +- 1 sigma
        for given parameters


get strings to be used as names of parameters to be printed


Calculate weighted percentile of the data. Data can be weighted or not.


prepare values to be printed for EMCEE fitting


print best model found


print in yaml format best model found


save 3D cube with posterior to a numpy array


Parse results of MultiNest fitting


Print parameters and fluxes for each mode separately


Print parameters and fluxes for one of many modes


        Print results for MultiNest run in "single mode" setup.
        Note that this is different than
        _parse_results_MultiNest_multimodal_one_mode()


Calculate probabilities of each mode and its uncertainty


Return int which says how to round given value to 2 significant digits


set self._samples_flat and self._samples_flat_weights for MultiNest


prepare flux values to be printed for MultiNest and Ultranest fitting


        Parse results of UltraNest fitting.
        Functions that print and save EMCEE results are also called here.


Write residuals to a file


make plots after fitting: best model, triangle plot, trace plot


Make a triangle plot


Reset matplotlib rcParams to their defaults


Prepare samples that will be plotted on triangle plot


provide list of labels to be used by triangle plot


Save figure or display it


Make a trace plot


plot best model and residuals


prepare kwargs/settings for best plot model


find limits for the best model or trajectory plot


        Find Y axis ranges for plots of data and their residuals.
        Use t_1 and t_2 to limit the data considered.


Plot best models: first ground-based (if needed, hence loop), then satellite ones (if needed).


Plot one additional model


advanced call to plt.legend()


Creates title for the best model plot


        Mark the second (right-hand side) scale for Y axis in
        the best model plot


Creates settings for the second Y axis for the best model plot


Get settings for the second Y axis


Get fluxes and limiting magnification values for the second Y axis


Get optimal values of magnifications and labels


Get minor ticks for magnification axis from matplotlib


Issue warnings for negative flux or bad range of magnificaitons


make and save plot of the best trajectory


plot best model and residuals interactively


Prepares the layout for the interactive plot.


_
        setting kwargs for interactive plot


Creates plotly.graph_objects.Layout object analogues to best model plot


Modifying plotly.graph_objects.Layout object by adding second Y axis


Creates a dictionary with settings for the second Y axis for the interactive plot


Returning time span of datasets


Creates plotly.graph_objects.Scatter objects with model light curve


Generates Plotly Scatter traces for the light-curve satellite models.


Set times for the satellite model whihin the time range of ephemerides


Creates plotly.graph_objects.Scatter object for line y=0 in residuals plot


        Creates plotly.graph_objects.Scatter object for observation points
        per each data set.


Creates plotly.graph_objects.Scatter object with data points form a given data set.


Get dataset properties for interactive plot settings.


Creates a single plotly.graph_objects.Scatter object for the good data points.


Creates single plotly.graph_objects.Scatter object for good or bad data.


Creates a single plotly.graph_objects.Scatter object for the bad data points.


        Creates plotly.graph_objects.Scatter object for residuals points
        per each data set.


Saving interactive figure


make and save interactive best trajectory plot


Prepares the settings of interactive plot for the trajectory.


Adds caustics to the interactive trajectory plot.


Chosing time limits for the trajectory plot


Prepares the layout for the interactive trajectory plot.


Get axis limits for the interactive trajectory plot


Creates imput dictionary for plotly.graph_objects.Layout for the interactive trajectory plot


Creates plotly.graph_objects.Scatter objects with model trajectory


Prepere times grid for the interactive trajectory traces


Creates Plotly Scatter traces for trajectories of satellite models.


Slightly modifies the given color, specified as a matplotlib name or hex code.


        Prepare go.Scatter traces for all source trajectories, including arrows indicating the direction of
        relative proper motion, and the shape of the source if a finite-source model is used.


Creates a Plotly Scatter trace for the trajectory


Extracts rho and t_0 parameters for the sources from the model.


Extracting given paremeter for the sources


Creates Plotly Scatter trace with arrow pointing the direction of relative proper montion of the source


Creates go.Scatter objects with caustics for the interactive trajectory plot


Creates a Plotly Scatter trace for the caustics of the model single and binary lense.


Creates a Plotly Scatter trace for the caustics of the binary lens model.


Create dictionary with shape of the sources in the interactive trajectory plot.


Returns the result of the mm.model.get_trajectory() method, but always as a list.


for a given set of parameters (theta), return the gradient of chi^2


    function to convert from center of magnification to center of mass
    coordinates. Note that this function is for illustration only. It has
    not been tested and may have sign errors.


    for given event set attributes from parameters_to_fit (list of str)
    to values from theta list


        Allow the two source fluxes to be freely fit for some reference
        dataset, but then constrain the fluxes for all other datasets in
        the same bandpass.


prints selected parameters


likelihood function that fixes some fluxes


    Change the 2 provided numbers into a number of microseconds.
    Examples inputs:
        "100", "us"
        "2.76", "ms"
        "3", "s"


simulate PSPL light curve and save to file


Read file and combine it in a single line.


Retrieve the Temperature difference from the EPICA signal


mass balance 'signal'


load climate data to run the Aletsch Glacier simulation


load smb data to run the Aletsch Glacier simulation


Returns a list of actionable modules to then apply the update, initialize, finalize functions on for IGM.


Validates that a module has the required functions to be used in IGM.


    Use wget to download a ZIP file and unzip its contents to a specified folder.

    Args:
    - url (str): The URL of the ZIP file to download.
    - folder_name (str): The name of the folder where the ZIP file's contents will be extracted.


Sets the ice thickness at the border of the domain to zero.


compute spatial 2D gradient of a given field


    upwind computation of the divergence of the flux : d(u h)/dx + d(v h)/dy
    First, u and v are computed on the staggered grid (i.e. cell edges)
    Second, one extend h horizontally by a cell layer on any bords (assuming same value)
    Third, one compute the flux on the staggered grid slecting upwind quantities
    Last, computing the divergence on the staggered grid yields values def on the original grid


    upwind computation of the divergence of the flux : d(u h)/dx + d(v h)/dy
    propose a slope limiter for the upwind scheme with 3 options : godunov, minmod, superbee

    References :
    - Numerical Methods for Engineers, Leif Rune Hellevik, book
      https://folk.ntnu.no/leifh/teaching/tkt4140/._main074.html

    - hydro_examples github page, Michael Zingale, Ian Hawke
     collection of simple python codes that demonstrate some basic techniques used in hydrodynamics codes.
     https://github.com/python-hydro/hydro_examples


This is a 1D interpolation tensorflow implementation


This function adds a postriori import fields such as X, Y, x, dx, ....


    This function originally comes from tensorflow-addon library
    (https://www.tensorflow.org/addons/api_docs/python/tfa/image/interpolate_bilinear)
    but the later was deprecated, therefore we copied the function here to avoid
    being dependent on a deprecated library.

    Similar to Matlab's interp2 function.

    Finds values for query points on a grid using bilinear interpolation.

    Args:
      grid: a 4-D float `Tensor` of shape `[batch, height, width, channels]`.
      query_points: a 3-D float `Tensor` of N points with shape
        `[batch, N, 2]`.
      indexing: whether the query points are specified as row and column (ij),
        or Cartesian coordinates (xy).

    Returns:
      values: a 3-D `Tensor` with shape `[batch, N, channels]`

    Raises:
      ValueError: if the indexing mode is invalid, or if the shape of the
        inputs invalid.


compute spatial 2D gradient on each layer of a given 3D field


compute spatial 2D gradient on each layer of a given 3D field along the x direction


compute spatial 2D gradient on each layer of a given 3D field along the direction y


    Compute the divergence on each layer of a 3D field
    u and v are the vertical average velocity (integral along z from the bedrock to the given layer,
    divided by the height between the bedrock and the layer)


    U and Z are 3D fields
    dX and dY are scalars


    here we define (xpos,ypos) the horiz coordinate of tracked particles
    and rhpos is the relative position in the ice column (scaled bwt 0 and 1)

    here we seed only the accum. area (a bit more), where there is
    significant ice, and in some points of a regular grid state.gridseed
    (density defined by density_seeding)


Routine serve to build a convolutional neural network


Routine serve to define a UNET network from keras_unet_collection


Initialize and write the ncdf optimze file


Write final geology after optimizing


Plot thickness, velocity, mand slidingco


compute spatial gradient, outcome on stagerred grid


Downsample a 2D array to a specified resolution using bilinear interpolation (chatgpt).


Pad Te and load arrays with one flexural wavelenth based on the mean effective elastic thickness. This is to avoid boundary effects.


Function written by Fabien Maussion


Function written by Ethan Welthy, Guillaume Jouvet and Samuel Cook


This serves to print key info on the fly during computation


Finds nearest power of two


Plot to the computational time of each model components in a pie


Plot to the memory size of each model components in a pie


Fetch views, clones, referrers, and popular paths from GitHub Traffic API.


Append rows to CSV; write header if file is new.


 Calculate the luminosity distance

        Parameters
        ----------
        z : float
            Redshift
        stepsize : float
            Integration stepsize

        Returns
        -------
        d : float
            Luminosity distance (units of 10 pc)


 Calculate the lookback time

        Parameters
        ----------
        z : float
            Redshift
        stepsize : float
            Integration stepsize

        Returns
        -------
        t : float
            Lookback time (units of Gyr)


    Collapse the SSP grid into fewer ages, if possible, to significantly
    increase the computational efficiency.

    If using a binned SFH, the SFR within each age bin is assumed to
    be constant, allowing the SSP spectra within the bin to be collapsed.

    The SSP spectra within each bin are combined via weighted average,
    where the weights are determined by the amount of time between the
    SSP ages that fall in the bin.

    The last age will extend to the oldest possible age of the galaxy.

    Parameters
    ----------
    ssp_ages : 1d array
        SSP age grid in Gyr
    ssp_starspec : 3d array
        stellar SSP spectra in units of micro-Jy at a distance of 10 pc
        dimensions: (wavelengths, ages, metallicities)
    ssp_nebspec : 3d array
        nebular SSP spectra in units of micro-Jy at a distance of 10 pc
        dimensions: (wavelengths, ages, metallicities)
    ssp_emlineflux : 3d array
        SSP emission line fluxes in units of ergs/s/cm2 at 10 pc
        dimensions: (wavelengths, ages, metallicities)
    sfh_ages : 1d array
        SFH age bins in Gyr
    galaxy_age : float
        maximum age of the galaxy in Gyr
        (age of Universe at the redshift of the galaxy)
    t_birth : float
        age of the birth cloud in Gyr

    Returns
    -------
    binned_ages : 1d array
        collapsed SSP age grid in Gyr
        include age of the birth cloud
        and all SFH age bins, accounting for the age of the galaxy
    binned_starspec : 3d array
        new ssp_starspec, accounting for the new age weighting
    binned_nebspec : 3d array
        new ssp_nebspec, accounting for the new age weighting
    binned_emlineflux : 3d array
        new ssp_emlineflux, accounting for the new age weighting


    Returns
    -------
    Z : list (1 dim)
        metallicity grid in log solar units
    Age : list (1 dim)
        age grid in years (up to 10 Myr)
    logU : list (1 dim)
        ionization parameter grid
    spec : list (1 dim)
        elements are spectra (numpy array, 1 dim)
        relative line fluxes, normalized by number of ionizing photons,
        i.e., units of the table values are inverse (photons / s)
    wave : numpy array (1 dim)
        wavelength for each spectrum in Angstroms


Read in the stellar population models from fsps for a given isochrone
    and metallicity.

    Parameters
    ----------
    args : class
        The args class from mcsed.parse_args()

    Returns
    -------
    ages : numpy array (1 dim)
        ages of each SPS (Gyr)
    wave : numpy array (1 dim)
        wavelength grid for each spectrum in units of Angstroms
    spec : numpy array (2 dim)
        Spectra in f_nu (micro Janskies, i.e., 1e-29 ergs/s/cm^2/Hz) at 10pc


Speed up construction of emission line fluxes from the CSP

    Parameters
    ----------
    args : dictionary
        user-passed arguments from config.py and command line
    linewave : numpy array (1 dim)
        wavelength for SSP models
    linespec : numpy array (3 dim)
        SSP spectrum for each age and each metallicity

    Returns
    -------
    linewave : numpy array (1 dim)
        collapsed wavelength grid of emission lines
    linespec : numpy array (3 dim)
        collapsed SSP spectrum for each age and each metallicity
        in units of ergs / s / cm^2 at 10 pc


    Parameters
    ----------
    wavebig, wave both in units of Angstroms

    Returns
    -------
    gspec : FILL IN
        in units per Hz


    Parameters
    ----------
    wave : numpy array (1 dim)
        wavelength grid in units of Angstroms
    spectrum : numpy array (1 dim)
        Spectrum in f_nu (micro Janskies, i.e., 1e-29 ergs/s/cm^2/Hz) at 10pc

    Returns
    -------
    float
        number of photons capable of ionizing Hydrogen
        in units of 1e-29 photons / s / cm^2 at 10 pc


 Read in SPS model and return ages, wavelength, and spectra

    Parameters
    ----------
    args : class
        The args class from mcsed.parse_args()

    Returns
    -------
    ages : numpy array (1d)
        SSP age grid (Gyr)
    wave : numpy array (1d)
        SSP wavelength grid (Angstroms)
    starspec : numpy array (3d)
        stellar SSP spectra in units micro-Jy at a distance of 10 pc
        dimensions: (wave, ages, metallicities)
    nebspec : numpy array (3d)
        nebular SSP spectra in units micro-Jy at a distance of 10 pc
        dimensions: (wave, ages, metallicities)
    metallicities : numpy array (1d)
        SSP metallicities (in values of Z, where Zsolar = 0.019)
    emlinewave : numpy array (1d)
        rest-frame wavelengths of emission-line fluxes
        (if used in model calculation)
    emlineflux : numpy array (3d)
        line fluxes in units ergs / cm2 / s at distance of 10 pc
        dimensions: (emlinewave, ages, metallicities)


 Calzetti et al. (2000) dust attenuation curve, k(wave)

    Parameters
    ----------
    wave : numpy array (1 dim)
        wavelength in Angstroms
    Rv : float
        extinction factor
    Returns
    -------
    k : numpy array (1 dim)
        A(wave) / Av = k(wave) / Rv


 Evaluate Dust Law

        Parameters
        ----------
        wave : numpy array (1 dim)
            wavelength
        new_wave : bool
            recompute k(wave), even if already present
            only used in emission line strengths: finer wavelength grid

        Returns
        -------
        Alam : numpy array (1 dim)
            Effective optical depth as a function of wavelength
            Observed = True * 10**(-0.4 * Av / Rv * k(wave))
            A(wave) = E(B-V) * k(wave) = Av / Rv * k(wave)


Uniform prior based on boundaries


 Evaluate Dust Law

        Parameters
        ----------
        wave : numpy array (1 dim)
            wavelength
        new_wave : bool
            recompute k(wave), even if already present
            only used in emission line strengths: finer wavelength grid

        Returns
        -------
        Alam : numpy array (1 dim)
            Effective optical depth as a function of wavelength


 Reddy et al. (2015) dust attenuation curve, k(wave)

        Parameters
        ----------
        wave : numpy array (1 dim)
            wavelength in Angstroms
        Returns
        -------
        k : numpy array (1 dim)
            A(wave) / Av = k(wave) / Rv


 Conroy et al. (2010) dust attenuation curve, a(x) and b(x)
        where A(wave) / Av = a(x) + b(x) / Rv
        and x = 1 / wave (units inverse microns)

        Parameters
        ----------
        wave : numpy array (1 dim)
            wavelength in Angstroms
        Returns
        -------
        a : numpy array (1 dim)
        b : numpy array (1 dim)


 Evaluate Dust Law

        Parameters
        ----------
        wave : numpy array (1 dim)
            wavelength
        new_wave : bool
            recompute k(wave), even if already present
            only used in emission line strengths: finer wavelength grid

        Returns
        -------
        Alam : numpy array (1 dim)
            Effective optical depth as a function of wavelength
            A(wave) / Av = a(x) + b(x) / Rv
            and x = 1 / wave (units inverse microns)
            and Av = Rv * EBV


 Cardelli et al. (1989) extinction curve, a(x) and b(x)
        where A(wave) / Av = a(x) + b(x) / Rv
        and x = 1 / wave (units inverse microns)

        Parameters
        ----------
        wave : numpy array (1 dim)
            wavelength in Angstroms
        Returns
        -------
        a : numpy array (1 dim)
        b : numpy array (1 dim)


Simple design to catch exceptions from the given call


    Make multiple calls to run_mcsed_fit's main function for either
    test or real data to parallelize the computing effort.  Collect the info
    at the end.

    Inputs
    ------
    func : callable function
        This is meant to be run_mcsed_fit's main function
    argv : list
        Arguments (command line or otherwise) list.
        python run_mcsed_fit.py -h
    args : class
        Built arguments from argv
    ncpu : int
        Number of parallelized cpus
    ssp_info : list
        SSP data for spectra, ages, metallicities, etc.
    clean : bool
        Remove temporary files


 Evaluate Dust Law

        Parameters
        ----------
        wave : numpy array (1 dim)
            wavelength in Angstroms

        Returns
        -------
        DustE : numpy array (1 dim)
            Dust emission spectrum (flux in uJy 10 pc)
            linear combination of emission from dust heated by starlight
            at Umin and dust heated by starlight at U>Umin


Parse arguments from commandline or a manually passed list

    Parameters
    ----------
    argv : list
        list of strings such as ['-f', 'input_file.txt', '-s', 'default.ssp']

    Returns
    -------
    args : class
        args class has attributes of each input, i.e., args.filename
        as well as astributes from the config file