Esempio n. 1
0
def test_unequal_temperatures_raise_assertion_error(hdf5_dbase_root):
    first_ion = fiasco.Ion('Fe 12', [1e6, 1e7] * u.K,
                           hdf5_dbase_root=hdf5_dbase_root)
    second_ion = fiasco.Ion('Fe 9', [1e4, 1e5] * u.K,
                            hdf5_dbase_root=hdf5_dbase_root)
    with pytest.raises(AssertionError):
        fiasco.IonCollection(first_ion, second_ion)
Esempio n. 2
0
def test_spectrum(hdf5_dbase_root):
    i1 = fiasco.Ion('H 1', 1 * u.MK, hdf5_dbase_root=hdf5_dbase_root)
    i2 = fiasco.Ion('Fe 5', 1 * u.MK, hdf5_dbase_root=hdf5_dbase_root)
    c = i1 + i2
    density = 1e9 * u.cm**-3
    em = 1e29 * u.cm**-5
    w, spec = c.spectrum(density, em)
    assert spec.shape == (1, 1, ) + w.shape
    # Add an ion with no spectral information
    i3 = fiasco.Ion('H 2', 1 * u.MK, hdf5_dbase_root=hdf5_dbase_root)
    c += i3
    with pytest.warns(UserWarning, match=f'No transition data available for {i3.ion_name}'):
        w2, spec2 = c.spectrum(density, em)
    assert spec2.shape == (1, 1, ) + w2.shape
    assert np.all(spec == spec2)
Esempio n. 3
0
def test_repr_no_levels(hdf5_dbase_root):
    """
    Ensures the repr can be printed without errors even when
    no energy level or transition information is available.
    """
    assert fiasco.Ion('Fe 1', temperature,
                      hdf5_dbase_root=hdf5_dbase_root).__repr__
Esempio n. 4
0
def test_indexing_no_levels(hdf5_dbase_root):
    ion = fiasco.Ion('Fe 1', temperature, hdf5_dbase_root=hdf5_dbase_root)
    print(ion)
    assert [l for l in ion] == []
    with pytest.raises(IndexError,
                       match='No energy levels available for Fe 1'):
        ion[0]
Esempio n. 5
0
def test_missing_abundance(hdf5_dbase_root):
    ion = fiasco.Ion('Li 1',
                     temperature,
                     abundance_filename='sun_coronal_1992_feldman',
                     hdf5_dbase_root=hdf5_dbase_root)
    with pytest.raises(KeyError):
        _ = ion.abundance
Esempio n. 6
0
    def __init__(self,
                 element_name,
                 temperature: u.K,
                 hdf5_path=None,
                 **kwargs):
        self.temperature = temperature
        if type(element_name) is str:
            element_name = element_name.capitalize()
        self.atomic_symbol = plasmapy.atomic.atomic_symbol(element_name)
        self.atomic_number = plasmapy.atomic.atomic_number(element_name)
        self.element_name = plasmapy.atomic.element_name(element_name)
        if hdf5_path is None:
            self.hdf5_dbase_root = fiasco.defaults['hdf5_dbase_root']
        else:
            self.hdf5_dbase_root = hdf5_path
        ion_kwargs = kwargs.get('ion_kwargs', {})
        ion_kwargs['hdf5_path'] = self.hdf5_dbase_root

        chianti_ions = fiasco.DataIndexer(self.hdf5_dbase_root,
                                          self.atomic_symbol.lower()).fields
        ion_list = []
        for i in range(self.atomic_number + 1):
            ion = f'{self.atomic_symbol.lower()}_{i+1}'
            if ion in chianti_ions:
                ion_list.append(
                    fiasco.Ion(f'{self.atomic_symbol} {i+1}', temperature,
                               **ion_kwargs))
        super().__init__(*ion_list)
Esempio n. 7
0
def test_scalar_density(hdf5_dbase_root):
    ion = fiasco.Ion('H 1', temperature, hdf5_dbase_root=hdf5_dbase_root)
    pop = ion.level_populations(1e8 * u.cm**-3)
    assert pop.shape == ion.temperature.shape + (
        1, ) + ion._elvlc['level'].shape
    # This value has not been checked for correctness
    np.testing.assert_allclose(pop[0, 0, 0], 0.9965048292729177)
