.. _isochrones_module:

Isochrones module
#################

To generate synthetic clusters, **ASteCA** requires a set of theoretical isochrones 
to serve as their foundation. The supported services are:
`PARSEC <http://stev.oapd.inaf.it/cgi-bin/cmd_3.7>`_,
`MIST <https://waps.cfa.harvard.edu/MIST/>`_, and
`BASTI <http://basti-iac.oa-abruzzo.inaf.it/isocs.html>`_.

Each service produces the isochrone files in a different way. A single file
produced with these services will contain:

* PARSEC : multiple metallicities and multiple ages
* MIST   : single metallicity and multiple ages
* BASTI  : single metallicity and single age


All isochrones files must be stored in a single folder; **ASteCA** assumes that
all files within that folder are isochrone files that should be loaded. 

.. note::
    The user can combine files for different photometric systems as long as they
    are generated by the same service (PARSEC, MIST, or BASTI). The only restriction is
    that the files must have the same shape, this is: the same number of metallicities,
    ages, and initial masses.

To load the isochrones and generate an object, called here :py:obj:`isochs`, we make use
of the :py:class:`asteca.Isochrones` class as follows:

.. code-block:: python

    import asteca

    # Load PARSEC isochrones
    isochs = asteca.Isochrones(
        model="PARSEC",
        isochs_path="isochrones/",
        mag="Gmag",
        color=("G_BPmag", "G_RPmag"),
        magnitude_effl=6390.7,
        color_effl=(5182.58, 7825.08),
        verbose=3
    )

    Instantiating isochrones...
    Model          : PARSEC
    N_files        : 1
    N_mets         : 3
    N_ages         : 36
    N_points       : 2000
    z    range     : [0.01, 0.02]
    loga range     : [6.6, 10.10001]
    Magnitude      : Gmag
    Color          : G_BPmag-G_RPmag
    Isochrone object generated

Where:

- ``model`` : Model used to generate the isochrones. Must be one of the three
  allowed models
- ``isochs_path`` : Path to the file or folder where the isochrone file(s) is(are) stored
- ``mag`` : Name of the magnitude column in the isochrone file(s)
- ``color`` : Names of the two filters that make up the color. Names must be
  **in the proper order**, i.e. such that the color is computed as
  ``filter1 − filter2`` (the first filter minus the second).
- ``magnitude_effl`` : Effective lambda (in Angstrom) for the magnitude filter.
- ``color_effl`` : Effective lambdas for the filters that make up the ``color`` (in the
  same order as the names in the defined color).

The figure below shows loaded isochrones for the three supported models, with the same photometric system (``Gaia EDR3``) and the same metallicity and age ranges.

.. figure:: ../_static/isoch_models.webp
    :align: center


The effective lambda values represent the effective central/midpoint wavelength of a
filter. These values are returned by the
`CMD service <http://stev.oapd.inaf.it/cgi-bin/cmd>`_, and are also available in
the documentation for the
`pyphot <https://mfouesneau.github.io/pyphot/libcontent.html>`_ package and the
`Filter Profile Service <http://svo2.cab.inta-csic.es/theory/fps/>`_
of the Spanish Virtual Observatory.

The effective lambda values are required to generate synthetic clusters later on,
as these values are used to calculate the extinction coefficients for the magnitude and color filters when using the default ``CCMO`` extinction law. If the :py:class:`Synthetic`
object is generated with the ``GAIADR3`` extinction law, then the effective lambda
values are not used and the extinction coefficients are calculated internally by
the :py:class:`asteca.Synthetic` class using the extinction coefficients provided by the
`Gaia EDR3 documentation <https://www.cosmos.esa.int/web/gaia/edr3-extinction-law>`_.
In this case you can safely ignore the effective lambda values when loading the
isochrones, as follows:

.. code-block:: python

    # Load PARSEC isochrones
    isochs = asteca.Isochrones(
        model="PARSEC",
        isochs_path="isochrones/",
        mag="Gmag",
        color=("G_BPmag", "G_RPmag"),
    )

See the :ref:`extinction_law` section for a detailed explanation of how the extinction
coefficients are calculated and used in **ASteCA**.





Extra arguments
===============

There are a few more arguments that can be modified when loading the
:py:class:`asteca.Isochrones` class. These are:
``z_to_FeH, N_points, parsec_rm_stages, column_names``.

The ``z_to_FeH`` argument is used to transform metallicity values from the default ``z``
to the logarithmic version ``FeH``. If you want to generate your synthetic cluster
models using ``FeH`` instead of ``z``, then this argument must be set to the value
of the solar ``z`` metallicity for the isochrones. For example, if you are using PARSEC
isochrones a solar metallicity of ``z=0.0152`` is recommended (see
`CMD input form <http://stev.oapd.inaf.it/cgi-bin/cmd>`_), which means that
you would load your isochrones as:

.. code-block:: python

    isochs = asteca.Isochrones(
        model="PARSEC",
        isochs_path="isochrones/",
        mag="Gmag",
        color=("G_BPmag", "G_RPmag"),
        magnitude_effl=6390.7,
        color_effl=(5182.58, 7825.08),
        z_to_FeH=0.0152
    )

If this argument is not changed from its default then the ``z`` parameter will be used
to generate synthetic clusters, as shown in the section :ref:`ref_generating`.

The ``N_points`` argument controls the resolution of the isochrones interpolation, set
to ``2000`` by default. A smaller value can be used to lower the amount of memory
used by this class, but it comes at the expense of more coarse synthetic clusters being
generated later on (since the isochrones will be interpolated with fewer points and will
thus contain less resolution).

The ``parsec_rm_stages`` affects PARSEC isochrones only. Is set to ``9.0`` by default
and it indicates that the `post_AGB` stage (``label=9``) should be removed. This is
because this stage is still `"in preparation" <https://stev.oapd.inaf.it/cmd/faq.html>`_

Finally, the ``column_names`` argument is an internal dictionary that should only be
manually passed if the :py:class:`Isochrones` class fails to parse the column names of
the isochrones files. Please `contact me <gabrielperren@gmail.com>`_ if you have any
issues with the loading process of the theoretical isochrones and need to modify
this argument.

The user can refer to :py:class:`asteca.Isochrones` for detailed information on each
of these arguments.
