fiasco currently only supports version 8 of the CHIANTI database.

Source code for fiasco.fiasco

"""
Package-level functions
"""
import astropy.units as u
import numpy as np
import plasmapy.particles

from plasmapy.particles.exceptions import InvalidParticleError
from scipy.interpolate import interp1d

import fiasco

from fiasco.io import DataIndexer

__all__ = ['list_elements', 'list_ions', 'proton_electron_ratio']


[docs] def list_elements(hdf5_dbase_root=None, sort=True): """ List all available elements in the CHIANTI database. Parameters ---------- hdf5_dbase_root: path-like, optional If not specified, will default to that specified in `fiasco.defaults`. sort: `bool`, optional If True, sort the list of elements by increasing atomic number. """ if hdf5_dbase_root is None: hdf5_dbase_root = fiasco.defaults['hdf5_dbase_root'] elements = [] root = DataIndexer.create_indexer(hdf5_dbase_root, '/') for f in root.fields: try: elements.append(plasmapy.particles.atomic_symbol(f.capitalize())) except InvalidParticleError: continue if sort: elements = sorted(elements, key=lambda x: plasmapy.particles.atomic_number(x)) return elements
[docs] def list_ions(hdf5_dbase_root=None, sort=True): """ List all available ions in the CHIANTI database Parameters ---------- hdf5_dbase_root: path-like, optional If not specified, will default to that specified in `fiasco.defaults`. sort: `bool`, optional If True, sort the list of elements by increasing atomic number. """ if hdf5_dbase_root is None: hdf5_dbase_root = fiasco.defaults['hdf5_dbase_root'] root = DataIndexer(hdf5_dbase_root, '/') # NOTE: get the list from the index if possible. This is ~30x faster try: ions = root['ion_index'] except KeyError: ions = [] for f in root.fields: try: el = plasmapy.particles.atomic_symbol(f.capitalize()) for i in root[f].fields: if f == i.split('_')[0]: ions.append(f"{el} {i.split('_')[1]}") except InvalidParticleError: continue # Optional because adds significant overhead if sort: ions = sorted(ions, key=lambda x: (plasmapy.particles.atomic_number(x.split()[0]), int(x.split()[1]))) # NOTE: when grabbing straight from the index and not sorting, the result will be # a numpy array. Cast to a list to make sure the return type is consistent for # all possible inputs return ions.tolist() if type(ions) == np.ndarray else ions
[docs] @u.quantity_input def proton_electron_ratio(temperature: u.K, **kwargs): """ Calculate ratio between proton and electron densities as a function of temperature according to Eq. 7 of :cite:t:`young_chianti-atomic_2003`. Parameters ---------- temperature : `~astropy.units.Quantity` See Also -------- fiasco.Ion : Accepts same keyword arguments for setting database and dataset names """ # Import here to avoid circular imports from fiasco import log h_2 = fiasco.Ion('H +1', temperature, **kwargs) numerator = h_2.abundance * h_2._ioneq[h_2._instance_kwargs['ioneq_filename']]['ionization_fraction'] denominator = u.Quantity(np.zeros(numerator.shape)) for el_name in list_elements(h_2.hdf5_dbase_root): el = fiasco.Element(el_name, temperature, **h_2._instance_kwargs) try: abundance = el.abundance except KeyError: abund_file = el[0]._instance_kwargs['abundance'] log.warning( f'Not including {el.atomic_symbol}. Abundance not available from {abund_file}.') continue for ion in el: ioneq_file = ion._instance_kwargs['ioneq_filename'] # NOTE: We use ._ioneq here rather than .ioneq to avoid doing an interpolation to the # temperature array every single time and instead only interpolate once at the end. # It is assumed that the ioneq temperature array for each ion is the same. try: ioneq = ion._ioneq[ioneq_file]['ionization_fraction'] t_ioneq = ion._ioneq[ioneq_file]['temperature'] except KeyError: log.warning( f'Not including {ion.ion_name}. Ionization fraction not available from {ioneq_file}.') continue denominator += ioneq * abundance * ion.charge_state ratio = numerator / denominator f_interp = interp1d(t_ioneq.to(temperature.unit).value, ratio.value, kind='linear', bounds_error=False, fill_value=(ratio[0], ratio[-1])) return u.Quantity(f_interp(temperature.value))