Esempio n. 8
0
def test_scalar_temperature(hdf5_dbase_root):
    ion = fiasco.Ion('H 1', 1 * u.MK, hdf5_dbase_root=hdf5_dbase_root)
    ioneq = ion.ioneq
    assert ioneq.shape == (1, )
    t_data = ion._ioneq[ion._dset_names['ioneq_filename']]['temperature']
    ioneq_data = ion._ioneq[
        ion._dset_names['ioneq_filename']]['ionization_fraction']
    i_t = np.where(t_data == ion.temperature)
    np.testing.assert_allclose(ioneq, ioneq_data[i_t])
Esempio n. 9
0
    def __init__(self, element_name, temperature: u.K, **kwargs):
        if type(element_name) is str:
            element_name = element_name.capitalize()
        Z = plasmapy.particles.atomic_number(element_name)
        ion_list = []
        for i in range(Z + 1):
            ion = fiasco.Ion(f'{Z} {i+1}', temperature, **kwargs)
            ion_list.append(ion)

        super().__init__(*ion_list)
Esempio n. 10
0
def test_spectrum_no_valid_ions(hdf5_dbase_root):
    # Consider the case of an collection with ions with no spectral information
    c2 = fiasco.IonCollection(
        fiasco.Ion('H 2', 1 * u.MK, hdf5_dbase_root=hdf5_dbase_root))
    with pytest.warns(UserWarning,
                      match='No transition data available for H 2'):
        with pytest.raises(
                ValueError,
                match=
                'No collision or transition data available for any ion in collection.'
        ):
            c2.spectrum(1e9 * u.cm**-3, 1e29 * u.cm**-5)
Esempio n. 11
0
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 [1]_.

    Parameters
    ----------
    temperature : `~astropy.units.Quantity`

    See Also
    --------
    fiasco.Ion : Accepts same keyword arguments for setting database and dataset names

    References
    ----------
    .. [1] Young, P. et al., 2003, ApJS, `144 135 <http://adsabs.harvard.edu/abs/2003ApJS..144..135Y>`_
    """
    h_2 = fiasco.Ion('H +1', temperature, **kwargs)
    numerator = h_2.abundance * h_2._ioneq[
        h_2._dset_names['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, **kwargs)
        abundance = el.abundance
        if abundance is None:
            warnings.warn(
                f'Not including {el.atomic_symbol}. Abundance not available.')
            continue
        for ion in el:
            ioneq = ion._ioneq[
                ion._dset_names['ioneq_filename']]['ionization_fraction']
            if ioneq is None:
                warnings.warn(
                    f'Not including {ion.ion_name}. Ionization fraction not available.'
                )
                continue
            denominator += ioneq * abundance * ion.charge_state

    ratio = numerator / denominator
    interp = interp1d(
        ion._ioneq[ion._dset_names['ioneq_filename']]['temperature'].value,
        ratio.value,
        kind='linear',
        bounds_error=False,
        fill_value=(ratio[0], ratio[-1]))

    return u.Quantity(interp(temperature))
Esempio n. 12
0
    def from_asdf(cls, filename):
        """
        Restore `EmissionModel` instance from an ASDF file
        """
        with asdf.open(filename, mode='r', copy_arrays=True) as af:
            temperature = af.tree['temperature']
            density = af.tree['density']
            ions = af.tree['ions']
            dset_names = af.tree['dset_names']
            emissivity_table_filename = af.tree['emissivity_table_filename']

        ions = [
            fiasco.Ion(ion, temperature, **ds)
            for ion, ds in zip(ions, dset_names)
        ]
        em_model = cls(density, *ions)
        em_model.emissivity_table_filename = emissivity_table_filename
        return em_model
Esempio n. 13
0
def test_repr_scalar_temp(ion, hdf5_dbase_root):
    assert 'Fe 5' in fiasco.Ion('Fe 5',
                                1e6 * u.K,
                                hdf5_dbase_root=hdf5_dbase_root).__repr__()
Esempio n. 14
0
def fe10(hdf5_dbase_root):
    return fiasco.Ion('Fe 10', temperature, hdf5_dbase_root=hdf5_dbase_root)
Esempio n. 15
0
def test_create_ion_with_wrong_units_raises_unit_conversion_error(
        hdf5_dbase_root):
    with pytest.raises(u.UnitsError):
        fiasco.Ion('Fe 5',
                   temperature.value * u.s,
                   hdf5_dbase_root=hdf5_dbase_root)
Esempio n. 16
0
#############################################################
# Plot the wavelength response
plt.plot(ch.wavelength, response)
plt.xlim(ch.channel + [-4, 4] * u.angstrom)
plt.axvline(x=ch.channel, ls='--', color='k')
plt.title(f'{ch.channel.to_string(format="latex")} Wavelength Response')
plt.show()

############################################################
# Next, we construct for the `~fiasco.Ion` object for Fe 18. Note
# that we choose to use the coronal abundances of
# `Feldman et al. (1992) <https://ui.adsabs.harvard.edu/abs/2012SoPh..275...41B/>`_.
temperature = 10.**(np.arange(4.5, 8, 0.05)) * u.K
fe18 = fiasco.Ion('Fe 18',
                  temperature,
                  abundance_filename='sun_coronal_1992_feldman')

############################################################
# Compute contribution function,
#
# .. math:: G(n,T,\lambda) = 0.83\mathrm{Ab}\frac{hc}{\lambda}N_{\lambda}A_{\lambda}f\frac{1}{n}
#
# for each transition of Fe 18 at a single density.
# `~fiasco.Ion.contribution_function` also accepts an array of
# densities, but this requires significantly more computation.
g = fe18.contribution_function(1e9 * u.cm**(-3), include_protons=False)

############################################################
# Get the corresponding transition wavelengths
transitions = fe18.transitions.wavelength[~fe18.transitions.is_twophoton]
Esempio n. 17
0
def test_contains(collection, hdf5_dbase_root):
    assert 'H 1' in collection
    assert 'hydrogen 1' in collection
    assert 'hydrogen +0' in collection
    ion = fiasco.Ion('H 1', temperature, hdf5_dbase_root=hdf5_dbase_root)
    assert ion in collection
Esempio n. 18
0
def another_ion(hdf5_dbase_root):
    return fiasco.Ion('Ca 2', temperature, hdf5_dbase_root=hdf5_dbase_root)
Esempio n. 19
0
def test_no_elvlc_raises_index_error(hdf5_dbase_root):
    with pytest.raises(IndexError):
        fiasco.Ion('H 2', temperature, hdf5_dbase_root=hdf5_dbase_root)[0]
Esempio n. 20
0
def test_missing_ip():
    ion = fiasco.Ion('Fe 27', temperature)
    assert ion.ip is None
Esempio n. 21
0
def test_missing_abundance():
    ion = fiasco.Ion('Li 1',
                     temperature,
                     abundance_filename='sun_coronal_1992_feldman')
    assert ion.abundance is None
Esempio n. 22
0
def test_no_elvlc_raises_index_error():
    with pytest.raises(IndexError):
        fiasco.Ion('Cr 1', temperature)[0]
Esempio n. 23
0
def another_ion():
    return fiasco.Ion('Fe 6', temperature)
Esempio n. 24
0
def ion():
    return fiasco.Ion('Fe 5', temperature)
Esempio n. 25
0
def ion(hdf5_dbase_root):
    return fiasco.Ion('Fe 2', temperature, hdf5_dbase_root=hdf5_dbase_root)
Esempio n. 26
0
def test_missing_abundance(hdf5_dbase_root):
    ion = fiasco.Ion('Li 1',
                     temperature,
                     abundance_filename='sun_coronal_1992_feldman',
                     hdf5_dbase_root=hdf5_dbase_root)
    assert ion.abundance is None
Esempio n. 27
0
def collection(hdf5_dbase_root):
    return fiasco.IonCollection(
        fiasco.Ion('H 1', temperature, hdf5_dbase_root=hdf5_dbase_root),
        fiasco.Ion('He 2', temperature, hdf5_dbase_root=hdf5_dbase_root))
Esempio n. 28
0
def test_missing_ip(hdf5_dbase_root):
    ion = fiasco.Ion('Fe 27', temperature, hdf5_dbase_root=hdf5_dbase_root)
    assert ion.ip is None
Esempio n. 29
0
def test_create_ion_without_units_raises_units_error():
    with pytest.raises(TypeError):
        fiasco.Ion('Fe 5', temperature.value)
Esempio n. 30
0
def test_create_ion_without_units_raises_units_error(hdf5_dbase_root):
    with pytest.raises(TypeError):
        fiasco.Ion('Fe 5', temperature.value, hdf5_dbase_root=hdf5_dbase_root)